diff --git a/Data/Input/apTvUtExportBandMathX.txt b/Data/Input/apTvUtExportBandMathX.txt
index baa6a64fc44bd2084a44a5b4ff0044f7b0e3fa21..774aca47ddf40b5931ef58ec124c5394bbb4a511 100644
--- a/Data/Input/apTvUtExportBandMathX.txt
+++ b/Data/Input/apTvUtExportBandMathX.txt
@@ -1,2 +1,3 @@
-#E cos(im1b1)+im2b1*im3b1-im3b2+ndvi(im3b3,im3b4)
+#F val 1
+#E im1b1 + 2*val + im2b1
 
diff --git a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
index 4ea775fdb56ca5db88271e0918e90a39da46dcb8..95a859ebbecede54dad37cc8cbc1587330bd6b91 100644
--- a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
+++ b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
@@ -246,54 +246,42 @@ private:
   void DoUpdateParameters() override
   {
     // check if input context should be used
-    bool useContext = this->ContextCheck();
+    bool context_exists = this->ContextCheck();
     // Check if the expression is correctly set
-    if (HasValue("il") && HasValue("exp"))
-      {
-      this->LiveCheck(useContext);
-      }
+    BandMathImageFilterType::Pointer math_filter = BandMathImageFilterType::New();
+    math_filter->SetManyExpressions(false);
+    // first thing, load context if there is one
+    if (context_exists)
+      math_filter->ImportContext(GetParameterString("incontext"));
+    // Only one expression is allowed '-exp'>'-incontext'
+    if ( !HasValue("exp") ) 
+      SetParameterString("exp", math_filter->GetExpression(0));
+    if ( HasValue("il") && HasValue("exp") )
+    {
+      math_filter->ClearExpression(); // remove expression set by context
+      math_filter->SetExpression(GetParameterString("exp")); //set expression
+      LiveCheck(math_filter);
+    }
   }
 
+  // Check if the given filename is valid
   bool ContextCheck(void)
-    {
-    bool useContext = false;
+  {
+    bool context_exists = false;
     if (IsParameterEnabled("incontext") && HasValue("incontext"))
-      {
+    {
       std::string contextPath = GetParameterString("incontext");
       // check that file exists
       if (itksys::SystemTools::FileExists(contextPath,true))
-        {
-        BandMathImageFilterType::Pointer dummyFilter =
-          BandMathImageFilterType::New();
-        dummyFilter->SetManyExpressions(false);
-        try
-          {
-          dummyFilter->ImportContext(contextPath);
-          useContext = true;
-          }
-        catch(itk::ExceptionObject& err)
-          {
-          //trick to prevent unreferenced local variable warning on MSVC
-          (void)err;
-          // silent catch
-          useContext = false;
-          }
-        if (useContext)
-          {
-          // only set the first expression, 'ManyExpression' is disabled.
-          this->SetParameterString("exp",dummyFilter->GetExpression(0));
-          }
-        }
+      {
+        context_exists = true;
       }
-    return useContext;
     }
+    return context_exists;
+  }
 
-  void LiveCheck(bool useContext=false)
+  void LiveCheck( BandMathImageFilterType::Pointer math_filter )
     {
-    BandMathImageFilterType::Pointer dummyFilter =
-      BandMathImageFilterType::New();
-    dummyFilter->SetManyExpressions(false);
-
     std::vector<MultiChannelExtractorType::Pointer> extractors;
     FloatVectorImageListType::Pointer inList = GetParameterImageList("il");
     for (unsigned int i = 0; i < inList->Size(); i++)
@@ -314,19 +302,11 @@ private:
         {
         extract->SetChannel(j+1);
         }
-      dummyFilter->SetNthInput(i,extract->GetOutput());
-      }
-    if (useContext)
-      {
-      dummyFilter->ImportContext(GetParameterString("incontext"));
-      }
-    else
-      {
-      dummyFilter->SetExpression(GetParameterString("exp"));
+      math_filter->SetNthInput(i,extract->GetOutput());
       }
     try
       {
-      dummyFilter->UpdateOutputInformation();
+      math_filter->UpdateOutputInformation();
       SetParameterDescription("exp", "Valid expression");
       }
     catch(itk::ExceptionObject& err)
@@ -334,8 +314,15 @@ private:
       // Change the parameter description to be able to have the
       // parser errors in the tooltip
       SetParameterDescription("exp", err.GetDescription());
+      // std::string error_string(err.GetDescription());
+      // otbAppLogINFO("There was an error while parsing the expression given "
+      //   "its input:" + error_string );
       }
+    catch(...)
+    {
+      SetParameterDescription("exp", "Other exception catched");
     }
+  }
 
   void DoExecute() override
   {
@@ -352,11 +339,11 @@ private:
 
     if ( (!IsParameterEnabled("exp")) && (!IsParameterEnabled("incontext")) )
     {
-     itkExceptionMacro("No expression set...; please set and enable at least one one expression");
+     itkExceptionMacro("No expression set...; please set and enable at least one expression");
     }
 
-    m_Filter               = BandMathImageFilterType::New();
-    m_Filter->SetManyExpressions(false);
+    BandMathImageFilterType::Pointer  math_filter = BandMathImageFilterType::New();
+    math_filter->SetManyExpressions(false);
 
     for (unsigned int i = 0; i < nbImages; i++)
       {
@@ -367,31 +354,33 @@ private:
                        << currentImage->GetNumberOfComponentsPerPixel()
                        << " components");
 
-        m_Filter->SetNthInput(i,currentImage);
+        math_filter->SetNthInput(i,currentImage);
 
       }
 
