diff --git a/.gitlab/merge_request_templates/request_for_changes.md b/.gitlab/merge_request_templates/request_for_changes.md
index 2ef19399b7b3fb09188cbc12dd4daf76bf55e449..31bf9cb52c20e5b67e82be1158a46b7bbd7ca268 100644
--- a/.gitlab/merge_request_templates/request_for_changes.md
+++ b/.gitlab/merge_request_templates/request_for_changes.md
@@ -37,9 +37,11 @@ List or link documentation modifications that were made (doxygen, example, Softw
 The copyright owner is *COPYRIGHT OWNER (OR OWNER'S AGENT)* and has signed the ORFEO ToolBox Contributor License Agreement.
 
 <hr>
+
 ***Check before merging:***
+
 - All discussions are resolved
 - At least 2 :thumbsup: votes from core developers, no :thumbsdown: vote.
 - The feature branch is (reasonably) up-to-date with the base branch
 - Dashboard is green
-- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
\ No newline at end of file
+- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 811a407e92fc28f819e62416cd56e02c26d397f6..6e9e0a2ba1819a98a2feea1ad2d66bb40a64f0e0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -156,16 +156,16 @@ if(NOT OTB_INSTALL_INCLUDE_DIR)
   set(OTB_INSTALL_INCLUDE_DIR include/OTB-${OTB_VERSION_MAJOR}.${OTB_VERSION_MINOR})
 endif()
 if(NOT OTB_INSTALL_APP_DIR)
-  set(OTB_INSTALL_APP_DIR "lib/otb/applications")
+  set(OTB_INSTALL_APP_DIR "${OTB_INSTALL_LIBRARY_DIR}/otb/applications")
 endif()
 if(NOT OTB_INSTALL_PYTHON_DIR)
-  set(OTB_INSTALL_PYTHON_DIR "lib/otb/python")
+  set(OTB_INSTALL_PYTHON_DIR "${OTB_INSTALL_LIBRARY_DIR}/otb/python")
 endif()
 if(NOT OTB_INSTALL_PYTHON3_DIR)
-  set(OTB_INSTALL_PYTHON3_DIR "lib/otb/python3")
+  set(OTB_INSTALL_PYTHON3_DIR "${OTB_INSTALL_LIBRARY_DIR}/otb/python3")
 endif()
 if(NOT OTB_INSTALL_JAVA_DIR)
-  set(OTB_INSTALL_JAVA_DIR "lib/otb/java")
+  set(OTB_INSTALL_JAVA_DIR "${OTB_INSTALL_LIBRARY_DIR}/otb/java")
 endif()
 if(NOT OTB_INSTALL_DATA_DIR)
   set(OTB_INSTALL_DATA_DIR "share/otb")
diff --git a/Documentation/Cookbook/rst/recipes/bandmathx.rst b/Documentation/Cookbook/rst/recipes/bandmathx.rst
index d1036da139043bc626b953df22b2983c6a895c08..54c0d9eb4eb1309ad9a98f1e41237e83d3030bad 100644
--- a/Documentation/Cookbook/rst/recipes/bandmathx.rst
+++ b/Documentation/Cookbook/rst/recipes/bandmathx.rst
@@ -25,7 +25,7 @@ Syntax: first elements
 
 The default prefix name for variables related to the ith input is
 *im(i+1)* (note the indexing from 1 to N, for N inputs). The user has
-the possibility to change this default behaviour by setting its own
+the possibility of changing this default behaviour by setting its own
 prefix.
 
 ::
@@ -90,7 +90,7 @@ represents a pixel of an image made of only one band:
 .. math:: im1+1
 
 A scalar can’t be added to a vector. The right formula is instead (one
-can notice the way that muParserX allows to define vectors on the fly):
+can notice the way that muParserX allows vectors to be defined on the fly):
 
 .. math:: im1+\{ 1 \}
 
@@ -205,8 +205,8 @@ ones. For instance:
 .. math:: im1 ~  mlt ~ 2.0
 
 Note that the operator ’\*’ could have been used instead of ’pw’ one.
-But ’pw’ is a little bit more permisive, and can tolerate
-one-dimensional vector as right element.
+But ’pw’ is a little bit more permisive, and can tolerate a
+one-dimensional vector as the right operand.
 
 **Operators pow and pw** The first operator allows the definition of an
 element-wise exponentiation of two vectors (and even matrices), provided
diff --git a/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst b/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst
index ab2a9a98170936d720cec4daf7a6c913c8ae9d6c..f4b1cf55db391b40d709c00465fe4352be05b561 100644
--- a/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst
+++ b/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst
@@ -4,10 +4,10 @@ Enhance local contrast
 Principles
 ~~~~~~~~~~
 
-Sensor images have often a wide dynamic range. Whereas it is helpful to have
-high precision to do complex processing, it is pretty hard to display high
+Sensor images often have a wide dynamic range. While it is helpful to have
+high precision for complex processing, it is generally difficult to display high
 dynamic images, even on modern screen as the dynamic range for basic screen is
-of 8 bits while images can be encoded on 12 or 16 bits (or even more!).
+of 8 bits while images can be encoded using 12 or 16 bits (or even more!).
 
 .. _Figure1:
       
@@ -41,24 +41,24 @@ You can apply this transformation with the *ContrastEnhancement* application:
                                -out output_image.tif
                                -spatial global
 
-It allows to compress the dynamic without losing details and contrast.
+It compresses the dynamic without losing details and contrast.
 
 Advanced parameters
 ~~~~~~~~~~~~~~~~~~~
 
 The *ContrastEnhancement* provides different options to configure the contrast
-enhancement method. Let us see what there are for.
+enhancement method. Let us see what they are for:
 
 First what you want to equalize. Two modes are available:
 
-* **luminance:** on 3 bands image, the equalization will be done on a single
+* **luminance:** on 3 band images, the equalization will be done on a single
   band which will be a composition of the original bands. The computed gain will
-  then be applied on the different bands. The classical use of this method is to
-  conserve ratio between the different color, conserve the hue.
-* **channel:** each bands are equalized independently.
+  then be applied to the different bands. The classical use of this method is to
+  conserve the ratio between the different colors and conserve the hue.
+* **channel:** each band is equalized independently.
 
 The other option is the local equalization. You can choose a window size that
-will be use to split the image in tiles and histograms will be computed over
+will be used to split the image into tiles and histograms will be computed over
 those tiles. Gain will be interpolated between the adjacent tiles in order to
 give a smooth result.
 
@@ -69,9 +69,9 @@ give a smooth result.
                                -spatial.local.w 500
                                -mode lum
 
-The *ContrastEnhancement* application also offers a way to limit contrast by
-adjusting original histogram with the **hfact** parameter. The limitation factor
-represents the limit height that can have any bucket of the histogram; the
+The *ContrastEnhancement* application also offers a way of limiting the contrast by
+adjusting the original histogram with the **hfact** parameter. The limitation factor
+represents the limit height that any bucket of the histogram can have; the
 application computes the height of the flat histogram and the maximal height is
 the limitation factor time this "flat height".
 
@@ -80,7 +80,7 @@ the limitation factor time this "flat height".
 |image4|
 
 Finally, you can ignore a particular value with the **nodata** parameter, and
-also set manually your minimum and maximum value. Any value out of bound will be
+also manually set your minimum and maximum value. Any value out of bound will be
 ignored.
 
 
diff --git a/Documentation/Cookbook/rst/recipes/python.rst b/Documentation/Cookbook/rst/recipes/python.rst
index 0033762554b92aa9827f9af92c91d6aa7d4b70b5..b03145be78c074b5c761bc2233162a98a553f4cb 100644
--- a/Documentation/Cookbook/rst/recipes/python.rst
+++ b/Documentation/Cookbook/rst/recipes/python.rst
@@ -114,17 +114,17 @@ temporary file.
 In-memory connection
 --------------------
 
-Applications are often use as parts of larger processing
-workflow. Chaining applications currently requires to write/read back
+Applications are often used as part of larger processing
+workflows. Chaining applications currently requires to write/read back
 images between applications, resulting in heavy I/O operations and a
 significant amount of time dedicated to writing temporary files.
 
 Since OTB 5.8, it is possible to connect an output image parameter
 from one application to the input image parameter of the next
 parameter. This results in the wiring of the internal ITK/OTB
-pipelines together, allowing to perform image streaming between the
-applications. There is therefore no more writing of temporary
-images. The last application of the processing chain is responsible
+pipelines together, permitting image streaming between the
+applications. Consequently, this removes the need of writing temporary
+images and improves performance. Only the last application of the processing chain is responsible
 for writing the final result images.
 
 In-memory connection between applications is available both at the C++
@@ -180,8 +180,8 @@ Interactions with OTB pipeline
 
 The application framework has been extended in order to provide ways to
 interact with the pipelines inside each application. It applies only to
-applications that use input or output images. Let's check what are the 
-functions added to the ``Application`` class. There are a lot of getter 
+applications that use input or output images. Let's check which  
+functions are available in the ``Application`` class. There are lots of getter 
 functions:
 
 +---------------------------------+---------------------------------------+
@@ -221,11 +221,11 @@ There is also a function to send orders to the pipeline:
   can be used to measure the requested portion of input images necessary to produce
   an extract of the full output.
 
-Note: a requested region (like other regions in the C++ API of otb::Image) is 
-just a pair of an image index and a size, that define a rectangular extract of
+Note: a requested region (like other regions in the C++ API of otb::Image) consists 
+of an image index and a size, which defines a rectangular extract of
 the full image.
 
-This set of function has been used to enhance the bridge between OTB images
+This set of functions has been used to enhance the bridge between OTB images
 and Numpy arrays. There are now import and export functions available in
 Python that preserve the metadata of the image during conversions to Numpy
 arrays:
@@ -257,7 +257,7 @@ Now some basic Q&A about this interface:
     A: The first one is here for Applications that expect a monoband otb::Image.
     In most cases, you will use the second one: ImportVectorImage.
     
-    Q: What kind of object are there in this dictionary export?
+    Q: What kind of objects are there in this dictionary export?
     A: The array is a numpy.ndarray. The other fields are wrapped
     objects from the OTB library but you can interact with them in a
     Python way: they support ``len()`` and ``str()`` operator, as well as 
@@ -265,7 +265,7 @@ Now some basic Q&A about this interface:
     dictionaries.
     
 This interface allows you to export OTB images (or extracts) to Numpy array,
-process them  by other means, and re-import them with preserved metadatas. Please
+process them  by other means, and re-import them with preserved metadata. Please
 note that this is different from an in-memory connection.
 
 Here is a small example of what can be done:
@@ -368,9 +368,9 @@ arrays. For instance, when converting from OTB to NumPy array:
 * The pixel buffer is copied into a ``numpy.array``
 
 As you can see, there is no export of the metadata, such as origin, spacing,
-geographic projection. It means that if you want to import back a NumPy array into OTB,
-the image won't have any of these metadata. It can be a problem for applications
-doing geometry, projections, and also calibration.
+geographic projection. It means that if you want to re-import a NumPy array back into OTB,
+the image won't have any of these metadata. This can pose problems for applications
+that relate to geometry, projections, and also calibration.
 
 Future developments will probably offer a more adapted structure to import and
 export images between OTB and the Python world.
diff --git a/Documentation/SoftwareGuide/Latex/Installation.tex b/Documentation/SoftwareGuide/Latex/Installation.tex
index a5ee979ae22700ea1223bb14cba798cff3b47dd3..3b91d1d317ca57be57c15702a8e14e416667edfa 100644
--- a/Documentation/SoftwareGuide/Latex/Installation.tex
+++ b/Documentation/SoftwareGuide/Latex/Installation.tex
@@ -4,20 +4,20 @@
 \label{chapter:Installation}
 \index{Installation}
 
-There are two ways to install OTB library on your system: installing from a binary distribution or compiling from sources.
+There are two ways to install OTB on your system: installing from a binary distribution or compiling from sources.
 You can find information about the installation of binary packages for OTB and Monteverdi in the OTB-Cookbook.
 
-This chapter covers compilation of OTB library from source. Note that it covers
-also the compilation of Monteverdi which is integrated as an OTB module since
+This chapter covers the compilation of OTB from source. Note that it also includes
+the compilation of Monteverdi which is integrated as an OTB module since
 version 5.8.
 
 OTB has been developed and tested across different combinations of operating
-systems, compilers, and hardware platforms including Windows, Linux and Mac OSX.
+systems, compilers, and hardware platforms including Windows, GNU/Linux and macOS.
 It is known to work with the following compilers in 32/64 bit:
 \begin{itemize}
 \item Visual Studio 2015 on Windows
 \item GCC 4.x,5.x or CLang 3.x on GNU/Linux
-\item AppleClang on Mac~OS~X (10.8 or higher)
+\item AppleClang on macOS (10.8 or higher)
 \end{itemize}
 
 Since release version 6.2.0, OTB is compiled using the C++14 standard by default.
@@ -29,13 +29,13 @@ configuration files.  CMake generates native makefiles and workspaces that can b
 your choice. CMake is quite sophisticated: it supports complex environments requiring system configuration, compiler
 feature testing, and code generation.
 
-CMake supports several generators to produce the compilation scripts, dependending on the platform and compiler. It can use :
+CMake supports several generators to produce the compilation scripts, dependending on the platform and compiler. It can use:
 \begin{itemize}
 \item Makefiles for Unix systems
 \item Visual Studio workspaces for Windows
 \item NMake Makefiles for Windows
 \item Ninja scripts
-\item and many more ...
+\item and many more...
 \end{itemize}
 The information used by CMake is provided by \code{CMakeLists.txt} files that
 are present in every directory of the OTB source tree. These files contain information that the user provides to CMake
@@ -54,7 +54,7 @@ configuration. This is the easiest way to start.
 \end{itemize}
 
 As shown in figure \ref{fig:CMakeGUI}, CMake has a different interfaces according to your system.
-Refer to section~\ref{sec:compiling-linux} for Linux and Mac~OS~X build instructions
+Refer to section~\ref{sec:compiling-linux} for GNU/Linux and macOS build instructions
 and \ref{sec:compiling-windows} for Windows.
 
 \begin{figure}[tpb]
@@ -144,7 +144,7 @@ See table \ref{tab:otb-dependencies} for the full list of dependencies.
 \end{tiny}
 \end{center}
 
-\section{Linux and Mac OS X}
+\section{GNU/Linux and macOS}
 \label{sec:compiling-linux}
 
 \subsection{Setting up the build environment}
@@ -293,20 +293,20 @@ want to build) :
 \url{https://www.orfeo-toolbox.org/packages}
 \end{center}
 
-Qt library: Unlike other dependencies building Qt5 on all platform is not trivial task but
-OTB SuperBuild makes best effort to make it easier for you. So there is still
+Qt library: Unlike other dependencies, building Qt5 on all platforms is not a trivial task but
+OTB SuperBuild does its level best to facilitate this for the user. So there is still
 some additional package installation, one has to do as a pre-requistie for SuperBuild
 On a GNU/Linux you must have Qt X11 dependencies installed.
-See Qt 5 documentation for list of packages that needs to be installed
+See Qt 5 documentation for the list of packages that need to be installed
 before starting superbuild. https://doc.qt.io/qt-5/linux-requirements.html.
-For a Debian 8.1 system, I installed all Qt5 dependencies with below 'apt-get install'
+For a Debian 8.1 system, all Qt5 dependencies can be installed with the following 'apt-get install' command:
 \texttt{apt-get install libx11-dev libxext-dev libxt-dev libxi-dev libxrandr-dev
 libgl-dev libglu-dev libxinerama-dev libxcursor-dev}
 
-You can also deactivate QT5 and skip this by passing \texttt{-DOTB\_USE\_QT=OFF} to cmake.
-This will give you OTB install without monteverdi, mapla and gui application launchers.
+You can also deactivate Qt5 and skip this by passing \texttt{-DOTB\_USE\_QT=OFF} to cmake, but
+this will install OTB without Monteverdi, Mapla and the GUI application launchers.
 
-For Mac OSX you need to install XCode and Windows 7,8.1,10 requires MSVC 2015 or higher.
+For macOS you need to install XCode and Windows 7,8.1,10 requires MSVC 2015 or higher.
 
 You are now ready to compile OTB!
 Simply use the make command (other targets can be generated with CMake's \texttt{-G} option):
@@ -328,19 +328,20 @@ while:
 \end{verbatim}
 will launch the graphical version.
 
-To be able to use your OTB build from everywhere, we recommend the following.
-First, add \texttt{bin/} directory to your PATH for easy access:
+In order to ensure access to your OTB build from anywhere within your system, we recommend setting the following
+environment variables.
+Firstly, add \texttt{bin/} directory to your PATH for easy access:
 \begin{verbatim}
 export PATH=$PATH:~/OTB/install/bin
 \end{verbatim}
 
-Second, add the \texttt{lib/} directory to your LD\_LIBRARY\_PATH:
+Secondly, add the \texttt{lib/} directory to your LD\_LIBRARY\_PATH:
 \begin{verbatim}
 export LD_LIBRARY_PATH=~/OTB/install/lib:$LD_LIBRARY_PATH
 \end{verbatim}
 
 Monteverdi is integrated as an OTB module since release 5.8 and it is compiled
-by the SuperBuild (as long as GLEW, GLUT, OPENGL, Qt and QWT modules are
+by the SuperBuild (provided that GLEW, GLUT, OPENGL, Qt and QWT modules are
 activated).
 
 To use OTB applications from within Monteverdi you will need to define the
@@ -377,8 +378,8 @@ off the CMake variable OTB\_BUILD\_DEFAULT\_MODULES, configure, and then switch
 off each \texttt{Module\_module\_name} variable.  To provide an overview on how
 things work, the option \texttt{COMPONENTS} of the CMake command find\_package
 is used in order to only load the requested modules.  This module-specific list
-prevent CMake from performing a blind search; it is also a convienent way to
-monitor the dependencies of each module.
+prevents CMake from performing a blind search; it is also a convienent way of
+monitoring the dependencies of each module.
 \begin{verbatim}
 find_package(OTB COMPONENTS OTBCommon OTBTransform [...])
 \end{verbatim} 
@@ -454,30 +455,5 @@ Everything that is needed for OTB development on Windows, including compiling fr
 \section{Known issues}
 \label{sec:knownissues}
 
-\begin{itemize}
-\item  openjpeg/ITK
-\end{itemize}
-
-It is important to know that the OpenJpeg library doesn't support name mangling since version 2.0.
-As a consequence, if other libraries linked by your project already contain OpenJpeg, there may be a symbol conflict at run-time.
-For instance, this was observed with OTB build on a recent ITK version (ver. 4).
-The ITK library already had a version of OpenJpeg in libitkopenjpeg-*.so, which contained the OpenJpeg symbols un-wrapped.
-These symbols were also loaded by the GDAL driver but only the first ones were used, which caused a crash.
-
-Hopefully, thanks to the modular architecture of ITK, the library libitkopenjpeg-*.so is not imported anymore inside OTB.
-However the OpenJPEG headers may be present in ITK include directory. As the current architecture doesn't allow to tune
-include order between modules, the OpenJPEG header from ITK can be included before your own OpenJPEG install. There are
-two ways to avoid this situation :
-\begin{itemize}
-\item Use an ITK without GDCM nor ITKReview (only these modules depend on OpenJPEG)
-\item Hide the header openjpeg.h in the ITK include directory.
-\end{itemize}
-
-More information can be found here : \url{http://wiki.orfeo-toolbox.org/index.php/JPEG2000_with_GDAL_OpenJpeg_plugin}
-
-\begin{itemize}
-\item  libkml / Ubuntu 12.04
-\end{itemize}
-
-Another issue is related to the official package of libkml under Ubuntu 12.04.
-Users of this plateform should disable the option OTB\_USE\_KML, so that OTB won't be built with this third-party.
+Please check \url{https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues} with
+an updated list of known issues (tag bug).
diff --git a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
index 26b11023f6e5e1a441b5b592d991d2a601b210e8..05aee81453b8b62de06c103d4b96c70b40cfce0b 100644
--- a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
@@ -52,8 +52,9 @@ public:
                     "validation sets per class and per image.\n Several classifier parameters can be set depending on the chosen classifier. In the "
                     "validation process, the confusion matrix is organized the following way: rows = reference labels, columns = produced labels. "
                     "In the header of the optional confusion matrix output file, the validation (reference) and predicted (produced) class labels"
-                    " are ordered according to the rows/columns of the confusion matrix.\n This application is based on LibSVM and OpenCV Machine Learning "
-                    "(2.3.1 and later)." );
+                    " are ordered according to the rows/columns of the confusion matrix.\n This application is based on LibSVM, OpenCV Machine Learning "
+                    "(2.3.1 and later), and Shark ML. The output of this application is a text model file, whose format corresponds to the "
+                    "ML model type chosen. There is no image nor vector data output." );
     SetDocLimitations( "None" );
     SetDocAuthors( "OTB-Team" );
     SetDocSeeAlso( "OpenCV documentation for machine learning http://docs.opencv.org/modules/ml/doc/ml.html " );
diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
index 1f3dc77b0d36e4b0ee7cd87769a71cbf67fe948b..6f142bb04a28b69588cecb36045ab82eec2e7055 100644
--- a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
@@ -63,7 +63,10 @@ protected:
     SetDocName( "Train Vector Classifier" );
     SetDocLongDescription( "This application trains a classifier based on "
       "labeled geometries and a list of features to consider for "
-      "classification." );
+      "classification.\nThis application is based on LibSVM, OpenCV Machine "
+      "Learning (2.3.1 and later), and Shark ML The output of this application "
+      "is a text model file, whose format corresponds to the ML model type "
+      "chosen. There is no image nor vector data output.");
     SetDocLimitations( " " );
     SetDocAuthors( "OTB Team" );
     SetDocSeeAlso( " " );
diff --git a/Modules/Applications/AppClassification/include/otbLearningApplicationBase.hxx b/Modules/Applications/AppClassification/include/otbLearningApplicationBase.hxx
index 7ecc30ab6afcb7b7db71b51ae4d966a39f2c523a..01faddb594deeaaa463f31c6f985fe6fa8531478 100644
--- a/Modules/Applications/AppClassification/include/otbLearningApplicationBase.hxx
+++ b/Modules/Applications/AppClassification/include/otbLearningApplicationBase.hxx
@@ -138,7 +138,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
   RGBAPixelConverter<int,int>::Pointer dummyFilter =
     RGBAPixelConverter<int,int>::New();
   dummyFilter->SetProgress(0.0f);
-  this->AddProcess(dummyFilter,"Classify...");
+  this->AddProcess(dummyFilter,"Validation...");
   dummyFilter->InvokeEvent(itk::StartEvent());
 
   // load a machine learning model from file and predict the input sample list
@@ -169,6 +169,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
         typename TargetListSampleType::Pointer trainingLabeledListSample,
         std::string modelPath)
 {
+  otbAppLogINFO("Computing model file : "<<modelPath);
   // Setup fake reporter
   RGBAPixelConverter<int,int>::Pointer dummyFilter =
     RGBAPixelConverter<int,int>::New();
diff --git a/Modules/Core/Common/include/otbMacro.h b/Modules/Core/Common/include/otbMacro.h
index 6a248d4551a2f3f57220b4de62f3550a7dee5ad0..5327911da2b164e48f837236dbdc3078605c8aa8 100644
--- a/Modules/Core/Common/include/otbMacro.h
+++ b/Modules/Core/Common/include/otbMacro.h
@@ -129,7 +129,7 @@ namespace otb
       { \
       std::ostringstream message; \
       message << "otb::ERROR Unknown error while running " << # command << " (catch(...) )"; \
-      ::itk::ExceptionObject e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION); \
+      ::itk::ExceptionObject e_(__FILE__, __LINE__, message.str(), ITK_LOCATION); \
       throw e_; \
       } \
     std::cout << " Checking valid command " << # command " ok." << std::endl; \
