diff --git a/src/TNL/Containers/List.h b/src/TNL/Containers/List.h
index 3692a9a2ca56404151110eadb96acb211345f34a..adb163374dc7a3e9d7bbb626605bbebeb2e0c92d 100644
--- a/src/TNL/Containers/List.h
+++ b/src/TNL/Containers/List.h
@@ -71,6 +71,10 @@ template< class T > class List
 
       const List& operator = ( const List& lst );
 
+      bool operator == ( const List& lst ) const;
+
+      bool operator != ( const List& lst ) const;
+
       //! Append new data element
       bool Append( const T& data );
 
diff --git a/src/TNL/Containers/List_impl.h b/src/TNL/Containers/List_impl.h
index 63f5f195ddaff3c356ae2bb9ce68b6d7dc6f58d3..f91f30ca2b7fd7578a109d0786bfcbc93c91a100 100644
--- a/src/TNL/Containers/List_impl.h
+++ b/src/TNL/Containers/List_impl.h
@@ -107,6 +107,23 @@ const List< T >& List< T >::operator = ( const List& lst )
    return( *this );
 }
 
+template< typename T >
+bool List< T >::operator == ( const List& lst ) const
+{
+   if( this->getSize() != lst.getSize() )
+      return false;
+   for( int i = 0; i < this->getSize(); i++ )
+      if( (*this)[ i ] != lst[ i ] )
+         return false;
+   return true;
+}
+
+template< typename T >
+bool List< T >::operator != ( const List& lst ) const
+{
+   return ! operator==( lst );
+}
+
 template< typename T >
 bool List< T >::Append( const T& data )
 {
diff --git a/src/TNL/Containers/StaticVector.h b/src/TNL/Containers/StaticVector.h
index d3a10c9865bed431f05c6d30990b27c9fa14e018..2b0e7c7fdeb013e47d578a4ff33053a05aecde2e 100644
--- a/src/TNL/Containers/StaticVector.h
+++ b/src/TNL/Containers/StaticVector.h
@@ -306,9 +306,9 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real >
    ThisType abs() const;
 };
 
-template< int Size, typename Real >
+template< int Size, typename Real, typename Scalar >
 __cuda_callable__
-StaticVector< Size, Real > operator * ( const Real& c, const StaticVector< Size, Real >& u );
+StaticVector< Size, Real > operator * ( const Scalar& c, const StaticVector< Size, Real >& u );
 
 template< int Size, typename Real >
 __cuda_callable__