-    bool useContext = this->ContextCheck();
+    bool context_exists = this->ContextCheck();    
+    // first thing, load context if there is one
+    if (context_exists)
+    {
+      std::string context_string = GetParameterString("incontext");
+      math_filter->ImportContext(context_string);
+      otbAppLogINFO("Using Context: " << context_string
+      << " for variables (and expression if no parameter -exp has been given)." );
+    }
+    // Only one expression is allowed '-exp'>'-incontext'
+    math_filter->ClearExpression(); // remove expression set by context
     std::string expStr = GetParameterString("exp");
-    if (useContext)
-      {
-      otbAppLogINFO("Using input context: " << expStr );
-      m_Filter->ImportContext(GetParameterString("incontext"));
-      }
-    else
-      {
-      otbAppLogINFO("Using expression: " << expStr );
-      m_Filter->SetExpression(expStr);
-      }
+    otbAppLogINFO("Using expression: " << expStr );
+    math_filter->SetExpression(expStr);
 
     if ( IsParameterEnabled("outcontext") && HasValue("outcontext") )
-      m_Filter->ExportContext(GetParameterString("outcontext"));
+      math_filter->ExportContext(GetParameterString("outcontext"));
 
     // Set the output image
-    SetParameterOutputImage("out", m_Filter->GetOutput());
+    SetParameterOutputImage("out", math_filter->GetOutput());
+    RegisterPipeline();
   }
 
-  BandMathImageFilterType::Pointer  m_Filter;
 };
 
 } // namespace Wrapper
diff --git a/Modules/Applications/AppMathParserX/otb-module.cmake b/Modules/Applications/AppMathParserX/otb-module.cmake
index 54b1fc571ac6aedc6cdfa26f7c1c4949ce4c3baa..eda0082072a811e8947f5962ccacd390f71e8af5 100644
--- a/Modules/Applications/AppMathParserX/otb-module.cmake
+++ b/Modules/Applications/AppMathParserX/otb-module.cmake
@@ -26,6 +26,9 @@ otb_module(OTBAppMathParserX
     OTBMathParserX
     OTBObjectList
 
+  TEST_DEPENDS
+    OTBTestKernel
+    
   DESCRIPTION
     "${DOCUMENTATION}"
 )
diff --git a/Modules/Applications/AppMathParserX/test/CMakeLists.txt b/Modules/Applications/AppMathParserX/test/CMakeLists.txt
index b5d584699738fa153a1a7a5c93a80138bd52c904..65e464ffec60931c951646d2e77d2a31575c841f 100644
--- a/Modules/Applications/AppMathParserX/test/CMakeLists.txt
+++ b/Modules/Applications/AppMathParserX/test/CMakeLists.txt
@@ -20,15 +20,15 @@
 
 otb_module_test()
 
-#----------- BandMathX TESTS ----------------
-otb_test_application(NAME apTvUtBandMathX
-                     APP  BandMathX
-                     OPTIONS -il ${INPUTDATA}/poupees_sub_c1.png
-                                  ${INPUTDATA}/poupees_sub_c2.png
-                                  ${INPUTDATA}/poupees_sub.png
-                             -out ${TEMP}/apTvUtBandMathXOutput.tif
-                             -incontext ${INPUTDATA}/apTvUtExportBandMathX.txt
-                     VALID   --compare-image ${NOTOL}
-                             ${INPUTDATA}/apTvUtBandMathOutput.tif
-                             ${TEMP}/apTvUtBandMathXOutput.tif)
+set(OTBBandMathXAppTest
+otbBandMathXAppTests.cxx
+)
 