@@ -160,14 +160,14 @@ namespace otb
       { \
       std::ostringstream message; \
       message << "otb::ERROR Unknown error while running " << # command << " (catch(...) )"; \
-      ::itk::ExceptionObject e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION); \
+      ::itk::ExceptionObject e_(__FILE__, __LINE__, message.str(), ITK_LOCATION); \
       throw e_; \
       } \
     if (result == 1) \
       { \
       std::ostringstream message; \
       message << "otb::ERROR: " << # command << " should be throwing an exception."; \
-      ::itk::ExceptionObject e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION); \
+      ::itk::ExceptionObject e_(__FILE__, __LINE__, message.str(), ITK_LOCATION); \
       throw e_; \
       } \
     }
diff --git a/Modules/Core/ObjectList/include/otbObjectListToObjectListFilter.hxx b/Modules/Core/ObjectList/include/otbObjectListToObjectListFilter.hxx
index 16e3e46de47070b6607f8f8303eb76b7a667b555..3a87bfa4688940d1c7e45ae6f47b9f6d11b3d680 100644
--- a/Modules/Core/ObjectList/include/otbObjectListToObjectListFilter.hxx
+++ b/Modules/Core/ObjectList/include/otbObjectListToObjectListFilter.hxx
@@ -140,7 +140,7 @@ ObjectListToObjectListFilter<TInputList, TOutputList>
   std::ostringstream message;
   message << "itk::ERROR: " << this->GetNameOfClass()
           << "(" << this << "): " << "Subclass should override this method!!!";