@@ -377,10 +377,10 @@ Real tnlTriangleArea( const StaticVector< 3, Real >& a,
    StaticVector< 3, Real > u1, u2;
    u1. x() = b. x() - a. x();
    u1. y() = b. y() - a. y();
-   u1. z() = 0.0;
+   u1. z() = b. z() - a. z();
    u2. x() = c. x() - a. x();
    u2. y() = c. y() - a. y();
-   u2. z() = 0;
+   u2. z() = c. z() - a. z();
 
    const StaticVector< 3, Real > v = VectorProduct( u1, u2 );
    return 0.5 * ::sqrt( tnlScalarProduct( v, v ) );
diff --git a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
index 65a555bacf7db21b26aaca4492068301bd16a255..341ed711a4cb4da60f3f6501a5dec0f8b736925a 100644
--- a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
+++ b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h
@@ -45,7 +45,7 @@ write( const MeshFunctionType& function,
    {
       entity.refresh();
       typename MeshType::VertexType v = entity.getCenter();
-      str << v << " "
+      str << v.x() << " "
           << function.getData().getElement( entity.getIndex() ) << std::endl;
    }
    return true;
@@ -71,7 +71,7 @@ write( const MeshFunctionType& function,
    {
       entity.refresh();
       typename MeshType::VertexType v = entity.getCenter();
-      str << v << " "
+      str << v.x() << " "
           << function.getData().getElement( entity.getIndex() ) << std::endl;
    }
    return true;
diff --git a/src/TNL/Object.cpp b/src/TNL/Object.cpp
index c5350b287a067fc961a074aba910e331fde1847c..14418d26da1412d8f3785fce4f0c76fb0391e948 100644
--- a/src/TNL/Object.cpp
+++ b/src/TNL/Object.cpp
@@ -189,7 +189,7 @@ bool parseObjectType( const String& objectType,
 
    /****
     * Now, we will extract the parameters.
-    * Each parameter can be template, so we must compute and pair
+    * Each parameter can be template, so we must count and pair
     * '<' with '>'.
     */
    int templateBrackets( 0 );
@@ -201,13 +201,12 @@ bool parseObjectType( const String& objectType,
          templateBrackets ++;
       if( ! templateBrackets )
       {
-         if( objectType[ i ] == ' ' ||
-             objectType[ i ] == ',' ||
+         if( objectType[ i ] == ',' ||
              objectType[ i ] == '>' )
          {
             if( buffer != "" )
             {
-               if( ! parsedObjectType. Append( buffer ) )
+               if( ! parsedObjectType. Append( buffer.strip( ' ' ) ) )
                   return false;
                buffer. setString( "" );
             }
diff --git a/src/TNL/Solvers/SolverConfig_impl.h b/src/TNL/Solvers/SolverConfig_impl.h
index 76234b9880e45db4d023fa898622bef75ff361d7..eb981bb35b9ade583e8538376978443e04584e14 100644
--- a/src/TNL/Solvers/SolverConfig_impl.h
+++ b/src/TNL/Solvers/SolverConfig_impl.h
@@ -116,7 +116,7 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri
       if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitSORSolverTag >::enabled )
          config.addEntryEnum( "sor" );
 #ifdef HAVE_UMFPACK
-      if( MeshConfigSemiImplicitSolver< MeshConfig, SemiImplicitUmfpackSolverTag >::enabled )
+      if( ConfigTagSemiImplicitSolver< ConfigTag, SemiImplicitUmfpackSolverTag >::enabled )
          config.addEntryEnum( "umfpack" );
 #endif
    }
diff --git a/src/TNL/String.cpp b/src/TNL/String.cpp
index 4607d742a9aa5439ded39e2e0a750adf9e60abd9..980e0a1f6065062305033e3e0e9aedb02f3353bb 100644
--- a/src/TNL/String.cpp
+++ b/src/TNL/String.cpp
@@ -269,6 +269,23 @@ replace( const String& pattern,
    this->string = newString;
 }
 
+String
+String::strip( char strip ) const
+{
+   int prefix_cut_off = 0;
+   int sufix_cut_off = 0;
+
+   while( prefix_cut_off < getLength() && (*this)[ prefix_cut_off ] == strip )
+      prefix_cut_off++;
+
+   while( sufix_cut_off < getLength() && (*this)[ getLength() - 1 - sufix_cut_off ] == strip )
+      sufix_cut_off++;
+
+   if( prefix_cut_off + sufix_cut_off < getLength() )
+      return String( getString(), prefix_cut_off, sufix_cut_off );
+   return "";
+}
+
 
 const char* String :: getString() const
 {
diff --git a/src/TNL/String.h b/src/TNL/String.h
index 254c283e2cc259af4056fddfb0446ef82e4af5cc..65daaf4c8f4b01720efa109550bd4cccffcbf4fb 100644
--- a/src/TNL/String.h
+++ b/src/TNL/String.h
@@ -128,6 +128,8 @@ class String
    void replace( const String& pattern,
                  const String& replaceWith );
 
+   String strip( char strip = ' ' ) const;
+
    // TODO: remove
    //! Write to a binary file
    bool save( std::ostream& file ) const;
diff --git a/src/UnitTests/ObjectTest.cpp b/src/UnitTests/ObjectTest.cpp
index 557d1239ba2aceca88c65f3f4f253641ebd4a5d8..3c495846d3de7b62e8c0efb5050970b2fc275fdc 100644
--- a/src/UnitTests/ObjectTest.cpp
+++ b/src/UnitTests/ObjectTest.cpp
@@ -11,6 +11,7 @@
 #include <TNL/Devices/Host.h>
 #include <TNL/Object.h>
 #include <TNL/File.h>
+#include <TNL/Containers/Array.h>
 
 #ifdef HAVE_GTEST 
 #include "gtest/gtest.h"
@@ -29,6 +30,77 @@ TEST( ObjectTest, SaveAndLoadTest )
    file.open( "test-file.tnl", tnlReadMode );
    ASSERT_TRUE( testObject.load( file ) );
 }
+
+TEST( ObjectTest, parseObjectTypeTest )
+{
+   Containers::List< String > parsed;
+   Containers::List< String > expected;
+
+   // plain type
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "int", parsed ) );
+   expected.Append( "int" );
+   EXPECT_EQ( parsed, expected );
+
+   // type with space
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "short int", parsed ) );
+   expected.Append( "short int" );
+   EXPECT_EQ( parsed, expected );
+
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "unsigned short int", parsed ) );
+   expected.Append( "unsigned short int" );
+   EXPECT_EQ( parsed, expected );
+
+   // composed type
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "Containers::Vector< double, Devices::Host, int >", parsed ) );
+   expected.Append( "Containers::Vector" );
+   expected.Append( "double" );
+   expected.Append( "Devices::Host" );
+   expected.Append( "int" );
+   EXPECT_EQ( parsed, expected );
+
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "Containers::Vector< Containers::List< String >, Devices::Host, int >", parsed ) );
+   expected.Append( "Containers::Vector" );
+   expected.Append( "Containers::List< String >" );
+   expected.Append( "Devices::Host" );
+   expected.Append( "int" );
+   EXPECT_EQ( parsed, expected );
+
+   // spaces in the template parameter
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "A< short int >", parsed ) );
+   expected.Append( "A" );
+   expected.Append( "short int" );
+   EXPECT_EQ( parsed, expected );
+
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "A< B< short int >, C >", parsed ) );
+   expected.Append( "A" );
+   expected.Append( "B< short int >" );
+   expected.Append( "C" );
+   EXPECT_EQ( parsed, expected );
+
+   // spaces at different places in the template parameter
+   parsed.reset();
+   expected.reset();
+   ASSERT_TRUE( parseObjectType( "A< b , c <E>  ,d>", parsed ) );
+   expected.Append( "A" );
+   expected.Append( "b" );
+   expected.Append( "c <E>" );
+   expected.Append( "d" );
+   EXPECT_EQ( parsed, expected );
+}
 #endif
 
 
diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp
index 9b76b0f6d450f2c1f71882a844443d15f270faf4..1063d139dc9781af1fafc2f8ecf34e2a6c8401fe 100644
--- a/src/UnitTests/StringTest.cpp
+++ b/src/UnitTests/StringTest.cpp
@@ -106,6 +106,17 @@ TEST( StringTest, AdditionAssignmentOperator )
    ASSERT_EQ( strcmp( string2. getString(), "stringstring2" ), 0 );
 }
 
+TEST( StringTest, strip )
+{
+   EXPECT_EQ( String( "string" ).strip(), String( "string" ) );
+   EXPECT_EQ( String( "  string" ).strip(), String( "string" ) );
+   EXPECT_EQ( String( "string  " ).strip(), String( "string" ) );
+   EXPECT_EQ( String( "  string  " ).strip(), String( "string" ) );
+   EXPECT_EQ( String( " string1  string2  " ).strip(), String( "string1  string2" ) );
+   EXPECT_EQ( String( "" ).strip(), String( "" ) );
+   EXPECT_EQ( String( "  " ).strip(), String( "" ) );
+}
+
 
 TEST( StringTest, SaveLoad )
 {