+add_executable(OTBBandMathXAppTest ${OTBBandMathXAppTest})
+target_link_libraries(OTBBandMathXAppTest ${OTBAppMathParserX-Test_LIBRARIES})
+otb_module_target_label(OTBBandMathXAppTest)
+
+otb_add_test(NAME apTvUtBandMathX COMMAND OTBBandMathXAppTest
+  $<TARGET_FILE_DIR:otbapp_BandMathX>
+  ${INPUTDATA}/apTvUtExportBandMathX.txt
+  )
\ No newline at end of file
diff --git a/Modules/Applications/AppMathParserX/test/otbBandMathXAppTests.cxx b/Modules/Applications/AppMathParserX/test/otbBandMathXAppTests.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b2d425fc0632ff9f3c4cd85adb3572160bcfee87
--- /dev/null
+++ b/Modules/Applications/AppMathParserX/test/otbBandMathXAppTests.cxx
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "otbVectorImage.h"
+#include "otbWrapperApplicationRegistry.h"
+#include "otbWrapperTypes.h"
+#include <string>
+
+typedef otb::VectorImage<unsigned char> VectorImageType;
+typedef VectorImageType::PixelType PixelType;
+
+/* This function is creating and filling a vector image */
+VectorImageType::Pointer create_vector_image( int pxl_s , int nb_comp , unsigned char value )
+{
+  VectorImageType::SizeType size;
+  size.Fill(pxl_s);
+  VectorImageType::IndexType index;
+  index.Fill(0);
+  VectorImageType::RegionType region;
+  region.SetSize(size);
+  region.SetIndex(index);
+
+  VectorImageType::Pointer image = VectorImageType::New();
+
+  image->SetLargestPossibleRegion( region );
+  image->SetBufferedRegion( region );
+  image->SetRequestedRegion( region );
+  image->SetNumberOfComponentsPerPixel(nb_comp);
+  image->Allocate();
+  PixelType val(nb_comp);
+  val.Fill(value);
+  image->FillBuffer(val);
+  return image;
+}
+
+#define dyn_cast( im_base , vect_im )                                             \
+{                                                                                 \
+  vect_im = dynamic_cast<otb::VectorImage<float> *>(im_base);                     \
+  if( ! vect_im )                                                                 \
+  {                                                                               \
+    std::cout<<"Not the right conversion, cannot retrieve the output"<<std::endl; \
+    return EXIT_FAILURE ;                                                         \
+  }                                                                               \
+}
+
+int main(int , char * argv[] )
+{
+  std::cout<<"Begin bandMathX Test"<<std::endl;
+  int return_val = 0;
+  auto img1 = create_vector_image(5,2,1);
+  auto img2 = create_vector_image(5,1,2);
+  VectorImageType::IndexType index;
+  index.Fill(3); // Center of the images
+  std::cout<<"Create application"<<std::endl;
+  otb::Wrapper::ApplicationRegistry::SetApplicationPath(argv[1]);
+  auto app = otb::Wrapper::ApplicationRegistry::CreateApplication("BandMathX");
+  app->AddImageToParameterInputImageList("il", img1);
+  app->UpdateParameters();
+  app->AddImageToParameterInputImageList("il", img2);
+  app->UpdateParameters();
+  std::cout<<"Inputs are set"<<std::endl;
+
+  // Case one: only expression
+  app->SetParameterString("exp", "im1b1+im2b1");
+  app->UpdateParameters();
+  app->SetParameterOutputImagePixelType("out", otb::Wrapper::ImagePixelType::ImagePixelType_uint8);
+  std::cout<<"Case one: parameter exp is set"<<std::endl;
+  app->Execute();
+  auto output = app->GetParameterImageBase("out");
+  output->Update();
+  float im_val = 0;
+  // We need to be carefull as we are taking the direct output of the underlying 
+  // filter in the application
+  otb::VectorImage<float> * output_int = nullptr;
+  dyn_cast( output , output_int )
+  im_val = output_int->GetPixel(index).GetElement(0);
+  if ( im_val != 3 )
+  {
+    std::cout<<"Wrong value in test, was expecting 3, got "<<im_val<<std::endl;
+    return_val++;
+  }
+  else
+  {
+    std::cout<<"Case one passed"<<std::endl;
+  }
+
+  // Case two: expression and context
+  app->SetParameterString("exp", "im1b1+val-im2b1");
+  app->UpdateParameters();
+  std::cout<<"Case two: use context to define a constant"<<std::endl;
+  auto desc = app->GetParameterDescription("exp");
+  if (desc.find("Following variables not allowed : val") == std::string::npos)
+  {
+    std::cout<<"Cannot find usual value in the parameter description."<<std::endl;
+    std::cout<<"The test was looking for \"Following variables not allowed : val\""
+    <<" in the parameter description and got \""<<desc<<"\" instead."<<std::endl;
+    return_val++;
+  }
+
+  app->SetParameterString("incontext",argv[2]);
+  // val is set in the context to 1
+  app->UpdateParameters();
+  desc = app->GetParameterDescription("exp");
+  if (desc.find("Valid expression") == std::string::npos )
+  {
+    std::cout<<"Cannot find usual value in the parameter description."<<std::endl;
+    std::cout<<"The test was looking for \"Valid expression\""
+    <<" in the parameter description and got \""<<desc<<"\" instead."<<std::endl;
+    return_val++;
+  }
+  
+  app->Execute();
+  output = app->GetParameterImageBase("out");
+  output->Update();
+  // We need to be carefull as we are taking the direct output of the underlying 
+  // filter in the application
+  dyn_cast( output , output_int )
+  im_val = output_int->GetPixel(index).GetElement(0);
+  if ( im_val != 0 )
+  {
+    std::cout<<"Wrong value in test, was expecting 0, got "<<im_val<<std::endl;
+    return_val++;
+  }
+  else
+  {
+    std::cout<<"Case two passed"<<std::endl;
+  }
+  
+  // Case three: no expression and context
+  app->SetParameterString("exp", "");
+  app->UpdateParameters();
+  std::cout<<"Case three: no parameter exp"<<std::endl;
+  auto exp = app->GetParameterString("exp");
+  if (exp.find("im1b1 + 2*val + im2b1") == std::string::npos )
+  {
+    std::cout<<"The expression value is not set correctly."<<std::endl;
+    std::cout<<"The test was looking for \"im1b1 + 2*val + im2b1\""
+    <<" in the parameter value and got \""<<exp<<"\" instead."<<std::endl;
+    return_val++;
+  }
+  app->Execute();
+  output = app->GetParameterImageBase("out");
+  output->Update();
+  // We need to be carefull as we are taking the direct output of the underlying 
+  // filter in the application
+  dyn_cast( output , output_int )
+  im_val = output_int->GetPixel(index).GetElement(0);
+  if (im_val != 5 )
+  {
+    std::cout<<"Wrong value in test, was expecting 5, got "<<im_val<<std::endl;
+    return_val++;
+  }
+  else
+  {
+    std::cout<<"Case three passed"<<std::endl;
+  }
+  return return_val;
+}
\ No newline at end of file
diff --git a/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.h b/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.h
index 9822cd6ab731a520109484ec9e4bd32947f65468..ce76dd8e44ded0f672a328bb72bcabdf6566dced 100644
--- a/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.h
+++ b/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.h
@@ -112,8 +112,8 @@ public:
   /** Set an expression to be parsed */
   void SetExpression(const std::string& expression);
 