-  itk::ExceptionObject e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION);
+  itk::ExceptionObject e_(__FILE__, __LINE__, message.str(), ITK_LOCATION);
   throw e_;
 
 }
diff --git a/Modules/Core/PointSet/include/otbImageToPointSetFilter.hxx b/Modules/Core/PointSet/include/otbImageToPointSetFilter.hxx
index 9ac44aeef49112dd1c690bb3b8e3aecd1febc9cd..4186b715e92a66d5ddf796971ba8e5edfde870ca 100644
--- a/Modules/Core/PointSet/include/otbImageToPointSetFilter.hxx
+++ b/Modules/Core/PointSet/include/otbImageToPointSetFilter.hxx
@@ -265,7 +265,7 @@ ImageToPointSetFilter<TInputImage, TOutputPointSet>
   std::ostringstream message;
   message << "itk::ERROR: " << this->GetNameOfClass()
           << "(" << this << "): " << "Subclass should override this method!!!";
-  itk::ExceptionObject e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION);
+  itk::ExceptionObject e_(__FILE__, __LINE__, message.str(), ITK_LOCATION);
   throw e_;
 
 }
diff --git a/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.h b/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.h
index 0ad8a0c7b6b8585b8727d7e57508a2674a22138e..1360b703d6ea45ffc3e874774d296efb7d6c0872 100644
--- a/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.h
+++ b/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.h
@@ -54,36 +54,42 @@ class StatisticsAccumulator
 {
 public:
 
-  typedef typename TRealVectorPixelType::ValueType RealValueType;
+  typedef typename TRealVectorPixelType::ValueType  RealValueType;
+  typedef uint64_t                                  PixelCountType;
+  typedef itk::VariableLengthVector<PixelCountType> PixelCountVectorType;
 
   // Constructor (default)
-  StatisticsAccumulator(){}
+  StatisticsAccumulator() : m_Count(), m_NoDataValue(), m_UseNoDataValue() {}
 
   // Constructor (initialize the accumulator with the given pixel)
-  StatisticsAccumulator(const TRealVectorPixelType & pixel)
+  StatisticsAccumulator(RealValueType noDataValue,
+                        bool useNoDataValue,
+                        const TRealVectorPixelType & pixel)
+    : m_NoDataValue(noDataValue),
+      m_Count(1),
+      m_UseNoDataValue(useNoDataValue)
   {
     m_Count = 1;
     m_Sum = pixel;
     m_Min = pixel;
     m_Max = pixel;
     m_SqSum = pixel;
+    m_BandCount.SetSize(pixel.GetSize());
     for (unsigned int band = 0 ; band < m_SqSum.GetSize() ; band++)
-      m_SqSum[band] *= m_SqSum[band];
-  }
-
-  // Constructor (other)
-  StatisticsAccumulator(const StatisticsAccumulator & other)
-  {
-    m_Count = other.m_Count;
-    m_Sum = other.m_Sum;
-    m_Min = other.m_Min;
-    m_Max = other.m_Max;
-    m_SqSum = other.m_SqSum;
+      {
+      auto val = pixel[band];
+      if (!m_UseNoDataValue || val != m_NoDataValue)
+        {
+        m_BandCount[band] = 1;
+        m_SqSum[band] *= m_SqSum[band];
+        }
+      else
+        {
+        m_BandCount[band] = 0;
+        }
+    }
   }
 
-  // Destructor
-  ~StatisticsAccumulator(){}
-
   // Function update (pixel)
   void Update(const TRealVectorPixelType & pixel)
   {
@@ -93,8 +99,13 @@ public:
       {
       const RealValueType value = pixel[band];
       const RealValueType sqValue = value * value;
-      UpdateValues(value, sqValue, value, value,
-                   m_Sum[band], m_SqSum[band], m_Min[band], m_Max[band]);
+
+      UpdateValues(!m_UseNoDataValue || value != m_NoDataValue,
+                   value, sqValue,
+                   value, value,
+                   m_BandCount[band],
+                   m_Sum[band], m_SqSum[band],
+                   m_Min[band], m_Max[band]);
       }
   }
 
@@ -105,12 +116,17 @@ public:
     const unsigned int nBands = other.m_Sum.GetSize();
     for (unsigned int band = 0 ; band < nBands ; band ++ )
       {
-      UpdateValues(other.m_Sum[band], other.m_SqSum[band], other.m_Min[band], other.m_Max[band],
-                   m_Sum[band], m_SqSum[band], m_Min[band], m_Max[band]);
+      UpdateValues(other.m_BandCount[band],
+                   other.m_Sum[band], other.m_SqSum[band],
+                   other.m_Min[band], other.m_Max[band],
+                   m_BandCount[band],
+                   m_Sum[band], m_SqSum[band],
+                   m_Min[band], m_Max[band]);
       }
   }
 
   // Accessors