-  /** Return the nth expression to be parsed */
-  std::string GetExpression(int) const;
+  /** Return the nth expression to be parsed*/
+  std::string GetExpression(unsigned int IDExpression) const;
 
   /** Set a matrix (or a vector) */
   void SetMatrix(const std::string& name, const std::string& definition);
@@ -127,9 +127,15 @@ public:
   /** Import constants and expressions from a given filename */
   void ImportContext(const std::string& filename);
 
+  /** Clear all previously set expression*/
+  void ClearExpression();
   /** Return the variable and constant names */
   std::vector<std::string> GetVarNames() const;
 
+  bool GlobalStatsDetected() const
+  {
+    return !m_StatsVarDetected.empty();
+  }
 
 protected :
   BandMathXImageFilter();
@@ -145,11 +151,6 @@ protected :
 
 private :
 
-  bool globalStatsDetected() const
-  {
-    return (m_StatsVarDetected.size()>0);
-  }
-
   typedef struct {
       std::string name;
       ValueType   value;
diff --git a/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.hxx b/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.hxx
index 6092926c7d22d861d0a88a811de26f9f537d016c..44cde5bed777f89ebfada6a1e1c24de73a2802d1 100644
--- a/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.hxx
+++ b/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.hxx
@@ -261,7 +261,13 @@ void BandMathXImageFilter<TImage>
   this->Modified();
 }
 
-
+template< typename TImage >
+void BandMathXImageFilter<TImage>
+::ClearExpression()
+{
+  m_Expression.clear();
+  this->Modified();
+}
 template< typename TImage >
 void BandMathXImageFilter<TImage>
 ::SetMatrix(const std::string& name, const std::string& definition)
@@ -517,9 +523,11 @@ void BandMathXImageFilter<TImage>
 
 template< typename TImage >
 std::string BandMathXImageFilter<TImage>
-::GetExpression(int IDExpression) const
+::GetExpression(unsigned int IDExpression) const
 {
-  return m_Expression[IDExpression];
+  if ( IDExpression < m_Expression.size() )
+    return m_Expression[IDExpression];
+  return "";
 }
 
 
@@ -913,7 +921,7 @@ void BandMathXImageFilter< TImage >
 
   CheckImageDimensions();
   PrepareParsers();
-  if (globalStatsDetected())
+  if (GlobalStatsDetected())
     PrepareParsersGlobStats();
   OutputsDimensions();