+  itkGetMacro(BandCount, PixelCountVectorType);
   itkGetMacro(Sum, TRealVectorPixelType);
   itkGetMacro(SqSum, TRealVectorPixelType);
   itkGetMacro(Min, TRealVectorPixelType);
@@ -118,11 +134,14 @@ public:
   itkGetMacro(Count, double);
 
 private:
-  void UpdateValues(const RealValueType & otherSum, const RealValueType & otherSqSum,
-                    const RealValueType & otherMin, const RealValueType & otherMax,
+  void UpdateValues(PixelCountType otherCount,
+                    RealValueType otherSum, RealValueType otherSqSum,
+                    RealValueType otherMin, RealValueType otherMax,
+                    PixelCountType & count,
                     RealValueType & sum, RealValueType & sqSum,
                     RealValueType & min, RealValueType & max)
   {
+  count += otherCount;
   sum += otherSum;
   sqSum += otherSqSum;
   if (otherMin < min)
@@ -132,11 +151,14 @@ private:
   }
 
 protected:
+  PixelCountVectorType m_BandCount;
   TRealVectorPixelType m_Sum;
   TRealVectorPixelType m_SqSum;
   TRealVectorPixelType m_Min;
   TRealVectorPixelType m_Max;
-  double m_Count;
+  RealValueType m_NoDataValue;
+  PixelCountType m_Count;
+  bool m_UseNoDataValue;
 };
 
 /** \class PersistentStreamingStatisticsMapFromLabelImageFilter
@@ -198,6 +220,11 @@ public:
   itkStaticConstMacro(ImageDimension, unsigned int,
                       TInputVectorImage::ImageDimension);
 
+  itkGetMacro(NoDataValue, VectorPixelValueType);
+  itkSetMacro(NoDataValue, VectorPixelValueType);
+  itkGetMacro(UseNoDataValue, bool);
+  itkSetMacro(UseNoDataValue, bool);
+
   /** Smart Pointer type to a DataObject. */
   typedef typename itk::DataObject::Pointer DataObjectPointer;
   typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType;
@@ -260,6 +287,9 @@ private:
   PersistentStreamingStatisticsMapFromLabelImageFilter(const Self &) = delete;
   void operator =(const Self&) = delete;
 
+  VectorPixelValueType                   m_NoDataValue;
+  bool                                   m_UseNoDataValue;
+
   AccumulatorMapCollectionType           m_AccumulatorMaps;
 
   PixelValueMapType                      m_MeanRadiometricValue;
@@ -337,6 +367,9 @@ public:
   typedef TInputVectorImage                   VectorImageType;
   typedef TLabelImage                         LabelImageType;
 
+  typedef typename VectorImageType::PixelType                        VectorPixelType;
+  typedef typename VectorImageType::PixelType::ValueType             VectorPixelValueType;
+
   typedef typename Superclass::FilterType::PixelValueMapType         PixelValueMapType;
   typedef typename Superclass::FilterType::PixelValueMapObjectType   PixelValueMapObjectType;
 
@@ -397,6 +430,30 @@ public:
     return this->GetFilter()->GetLabelPopulationMap();
   }
 
+  /** Set the no data value */
+  void SetNoDataValue(VectorPixelValueType value)
+  {
+      this->GetFilter()->SetNoDataValue(value);
+  }
+
+  /** Return the no data value */
+  VectorPixelValueType GetNoDataValue() const
+  {
+      return this->GetFilter()->GetNoDataValue();
+  }
+
+  /** Configure whether no data pixels ignored, treating each band independently */
+  void SetUseNoDataValue(bool useNoDataValue)
+  {
+      this->GetFilter()->SetUseNoDataValue(useNoDataValue);
+  }
+
+  /** Return whether no data pixels are ignored */
+  bool GetUseNoDataValue() const
+  {
+      return this->GetFilter()->GetUseNoDataValue();
+  }
+
 protected:
   /** Constructor */
   StreamingStatisticsMapFromLabelImageFilter() {}
diff --git a/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.hxx b/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.hxx
index 4fdd5cc0ffeae1622a8a4a449ff38098725b7a05..582bf8607b0af38a4fc62ffa4568be17aa5b67dc 100644
--- a/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.hxx
+++ b/Modules/Filtering/Statistics/include/otbStreamingStatisticsMapFromLabelImageFilter.hxx
@@ -35,6 +35,7 @@ namespace otb
 template<class TInputVectorImage, class TLabelImage>
 PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelImage>
 ::PersistentStreamingStatisticsMapFromLabelImageFilter()
+    : m_UseNoDataValue()
 {
   // first output is a copy of the image, DataObject created by
   // superclass
@@ -155,20 +156,21 @@ PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelIm
  {
   // Update temporary accumulator
   AccumulatorMapType outputAcc;
+  auto endAcc = outputAcc.end();
 
   for (auto const& threadAccMap: m_AccumulatorMaps)
     {
     for(auto const& it: threadAccMap)
       {
-      const LabelPixelType label = it.first;
-      if (outputAcc.count(label) <= 0)
+      auto label = it.first;
+      auto itAcc = outputAcc.find(label);
+      if (itAcc == endAcc)
         {
-        AccumulatorType newAcc(it.second);
-        outputAcc[label] = newAcc;
+        outputAcc.emplace(label, it.second);
         }
       else
         {
-        outputAcc[label].Update(it.second);
+        itAcc->second.Update(it.second);
         }
       }
     }
@@ -177,18 +179,20 @@ PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelIm
   for(auto& it: outputAcc)
     {
     const LabelPixelType label = it.first;
-    const double count = it.second.GetCount();
-    const RealVectorPixelType sum   = it.second.GetSum();
-    const RealVectorPixelType sqSum = it.second.GetSqSum();
+    const auto &bandCount = it.second.GetBandCount();
+    const auto &sum       = it.second.GetSum();
+    const auto &sqSum     = it.second.GetSqSum();
 
     // Count
-    m_LabelPopulation[label] = count;
+    m_LabelPopulation[label] = it.second.GetCount();
 
     // Mean & stdev
     RealVectorPixelType mean (sum);
     RealVectorPixelType std (sqSum);
     for (unsigned int band = 0 ; band < mean.GetSize() ; band++)
       {
+      // Number of valid pixels in band
+      auto count = bandCount[band];
       // Mean
       mean[band] /= count;
 
@@ -265,28 +269,31 @@ PersistentStreamingStatisticsMapFromLabelImageFilter<TInputVectorImage, TLabelIm
 
   itk::ImageRegionConstIterator<TInputVectorImage> inIt(inputPtr, outputRegionForThread);
   itk::ImageRegionConstIterator<TLabelImage> labelIt(labelInputPtr, outputRegionForThread);
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
 
-  typename VectorImageType::PixelType value;
-  typename LabelImageType::PixelType label;
+  auto &acc = m_AccumulatorMaps[threadId];
+  auto endAcc = acc.end();
 
   // do the work
   for (inIt.GoToBegin(), labelIt.GoToBegin();
        !inIt.IsAtEnd() && !labelIt.IsAtEnd();
        ++inIt, ++labelIt)
     {
-      value = inIt.Get();
-      label = labelIt.Get();
+      const auto &value = inIt.Get();
+      auto label = labelIt.Get();
 
       // Update the accumulator
-      if (m_AccumulatorMaps[threadId].count(label) <= 0) //add new element to the map
+      auto itAcc = acc.find(label);
+      if (itAcc == endAcc)
         {
-        AccumulatorType newAcc(value);
-        m_AccumulatorMaps[threadId][label] = newAcc;
+        acc.emplace(label, AccumulatorType(this->GetNoDataValue(), this->GetUseNoDataValue(), value));
         }
       else
         {
-        m_AccumulatorMaps[threadId][label].Update(value);
+        itAcc->second.Update(value);
         }
+
+      progress.CompletedPixel();
     }
 }
 
diff --git a/Modules/Filtering/Wavelet/include/otbWaveletFilterBank.hxx b/Modules/Filtering/Wavelet/include/otbWaveletFilterBank.hxx
index 974a4c4dbdc8ceb8e9f85ffb360171e42dff423b..b3bae731d8f6fb43f0f9647a8f8ab39406b91651 100644
--- a/Modules/Filtering/Wavelet/include/otbWaveletFilterBank.hxx
+++ b/Modules/Filtering/Wavelet/include/otbWaveletFilterBank.hxx
@@ -377,7 +377,7 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::FORWARD>
     std::ostringstream msg;
     msg << "Output number 1<<" << dir << " = " << (1 << dir) << " not allocated\n";
     msg << "Number of expected outputs " << this->GetNumberOfOutputs() << "\n";
-    throw itk::ExceptionObject(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     }
 
   itk::ProgressReporter reporter(this, threadId,
diff --git a/Modules/Filtering/Wavelet/src/otbWaveletGenerator.cxx b/Modules/Filtering/Wavelet/src/otbWaveletGenerator.cxx
index 7680210873bcd582c9f4a85bec43a6ac34371028..c80b6ed76a0f07eab2a3a6fea892434dc96ba2cc 100644
--- a/Modules/Filtering/Wavelet/src/otbWaveletGenerator.cxx
+++ b/Modules/Filtering/Wavelet/src/otbWaveletGenerator.cxx
@@ -39,7 +39,7 @@ WaveletGenerator<TMotherWaveletOperator>
   std::ostringstream msg;
   msg << "The mother wavelet ID " << TMotherWaveletOperator;
   msg << " is unknown or has to be implemented...\n";
-  throw itk::ExceptionObject(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+  throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
 
   return "Unknown";
 }
@@ -52,7 +52,7 @@ WaveletGenerator<TMotherWaveletOperator>
   std::ostringstream msg;
   msg << "The mother wavelet ID " << TMotherWaveletOperator;
   msg << " is unknown or has to be implemented...\n";
-  throw itk::ExceptionObject(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+  throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
 }
 
 template <Wavelet::Wavelet TMotherWaveletOperator>
@@ -63,7 +63,7 @@ WaveletGenerator<TMotherWaveletOperator>
   std::ostringstream msg;
   msg << "The mother wavelet ID " << TMotherWaveletOperator;
   msg << " is unknown or has to be implemented (check the hxx file)...\n";
-  throw itk::ExceptionObject(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+  throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
 }
 
 /**
diff --git a/Modules/IO/ImageIO/include/otbImageSeriesFileReader.hxx b/Modules/IO/ImageIO/include/otbImageSeriesFileReader.hxx
index 2fb1d0fc5ba70a64100010d5938d4556edb474f5..43b6524b259e642e381c67f028f00e26203ef90d 100644
--- a/Modules/IO/ImageIO/include/otbImageSeriesFileReader.hxx
+++ b/Modules/IO/ImageIO/include/otbImageSeriesFileReader.hxx
@@ -54,7 +54,7 @@ ImageSeriesFileReader<TImage, TInternalImage>
   std::ostringstream msg;
   msg << "Something wrong... Check the template definition of this class in the program...\n";
   msg << "\"ENVI META FILE\" FileName: " << this->m_FileName << "\n";
-  ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+  ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
   throw e;
 }
 
@@ -100,7 +100,7 @@ ImageSeriesFileReader<Image<TPixel, 2>, Image<TInternalPixel, 2> >
     std::ostringstream msg;
     msg << "Unable to handle multicomponent file from Image<> class\n";
     msg << "\"ENVI META FILE\" FileName: " << this->m_FileName << "\n";
-    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     }
 
@@ -109,7 +109,7 @@ ImageSeriesFileReader<Image<TPixel, 2>, Image<TInternalPixel, 2> >
     std::ostringstream msg;
     msg << "Unable to handle given band reading from multicomponent file with Image<> class\n";
     msg << "\"ENVI META FILE\" FileName: " << this->m_FileName << "\n";
-    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     }
   return;
@@ -190,7 +190,7 @@ ImageSeriesFileReader<Image<TPixel, 2>, VectorImage<TInternalPixel, 2> >
     std::ostringstream msg;
     msg << "Unable to handle multicomponent file from Image<> class as output\n";
     msg << "\"ENVI META FILE\" FileName: " << this->m_FileName << "\n";
-    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     }
   return;
diff --git a/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.h b/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.h
index 2a7fadfbdbb61f7da614c3e5eb0b9db99ec05748..1c6cab107292c10c16d2264745ebd805e0f80b22 100644
--- a/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.h
+++ b/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.h
@@ -49,6 +49,11 @@ public:
                                  const char* message = "Error in IO",
                                  const char* loc = "Unknown") :
     itk::ExceptionObject(file, line, message, loc) {}
+
+  ImageSeriesFileReaderException(const std::string& file, unsigned int line,
+                                 const std::string& message = "Error in IO",
+                                 const std::string& loc = "Unknown") :
+    itk::ExceptionObject(file, line, message, loc) {}
 };
 
 /** \class ImageSeriesFileReaderBase
diff --git a/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.hxx b/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.hxx
index 037a4e054eea364a885bd5e374ce8cb5df8efa67..261587ca9fc4803b319b4add9f1b6d40c36087b8 100644
--- a/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.hxx
+++ b/Modules/IO/ImageIO/include/otbImageSeriesFileReaderBase.hxx
@@ -117,7 +117,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
     inputFile.close();
     std::ostringstream msg;
     msg << "The file " << m_FileName << " is not a \"ENVI META FILE\" format\n";
-    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     return;
     }
@@ -128,7 +128,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
     inputFile.close();
     std::ostringstream msg;
     msg << "The file " << m_FileName << " is not a \"ENVI META FILE\" format\n";
-    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     return;
     }
@@ -139,7 +139,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
     inputFile.close();
     std::ostringstream msg;
     msg << "The file " << m_FileName << " is not a \"ENVI META FILE\" format\n";
-    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     return;
     }
@@ -171,7 +171,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
         std::ostringstream msg;
         msg << "Unable to read image files in the  \"ENVI META FILE\" file \n";
         msg << "FileName: " << m_FileName << "\n";
-        ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+        ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
         throw e;
         return;
         }
@@ -205,7 +205,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
       std::ostringstream msg;
       msg << "Unable to read the number of bands in the images in the  \"ENVI META FILE\" file \n";
       msg << "FileName: " << m_FileName << "\n";
-      ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+      ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
       throw e;
       return;
       }
@@ -277,7 +277,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
         msg << "Unable to read image region in the  \"ENVI META FILE\" file \n";
         msg << "FileName : " << m_FileName << "\n";
         msg << "ImageName: " << imageFileName << "\n";
-        ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+        ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
         throw e;
         return;
         }
@@ -294,7 +294,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
       msg << "Unable to read image region selection in the  \"ENVI META FILE\" file \n";
       msg << "FileName : " << m_FileName << "\n";
       msg << "ImageName: " << imageFileName << "\n";
-      ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+      ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
       throw e;
       return;
       }
@@ -338,7 +338,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
   std::ostringstream msg;
   msg << "Something wrong... Check the template definition of this class in the program...\n";
   msg << "\"ENVI META FILE\" FileName: " << m_FileName << "\n";
-  ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+  ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
   throw e;
 }
 
@@ -464,7 +464,7 @@ ImageSeriesFileReaderBase<TImage, TInternalImage>
     std::ostringstream msg;
     msg << "The file couldn't be opened for reading. "
         << std::endl << "Filename: " << file << std::endl;
-    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    ImageSeriesFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     return;
     }
diff --git a/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.h b/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.h
index 275c6cfbd284cbbbe78d7cc8b07059b1f58d309f..9ecdbd0e1515952497c4de7c86776f60a71a7a5a 100644
--- a/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.h
+++ b/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.h
@@ -54,6 +54,13 @@ public:
     itk::ExceptionObject(file, line, message, loc)
   {
   }
+
+  VectorDataFileReaderException(const std::string& file, unsigned int line,
+                                const std::string& message = "Error in IO",
+                                const char* loc = "Unknown") :
+    itk::ExceptionObject(file, line, message, loc)
+  {
+  }
 };
 
 /** \brief Data source that reads vector data from a single file.
diff --git a/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.hxx b/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.hxx
index 275539f86baf7b6b806e5a71469c1a10e17e576b..9f5098b954343fd58a9647f112e289a622bcce03 100644
--- a/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.hxx
+++ b/Modules/IO/VectorDataIO/include/otbVectorDataFileReader.hxx
@@ -93,7 +93,7 @@ VectorDataFileReader<TOutputVectorData>
       msg << "The file couldn't be opened for reading. "
           << std::endl << "Filename: " << this->m_FileName
           << std::endl;
-      VectorDataFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+      VectorDataFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
       throw e;
       return;
 
@@ -174,7 +174,7 @@ VectorDataFileReader<TOutputVectorData>
       msg << "  You probably failed to set a file suffix, or" << std::endl;
       msg << "    set the suffix to an unsupported type." << std::endl;
       }
-    VectorDataFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    VectorDataFileReaderException e(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     throw e;
     return;
     }
diff --git a/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx b/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx
index 3473e2f423eb90b969339f1ee20fd2b0b315337a..93da2844a9180b93392a7523380028ab878ff1ac 100644
--- a/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx
+++ b/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx
@@ -51,7 +51,7 @@ MarkovRandomFieldFilter<TInputImage, TClassifiedImage>
     std::ostringstream msg;
     msg << "Input image dimension: " << InputImageDimension << " != output image dimension: " <<
     ClassifiedImageDimension;
-    throw itk::ExceptionObject(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
+    throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
     }
   m_InputImageNeighborhoodRadius.Fill(m_NeighborhoodRadius);
   //     m_MRFNeighborhoodWeight.resize(0);
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
index d1a6e50a7df621be6feddd4e5a2bb3d6e0479940..92c4fed306daa0c796be5bb64dfdfa47168a9860 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
@@ -61,9 +61,13 @@ public:
                        const char* loc = "Unknown");
 
   /** Constructor. */
-  ApplicationException(const std::string &file, unsigned int line,
+  ApplicationException(const std::string& file, unsigned int line,
                        const char* message = "Application error.",
                        const char* loc = "Unknown");
+
+  ApplicationException(const std::string& file, unsigned int line,
+                       const std::string& message = "Application error.",
+                       const std::string& loc = "Unknown");
 };
 
 namespace Wrapper
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h
index 39e4c57d938c3e58c6064b30da019aed529585bf..1024b46329246b849dd548a6a010eb0dc7f728b1 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperMacros.h
@@ -30,7 +30,7 @@
     {                                                                                          \
       std::ostringstream message;                                                              \
       message << "otb::ApplicationException " x;                                               \
-      ::otb::ApplicationException e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION); \
+      ::otb::ApplicationException e_(__FILE__, __LINE__, message.str(), ITK_LOCATION); \
       throw e_; /* Explicit naming to work around Intel compiler bug.  */                      \
     } \
   }
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
index 6043858e40230b7c597f4a2552219187ef1c1c6c..46635f7954c0fe78586d113e16755e2d540f8cbe 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
@@ -64,6 +64,12 @@ ExceptionObject(file, line, message, loc)
 {
 }
 
+ApplicationException::ApplicationException(const std::string &file, unsigned int line,
+                   const std::string& message, const std::string& loc) :
+ExceptionObject(file, line, message, loc)
+{
+}
+
 namespace Wrapper
 {
 
diff --git a/Modules/Wrappers/QGIS/src/CMakeLists.txt b/Modules/Wrappers/QGIS/src/CMakeLists.txt
index bb1208021ff12df7ce8a0d0e880f3048c7338a75..d87694ff0f283e56b3ceb3ea67cbdc32bc4d42d5 100644
--- a/Modules/Wrappers/QGIS/src/CMakeLists.txt
+++ b/Modules/Wrappers/QGIS/src/CMakeLists.txt
@@ -27,6 +27,8 @@ add_custom_command(TARGET otbQgisDescriptor PRE_BUILD
   COMMAND "${CMAKE_COMMAND}" "-E" "make_directory"   "${OTB_BINARY_DIR}/${OTB_INSTALL_DATA_DIR}/description/"
   )
 
+file(RELATIVE_PATH app_location ${OTB_BINARY_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/otb/applications)
+
 set(app_names ${OTB_APPLICATIONS_NAME_LIST})
 list(REMOVE_ITEM app_names "TestApplication")
 list(REMOVE_ITEM app_names "ApplicationExample")
@@ -44,9 +46,9 @@ foreach(app_name ${app_names})
   set(dfile "${OTB_BINARY_DIR}/${OTB_INSTALL_DATA_DIR}/description/${app_name}.txt")
   add_custom_command(OUTPUT "${dfile}"
     COMMAND ${generate_descriptor_cmd}
-    "${app_name}" "${OTB_BINARY_DIR}/${OTB_INSTALL_APP_DIR}" "${OTB_BINARY_DIR}/${OTB_INSTALL_DATA_DIR}/description/"
+    "${app_name}" "${app_location}" "./${OTB_INSTALL_DATA_DIR}/description/"
     WORKING_DIRECTORY ${OTB_BINARY_DIR}
-    COMMENT "./bin/otbQgisDescriptor ${app_name} ./${OTB_INSTALL_APP_DIR} ./${OTB_INSTALL_DATA_DIR}/description/"
+    COMMENT "./bin/otbQgisDescriptor ${app_name} ${app_location} ./${OTB_INSTALL_DATA_DIR}/description/"
     VERBATIM)
   list(APPEND dfiles "${dfile}")
 endforeach()