diff --git a/CMake/CTestCustom.cmake.in b/CMake/CTestCustom.cmake.in
index 612027d6e5c8fd494e34aea7afede597568d6d00..a2416c69f341f60e37c060ce71168ad0adfa2051 100644
--- a/CMake/CTestCustom.cmake.in
+++ b/CMake/CTestCustom.cmake.in
@@ -38,9 +38,11 @@
 #----------------------------------------------------------------------
 
 set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 1000000)
-set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS 300)
 set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS 50)
 
+if(NOT DEFINED CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS)
+  set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS 300)
+endif()
 
 set(CTEST_CUSTOM_COVERAGE_EXCLUDE
  ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
@@ -86,6 +88,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION
   # Ignore clang's summary warning, assuming prior text has matched some
   # other warning expression:
   "[0-9,]+ warnings? generated."
+  "cl...Command.line.warning.D9025"
   ".*include.opencv2.*warning.*"
   ".*include.opencv2.*note.*"
   ".*include.kml.*warning.*"
diff --git a/CMake/FindShark.cmake b/CMake/FindShark.cmake
index 7dced6bb432c256b17cafd6bd3394bea97bac4e8..c223e4a16c2b681d7aa9944987ead6c58da6df69 100644
--- a/CMake/FindShark.cmake
+++ b/CMake/FindShark.cmake
@@ -115,6 +115,10 @@ if(SHARK_USE_OPENMP_matched)
   set(SHARK_USE_OPENMP TRUE CACHE BOOL "shark is built with OpenMP" FORCE)
 endif()
 
+#This is quick fix/hack/commit that will get back all failing tests on
+# The good fix must to fix all those failing tests. They are crashing
+# due to openmp issues which only popup with this fix
+if(NOT WIN32)
 if(SHARK_USE_OPENMP)
   message(STATUS "Shark is built with OpenMP: SHARK_USE_OPENMP = TRUE")
   find_package(OpenMP REQUIRED QUIET)
@@ -129,6 +133,8 @@ if(SHARK_USE_OPENMP)
 else()
   message(STATUS "Shark is built without OpenMP: SHARK_USE_OPENMP = FALSE")
 endif()
+endif(NOT WIN32)
+
 INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Shark
   REQUIRED_VARS SHARK_LIBRARY SHARK_INCLUDE_DIR
diff --git a/CMake/OTBSetStandardCompilerFlags.cmake b/CMake/OTBSetStandardCompilerFlags.cmake
index 1d6d5fe51868db0778c318e405ccfca3c8a9ff13..f8549625df6b882bf1d666a037505a9f29677619 100644
--- a/CMake/OTBSetStandardCompilerFlags.cmake
+++ b/CMake/OTBSetStandardCompilerFlags.cmake
@@ -209,6 +209,9 @@ macro(check_compiler_platform_flags)
         set(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-auto-import")
       endif()
     else()
+      if(MSVC)
+        set(OTB_REQUIRED_LINK_FLAGS "${OTB_REQUIRED_LINK_FLAGS} /MANIFEST:NO")
+      endif()
       # if CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS is on, then
       # BUILD_SHARED_LIBS works as it would on other systems
       if(NOT CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS)
@@ -349,4 +352,4 @@ macro(set_linker_stack_size_flag exe_target requested_stack_size)
   elseif(MINGW)
     set_target_properties(${exe_target} PROPERTIES LINK_FLAGS "-Wl,--stack,${requested_stack_size}")
   endif()
-endmacro()
\ No newline at end of file
+endmacro()
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2380ec3d2599cda6ae1aa49294f947761987e8f1..19a6202b9f3e5a5455dc4babf186f9b1b6197fc2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -99,7 +99,7 @@ find_path(OTB_DATA_ROOT
   NAMES README-OTB-Data
   HINTS $ENV{OTB_DATA_ROOT} ${OTB_SOURCE_DIR}/../OTB-Data
 )
-mark_as_advanced(OTB_DATA_ROOT)
+#mark_as_advanced(OTB_DATA_ROOT)
 
 if(OTB_DATA_ROOT)
   repository_status(${OTB_DATA_ROOT} OTB_DATA_GIT_STATUS_MESSAGE)
@@ -216,7 +216,7 @@ mark_as_advanced(OTB_USE_DEPRECATED)
 #-----------------------------------------------------------------------------
 # SHOW_ALL_MSG_DEBUG option
 option(OTB_SHOW_ALL_MSG_DEBUG "Show all debug messages (very verbose)" OFF)
-mark_as_advanced(OTB_SHOW_ALL_MSG_DEBUG)
+#mark_as_advanced(OTB_SHOW_ALL_MSG_DEBUG)
 
 include(OTBSetStandardCompilerFlags)
 #---------------------------------------------------------------
diff --git a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
index aee544f9151f4deed65bb6f6bfecba1010b89269..59019e33e2a0a35c32134412512a82bbae52ab54 100755
--- a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
+++ b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
@@ -27,6 +27,12 @@ def ConvertString(s):
     s = s.replace('*','\*')
     return s
 
+def ConvertToLineBlock(s):
+    '''Convert a string into a line bloc (prefix with |) '''
+    s = s.strip()
+    s = s.replace('*','\*')
+    s = "  | " + s.replace('\n','\n  | ')
+    return s
 
 def EncloseString(s):
     if not s.startswith("\"") :
@@ -484,7 +490,7 @@ def ApplicationToRst(appname):
         output += "These additional resources can be useful for further information: " + linesep
         # hlink="<http://www.readthedocs.org/" + ConvertString(app.GetDocSeeAlso()) + ".html>`_ "
         # output += linesep + "`" + ConvertString(app.GetDocSeeAlso()) + " " + hlink + linesep + linesep
-        output += linesep + ConvertString(app.GetDocSeeAlso()) + linesep + linesep
+        output += ConvertToLineBlock(app.GetDocSeeAlso()) + linesep + linesep
 
     return output
 
@@ -507,7 +513,7 @@ def GenerateRstForApplications():
     allApps = None
     try:
         allApps = otbApplication.Registry.GetAvailableApplications( )
-    except e:
+    except:
         print 'error in otbApplication.Registry.GetAvailableApplications()'
         sys.exit(1)
 
diff --git a/Documentation/SoftwareGuide/Latex/Classification.tex b/Documentation/SoftwareGuide/Latex/Classification.tex
index fc255644fb110ecb3103750e46838a703649f86e..90e4b41d462b8f717722d811ffcf49a5cd8bad7f 100644
--- a/Documentation/SoftwareGuide/Latex/Classification.tex
+++ b/Documentation/SoftwareGuide/Latex/Classification.tex
@@ -64,197 +64,116 @@ properties than the image to classify, in order to build a classification model.
 %to other OTB libraries (edit the \code{TARGET\_LINK\_LIBRARIES} to add them),
 %for example OTBLearning, OTBMarkov.
 
-\section{Unsupervised classification}
-
-\subsection{K-Means Classification}
-\label{sec:KMeansClassifier}
-
-\subsubsection{Simple version}
-\ifitkFullVersion
-\input{ScalarImageKmeansClassifier.tex}
-\fi
-\ifitkFullVersion
-\input{ScalarImageKmeansModelEstimator.tex}
-\fi
-
-\subsubsection{General approach}
-\ifitkFullVersion
-\input{KMeansImageClassificationExample.tex}
-\fi
-
-\subsubsection{k-d Tree Based k-Means Clustering}
-\label{sec:KdTreeBasedKMeansClustering}
-\ifitkFullVersion
-\input{KdTreeBasedKMeansClustering.tex}
-\fi
-
-\subsection{Kohonen's Self Organizing Map}
-\label{sec:SOM}
-\input{Kohonen}
-%%%1. Construction SOM
-\subsubsection{Building a color table}
-\label{sec:SOMColorTable}
-\input{SOMExample}
-\subsubsection{SOM Classification}
-\label{sec:SOMClassification}
-\input{SOMClassifierExample}
-
-\subsubsection{Multi-band, streamed classification}
-
-\ifitkFullVersion
-\input{SOMImageClassificationExample.tex}
-\fi
-
-%%%2. Lecture SOM et ensemble de vecteurs autre image pour construire
-%%%ActivationMAP 
-
-%\subsection{Bayesian classification}
-
-\subsection{Bayesian Plug-In Classifier}
-\label{sec:BayesianPluginClassifier}
-
-\ifitkFullVersion 
-\input{BayesianPluginClassifier.tex}
-\fi
-
-
-\subsection{Expectation Maximization Mixture Model Estimation}
-\label{sec:ExpectationMaximizationMixtureModelEstimation}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Machine Learning Framework}
 
-\ifitkFullVersion 
-\input{ExpectationMaximizationMixtureModelEstimator.tex}
-\fi
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\subsection{Statistical Segmentations}
-\label{sec:StatisticalSegmentations}
-
-%\subsection{Markov Random Fields}
+\subsection{Machine learning models}
+\label{sec:MLGenericFramework}
 
-\subsubsection{Stochastic Expectation Maximization}
-\label{sec:SEM}
+The OTB classification is implemented as a generic Machine Learning
+framework, supporting several possible machine learning libraries as backends.
+The base class \doxygen{otb}{MachineLearningModel} defines this framework.
+As of now libSVM (the machine learning library historically integrated in OTB),
+machine learning methods of OpenCV library (\cite{opencv_library}) and also
+Shark machine learning library (\cite{shark_library}) are available. Both
+supervised and unsupervised classifiers are supported in the framework.
 
-The Stochastic Expectation Maximization (SEM) approach is a stochastic 
-version of the EM mixture estimation seen on
-section~\ref{sec:ExpectationMaximizationMixtureModelEstimation}. It has been 
-introduced by \cite{CeDi95} to prevent convergence of the EM approach from
-local minima. It avoids the analytical maximization issued by integrating a
-stochastic sampling procedure in the estimation process. It induces an almost
-sure (a.s.) convergence to the algorithm.
+The current list of classifiers available through the same generic interface within the OTB is:
 
-From the initial two step formulation of the EM mixture estimation, the SEM
-may be decomposed into 3 steps:
-\begin{enumerate}
-\item \textbf{E-step}, calculates the expected membership values for each 
-measurement vector to each classes.
-\item \textbf{S-step}, performs a stochastic sampling of the membership vector
-to each classes, according to the membership values computed in the E-step.
-\item \textbf{M-step}, updates the parameters of the membership probabilities
-(parameters to be defined through the class
-\subdoxygen{itk}{Statistics}{ModelComponentBase} and its inherited classes).
-\end{enumerate}
-The implementation of the SEM has been turned to a contextual SEM in the sense
-where the evaluation of the membership parameters is conditioned to
-membership values of the spatial neighborhood of each pixels.
+\begin{itemize}
+  \item \textbf{LibSVM}: Support Vector Machines classifier based on libSVM.
+  \item \textbf{SVM}: Support Vector Machines classifier based on OpenCV, itself based on libSVM.
+  \item \textbf{Bayes}: Normal Bayes classifier based on OpenCV.
+  \item \textbf{Boost}: Boost classifier based on OpenCV.
+  \item \textbf{DT}: Decision Tree classifier based on OpenCV.
+  \item \textbf{RF}: Random Forests classifier based on the Random Trees in OpenCV.
+  \item \textbf{GBT}: Gradient Boosted Tree classifier based on OpenCV (removed in version 3).
+  \item \textbf{KNN}: K-Nearest Neighbors classifier based on OpenCV.
+  \item \textbf{ANN}: Artificial Neural Network classifier based on OpenCV.
+  \item \textbf{SharkRF} : Random Forests classifier based on Shark.
+  \item \textbf{SharkKM} : KMeans unsupervised classifier based on Shark.
+\end{itemize}
 
-\ifitkFullVersion 
-\input{SEMModelEstimatorExample.tex}
-\fi
+These models have a common interface, with the following major functions:
+\begin{itemize}
+  \item \code{SetInputListSample(InputListSampleType *in)} : set the list of input samples
+  \item \code{SetTargetListSample(TargetListSampleType *in)} : set the list of target samples
+  \item \code{Train()} : train the model based on input samples
+  \item \code{Save(...)} : saves the model to file
+  \item \code{Load(...)} : load a model from file
+  \item \code{Predict(...)} : predict a target value for an input sample
+  \item \code{PredictBatch(...)} : prediction on a list of input samples
+\end{itemize}
 
+The \code{PredictBatch(...)} function can be multi-threaded when
+called either from a multi-threaded filter, or from a single location. In
+the later case, it creates several threads using OpenMP.
+There is a factory mechanism on top of the model class (see
+\doxygen{otb}{MachineLearningModelFactory}). Given an input file,
+the static function \code{CreateMachineLearningModel(...)} is able
+to instanciate a model of the right type.
 
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+For unsupervised models, the target samples \textbf{still have to be set}. They
+won't be used so you can fill a ListSample with zeros.
 
-\subsection{Classification using Markov Random Fields}
-\label{sec:MarkovRandomField}
+%-------------------------------------------------------------------------------
+\subsection{Training a model}
 
-Markov Random Fields are probabilistic models that use the statistical
-dependency between
-pixels in a neighborhood to infeer the value of a give pixel.
+The models are trained from a list of input samples, stored in a
+\subdoxygen{itk}{Statistics}{ListSample}. For supervised classifiers, they
+also need a list of targets associated to each input sample. Whatever the
+source of samples, it has to be converted into a \code{ListSample} before
+being fed into the model.
 
-\subsubsection{ITK framework}
-\label{sec:MarkovRandomFieldITK}
-The
-\subdoxygen{itk}{Statistics}{MRFImageFilter} uses the maximum a posteriori (MAP)
-estimates for modeling the MRF. The object traverses the data set and uses the
-model generated by the Mahalanobis distance classifier to get the the distance
-between each pixel in the data set to a set of known classes, updates the
-distances by evaluating the influence of its neighboring pixels (based on a MRF
-model) and finally, classifies each pixel to the class which has the minimum
-distance to that pixel (taking the neighborhood influence under consideration).
-The energy function minimization is done using the iterated conditional modes
-(ICM) algorithm \cite{Besag1986}.
+Then, model-specific parameters can be set. And finally, the \code{Train()}
+method starts the learning step. Once the model is trained it can be saved
+to file using the function \code{Save()}. The following examples show how
+to do that.
 
-\ifitkFullVersion
-\input{ScalarImageMarkovRandomField1.tex}
-\fi 
+\input{TrainMachineLearningModelFromSamplesExample.tex}
 
-\subsubsection{OTB framework}
-\label{sec:MarkovRandomFieldOTB}
-The ITK approach was considered not to be flexible enough for some
-remote sensing applications. Therefore, we decided to implement our
-own framework.
-\index{Markov}
+\input{TrainMachineLearningModelFromImagesExample.tex}
 
-\begin{figure}[th]
-  \centering
-  \includegraphics[width=0.7\textwidth]{MarkovFramework.eps}
-  \itkcaption[OTB Markov Framework]{OTB Markov Framework.}
-  \label{fig:markovFramework}
-\end{figure}
+%-------------------------------------------------------------------------------
+\subsection{Prediction of a model}
 
-\index{Markov!Classification}
-\ifitkFullVersion
-\input{MarkovClassification1Example.tex}
-\fi 
+For the prediction step, the usual process is to:
+\begin{itemize}
+\item Load an existing model from a file.
+\item Convert the data to predict into a \code{ListSample}.
+\item Run the \code{PredictBatch(...)} function.
+\end{itemize}
 
-\index{Markov!Classification}
-\ifitkFullVersion
-\input{MarkovClassification2Example.tex}
-\fi 
+There is an image filter that perform this step on a whole image, supporting
+streaming and multi-threading: \doxygen{otb}{ImageClassificationFilter}.
 
-\index{Markov!Classification}
 \ifitkFullVersion
-\input{MarkovClassification3Example.tex}
-\fi 
+\input{SupervisedImageClassificationExample.tex}
+\fi
 
-\index{Markov!Regularization}
-\ifitkFullVersion
-\input{MarkovRegularizationExample.tex}
-\fi 
+%-------------------------------------------------------------------------------
+\subsection{Integration in applications}
 
+The classifiers are integrated in several OTB Applications. There is a base
+class that provides an easy access to all the classifiers:
+\subdoxygen{otb}{Wrapper}{LearningApplicationBase}. As each machine learning
+model has a specific set of parameters, the base class
+\code{LearningApplicationBase} knows how to expose each type of classifier with
+its dedicated parameters (a task that is a bit tedious so we want to implement
+it only once). The \code{DoInit()} method creates a choice parameter named
+\code{classifier} which contains the different supported classifiers along
+with their parameters.
 
+The function \code{Train(...)} provide an easy way to train the selected
+classifier, with the corresponding parameters, and save the model to file.
 
+On the other hand, the function \code{Classify(...)} allows to load a model
+from file and apply it on a list of samples.
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Supervised classification}
 
-\subsection{Generic machine learning framework}
-\label{sec:MLGenericFramework}
-
-The OTB supervised classification is implemented as a generic Machine Learning
-framework, supporting several possible machine learning libraries as backends.
-As of now libSVM (the machine learning library historically integrated in OTB),
-machine learning methods of OpenCV library (\cite{opencv_library}) and also
-Shark machine learning library (\cite{shark_library}) are available.
-
-The current list of classifiers available through the same generic interface within the OTB is:
-
-\begin{itemize}
-  \item \textbf{LibSVM}: Support Vector Machines classifier based on libSVM.
-  \item \textbf{SVM}: Support Vector Machines classifier based on OpenCV, itself based on libSVM.
-  \item \textbf{Bayes}: Normal Bayes classifier based on OpenCV.
-  \item \textbf{Boost}: Boost classifier based on OpenCV.
-  \item \textbf{DT}: Decision Tree classifier based on OpenCV.
-  \item \textbf{RF}: Random Forests classifier based on the Random Trees in OpenCV.
-  \item \textbf{GBT}: Gradient Boosted Tree classifier based on OpenCV.
-  \item \textbf{KNN}: K-Nearest Neighbors classifier based on OpenCV.
-  \item \textbf{ANN}: Artificial Neural Network classifier based on OpenCV.
-\end{itemize}
-
-
-\subsection{An example of supervised classification method: Support Vector Machines}
+\subsection{Support Vector Machines}
 \label{sec:SupportVectorMachines}
 
 \subsubsection{SVM general description}
@@ -371,33 +290,35 @@ is the one that we use, the final decision is taken by choosing the
 class which is most often selected by the whole set of SVM.
 
 
+%-------------------------------------------------------------------------------
+\subsection{Shark Random Forests}
 
-\subsection{Learning from samples}
-\label{ssec:LearningFromSamples}
-\input{TrainMachineLearningModelFromSamplesExample.tex}
-
-\subsection{Learning from images}
-\label{ssec:LearningFromImages}
-\input{TrainMachineLearningModelFromImagesExample.tex}
-
-%\subsection{Image Classification}
-%\label{sec:ImageClassification}
-%\input{SVMImageEstimatorClassificationMultiExample}
-
-
-\subsection{Multi-band, streamed classification}
-
-\ifitkFullVersion
-\input{SupervisedImageClassificationExample.tex}
-\fi
-
+The Random Forests algorithm is also available in OTB machine learning
+framework. This model builds a set of decision trees. Each tree may not give
+a reliable prediction, but taking them together, they form a robust classifier.
+The prediction of this model is the mode of the predictions of individual trees.
 
+There are two implementations: one in OpenCV and the other on in
+Shark. The Shark implementation has a noteworthy advantage: the training step
+is parallel. It uses the following parameters:
+\begin{itemize}
+\item The number of trees to train
+\item The number of random attributes to investigate at each node
+\item The maximum node size to decide a split
+\item The ratio of the original training dataset to use as the out of bag sample
+\end{itemize}
 
+Except these specific parameter, its usage is exactly the same as the other
+machine learning models (such as the SVM model).
 
-\subsection{Generic Kernel SVM}
+%-------------------------------------------------------------------------------
+\subsection{Generic Kernel SVM (deprecated)}
 OTB has developed a specific interface for user-defined kernels. However, the 
-following functions use a deprecated OTB interface. A function 
-$k(\cdot,\cdot)$ is considered to be a kernel when:
+following functions use a deprecated OTB interface. The code source for these
+Generic Kernels has been removed from the official repository. It is now
+available as a remote module: \href{https://github.com/jmichel-otb/GKSVM}{GKSVM}.
+
+A function $k(\cdot,\cdot)$ is considered to be a kernel when:
 \begin{align}\label{eqMercer}
         \forall g(\cdot) \in {\cal L}^2(\mathbbm{R}^n) \quad & \text{so 
 that} \quad
@@ -428,7 +349,7 @@ with:
 \end{verbatim}
 This simple example shows that the classical dot product is already 
 implemented
-into \subdoxygen{otb}{GenericKernelFunctorBase}{dot()} as a protected
+into \code{otb::GenericKernelFunctorBase::dot()} as a protected
 function.
 \item The \code{Update()} function which synchronizes local variables and 
 their
@@ -438,16 +359,16 @@ the way to use it.
 
 Some pre-defined generic kernels have already been implemented in OTB:
 \begin{itemize}
-\item \doxygen{otb}{MixturePolyRBFKernelFunctor} which implements a 
+\item \code{otb::MixturePolyRBFKernelFunctor} which implements a 
 linear mixture
 of a polynomial and a RBF kernel;
-\item \doxygen{otb}{NonGaussianRBFKernelFunctor} which implements a non
+\item \code{otb::NonGaussianRBFKernelFunctor} which implements a non
 gaussian RBF kernel;
-\item \doxygen{otb}{SpectralAngleKernelFunctor}, a kernel that integrates
+\item \code{otb::SpectralAngleKernelFunctor}, a kernel that integrates
 the Spectral Angle, instead of the Euclidean distance, into an inverse 
 multiquadric kernel.
 This kernel may be appropriated when using multispectral data.
-\item \doxygen{otb}{ChangeProfileKernelFunctor}, a kernel which is
+\item \code{otb::ChangeProfileKernelFunctor}, a kernel which is
 dedicated to the supervized classification of the multiscale change profile
 presented in section \ref{sec:KullbackLeiblerProfile}.
 \end{itemize}
@@ -465,8 +386,185 @@ presented in section \ref{sec:KullbackLeiblerProfile}.
 \fi
 
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Unsupervised classification}
+
+\subsection{K-Means Classification}
+\label{sec:KMeansClassifier}
+
+\subsubsection{Shark version}
+
+The KMeans algorithm has been implemented in Shark library, and has been
+wrapped in the OTB machine learning framework. It is the first unsupervised
+algorithm in this framework. It can be used in the same way as other machine
+learning models. Remember that even if unsupervised model don't use a label
+information on the samples, the target ListSample still has to be set in
+\code{MachineLearningModel}. A ListSample filled with zeros can be used.
+
+This model uses a hard clustering model with the following parameters:
+\begin{itemize}
+\item The maximum number of iterations
+\item The number of centroids (K)
+\item An option to normalize input samples
+\end{itemize}
+
+As with Shark Random Forests, the training step is parallel.
+
+\subsubsection{Simple version}
+\ifitkFullVersion
+\input{ScalarImageKmeansClassifier.tex}
+\fi
+\ifitkFullVersion
+\input{ScalarImageKmeansModelEstimator.tex}
+\fi
+
+\subsubsection{General approach}
+\ifitkFullVersion
+\input{KMeansImageClassificationExample.tex}
+\fi
+
+\subsubsection{k-d Tree Based k-Means Clustering}
+\label{sec:KdTreeBasedKMeansClustering}
+\ifitkFullVersion
+\input{KdTreeBasedKMeansClustering.tex}
+\fi
+%-------------------------------------------------------------------------------
+\subsection{Kohonen's Self Organizing Map}
+\label{sec:SOM}
+\input{Kohonen}
+%%%1. Construction SOM
+\subsubsection{Building a color table}
+\label{sec:SOMColorTable}
+\input{SOMExample}
+\subsubsection{SOM Classification}
+\label{sec:SOMClassification}
+\input{SOMClassifierExample}
+
+\subsubsection{Multi-band, streamed classification}
+
+\ifitkFullVersion
+\input{SOMImageClassificationExample.tex}
+\fi
+
+%%%2. Lecture SOM et ensemble de vecteurs autre image pour construire
+%%%ActivationMAP 
+
+%\subsection{Bayesian classification}
+%-------------------------------------------------------------------------------
+\subsection{Bayesian Plug-In Classifier}
+\label{sec:BayesianPluginClassifier}
+
+\ifitkFullVersion
+\input{BayesianPluginClassifier.tex}
+\fi
+
+%-------------------------------------------------------------------------------
+\subsection{Expectation Maximization Mixture Model Estimation}
+\label{sec:ExpectationMaximizationMixtureModelEstimation}
+
+\ifitkFullVersion
+\input{ExpectationMaximizationMixtureModelEstimator.tex}
+\fi
+
+
+
 
+%-------------------------------------------------------------------------------
+\subsection{Statistical Segmentations}
+\label{sec:StatisticalSegmentations}
 
+%\subsection{Markov Random Fields}
+
+\subsubsection{Stochastic Expectation Maximization}
+\label{sec:SEM}
+
+The Stochastic Expectation Maximization (SEM) approach is a stochastic 
+version of the EM mixture estimation seen on
+section~\ref{sec:ExpectationMaximizationMixtureModelEstimation}. It has been 
+introduced by \cite{CeDi95} to prevent convergence of the EM approach from
+local minima. It avoids the analytical maximization issued by integrating a
+stochastic sampling procedure in the estimation process. It induces an almost
+sure (a.s.) convergence to the algorithm.
+
+From the initial two step formulation of the EM mixture estimation, the SEM
+may be decomposed into 3 steps:
+\begin{enumerate}
+\item \textbf{E-step}, calculates the expected membership values for each 
+measurement vector to each classes.
+\item \textbf{S-step}, performs a stochastic sampling of the membership vector
+to each classes, according to the membership values computed in the E-step.
+\item \textbf{M-step}, updates the parameters of the membership probabilities
+(parameters to be defined through the class
+\subdoxygen{itk}{Statistics}{ModelComponentBase} and its inherited classes).
+\end{enumerate}
+The implementation of the SEM has been turned to a contextual SEM in the sense
+where the evaluation of the membership parameters is conditioned to
+membership values of the spatial neighborhood of each pixels.
+
+\ifitkFullVersion
+\input{SEMModelEstimatorExample.tex}
+\fi
+
+%-------------------------------------------------------------------------------
+\subsection{Classification using Markov Random Fields}
+\label{sec:MarkovRandomField}
+
+Markov Random Fields are probabilistic models that use the statistical
+dependency between
+pixels in a neighborhood to infeer the value of a give pixel.
+
+\subsubsection{ITK framework}
+\label{sec:MarkovRandomFieldITK}
+The
+\subdoxygen{itk}{Statistics}{MRFImageFilter} uses the maximum a posteriori (MAP)
+estimates for modeling the MRF. The object traverses the data set and uses the
+model generated by the Mahalanobis distance classifier to get the the distance
+between each pixel in the data set to a set of known classes, updates the
+distances by evaluating the influence of its neighboring pixels (based on a MRF
+model) and finally, classifies each pixel to the class which has the minimum
+distance to that pixel (taking the neighborhood influence under consideration).
+The energy function minimization is done using the iterated conditional modes
+(ICM) algorithm \cite{Besag1986}.
+
+\ifitkFullVersion
+\input{ScalarImageMarkovRandomField1.tex}
+\fi
+
+\subsubsection{OTB framework}
+\label{sec:MarkovRandomFieldOTB}
+The ITK approach was considered not to be flexible enough for some
+remote sensing applications. Therefore, we decided to implement our
+own framework.
+\index{Markov}
+
+\begin{figure}[th]
+  \centering
+  \includegraphics[width=0.7\textwidth]{MarkovFramework.eps}
+  \itkcaption[OTB Markov Framework]{OTB Markov Framework.}
+  \label{fig:markovFramework}
+\end{figure}
+
+\index{Markov!Classification}
+\ifitkFullVersion
+\input{MarkovClassification1Example.tex}
+\fi
+
+\index{Markov!Classification}
+\ifitkFullVersion
+\input{MarkovClassification2Example.tex}
+\fi
+
+\index{Markov!Classification}
+\ifitkFullVersion
+\input{MarkovClassification3Example.tex}
+\fi
+
+\index{Markov!Regularization}
+\ifitkFullVersion
+\input{MarkovRegularizationExample.tex}
+\fi
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Fusion of Classification maps}
 
 \subsection{General approach of image fusion}
@@ -476,7 +574,7 @@ fuse several classification maps coming from different classification methods
 classification maps combines them in a more robust and precise one. Two methods are 
 available in the OTB: the majority voting and the Demspter Shafer framework.
 
-
+%-------------------------------------------------------------------------------
 \subsection{Majority voting}
 \subsubsection{General description}
 For each input pixel, the Majority Voting method consists in choosing the more 
@@ -489,7 +587,7 @@ the fused output image.
 \input{MajorityVotingFusionOfClassificationMapsExample.tex}
 \fi
 
-
+%-------------------------------------------------------------------------------
 \subsection{Dempster Shafer}
 
 \subsubsection{General description}
@@ -527,7 +625,7 @@ algorithm is available in the following OTB Wiki page:
 \fi
 
 
-
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Classification map regularization}
 
 %\subsection{Regularization by neighborhood-based majority voting}
diff --git a/Documentation/SoftwareGuide/Latex/ImageRegistration.tex b/Documentation/SoftwareGuide/Latex/ImageRegistration.tex
index 16d28a686326fc9d753fef6b56dcd0beb0d432f8..06c0f909466dab79bd10813ca06a140acfe0266c 100644
--- a/Documentation/SoftwareGuide/Latex/ImageRegistration.tex
+++ b/Documentation/SoftwareGuide/Latex/ImageRegistration.tex
@@ -502,9 +502,9 @@ describe the main characteristics of such transforms.
 
 %% The first case can be solved with a closed form solution when we are dealing
 %% with a Rigid or an Affine Transform~\cite{Horn1987}. This is done in ITK with
-%% the class \doxygen{LandmarkBasedTransformInitializer}. If we are interested in
+%% the class \doxygen{itk}{LandmarkBasedTransformInitializer}. If we are interested in
 %% a deformable Transformation then the problem can be solved with the
-%% \doxygen{KernelTransform} family of classes, which includes Thin Plate Splines
+%% \doxygen{itk}{KernelTransform} family of classes, which includes Thin Plate Splines
 %% among others~\cite{Rohr2001}. In both circumstances, the availability o f
 %% correspondences between the points make possible to apply a straight forward
 %% solution to the problem.
diff --git a/Documentation/SoftwareGuide/Latex/Optimizers.tex b/Documentation/SoftwareGuide/Latex/Optimizers.tex
index bc59c6845db754d067be0d22ba2a1e8dd2cee31b..eb865a56fb50a7f50b2f72c37e08191e1d007355 100644
--- a/Documentation/SoftwareGuide/Latex/Optimizers.tex
+++ b/Documentation/SoftwareGuide/Latex/Optimizers.tex
@@ -118,7 +118,7 @@ optimizer in \code{netlib}. Details on this optimizer can be found
 in~\cite{Byrd1995,Zhu1997} (\doxygen{itk}{LBFGSBOptimizer}).
 
 \item \textbf{One Plus One Evolutionary}: Strategy that simulates the
-biological evolution of a set of samples in the search space (\doxygen{itk}{OnePlusOneEvolutionaryOptimizer.}). Details on this optimizer can be
+biological evolution of a set of samples in the search space (\doxygen{itk}{OnePlusOneEvolutionaryOptimizer}). Details on this optimizer can be
 found in~\cite{Styner2000}.
 
 \item \textbf{Regular Step Gradient Descent}: Advances parameters in the
diff --git a/Documentation/SoftwareGuide/Latex/WriteAnApplication.tex b/Documentation/SoftwareGuide/Latex/WriteAnApplication.tex
index f019cba0774c7460ea73be2d85277e7296443fc0..b4029d13e7dce361ba0a43fb1e5c4306fd3d3cf0 100644
--- a/Documentation/SoftwareGuide/Latex/WriteAnApplication.tex
+++ b/Documentation/SoftwareGuide/Latex/WriteAnApplication.tex
@@ -30,7 +30,7 @@ divisions (see section \ref{sec:appParam}).
 
 \section{Architecture of the class}
 \label{sec:appArchitecture}
-Every application derive from the class \doxygen{otb}{Wrapper::Application}. An 
+Every application derive from the class \subdoxygen{otb}{Wrapper}{Application}. An 
 application can't be templated. It must contain the standard class typedefs and
 a call to the \code{OTB\_APPLICATION\_EXPORT} macro.
 
@@ -53,8 +53,8 @@ contain the following actions:
   \item Fill the documentation and give an example
   \item Declare all the parameters
   \item Define the documentation link:
-    \item for contrib application use SetDocLink("\textit{docLink}") function defined in \doxygen{otb}{Wrapper::Application}
-    \item for official application use SetOfficialDocLink() function defined in \doxygen{otb}{Wrapper::Application}
+    \item for contrib application use SetDocLink("\textit{docLink}") function defined in \subdoxygen{otb}{Wrapper}{Application}
+    \item for official application use SetOfficialDocLink() function defined in \subdoxygen{otb}{Wrapper}{Application}
 \end{itemize}
 
 
@@ -97,7 +97,7 @@ created and updated.
 \subsection{Parameters selection}
 \label{sec:appParam}
 In the new application framework, every input, output or parameter derive from 
-\doxygen{otb}{Wrapper::Parameter}. The application engine supplies the following 
+\subdoxygen{otb}{Wrapper}{Parameter}. The application engine supplies the following 
 types of parameters:
 \begin{itemize}
   \item \code{ParameterType\_Empty} : parameter without value (can be used to represent 
@@ -136,7 +136,7 @@ can be used to set a parameter optional or test if the user has modified the par
 are created in the \code{DoInit()} method, then the framework will set their value (either by parsing the 
 command line or reading the graphical user interface). The \code{DoExecute()} method is called when all 
 mandatory parameters have been given a value, which can be obtained with "Get" methods defined in 
-\doxygen{otb}{Wrapper::Application}. Parameters are set mandatory (or not) using \code{MandatoryOn(key)} method (\code{MandatoryOff(key)}).
+\subdoxygen{otb}{Wrapper}{Application}. Parameters are set mandatory (or not) using \code{MandatoryOn(key)} method (\code{MandatoryOff(key)}).
 
 Some functions are specific to numeric parameters, such as \code{SetMinimumParameterIntValue(key,value)}
 or \code{SetMaximumParameterFloatValue(key,value)}. By default, numeric parameters are treated as inputs.
@@ -158,7 +158,7 @@ that you want to chain in order to build a third application C. Rather than writ
 the code of A and B, you would like to re-use applications A and B. This plain example will be
 re-used in this section for explanations.
 
-A dedicated class \doxygen{otb}{Wrapper::CompositeApplication} has been added to create such applications.
+A dedicated class \subdoxygen{otb}{Wrapper}{CompositeApplication} has been added to create such applications.
 If you derive this class to implement application C, you will be able to create a composite application.
 
 \subsection{Creating internal applications}
diff --git a/Documentation/SoftwareGuide/SoftwareGuideConfiguration.tex.in b/Documentation/SoftwareGuide/SoftwareGuideConfiguration.tex.in
index 02868b264c65bf63aac1c3cb7c802772b1e72efc..22bd0cb1bad7d83d5e714fd11fbb266630a4a895 100644
--- a/Documentation/SoftwareGuide/SoftwareGuideConfiguration.tex.in
+++ b/Documentation/SoftwareGuide/SoftwareGuideConfiguration.tex.in
@@ -11,12 +11,17 @@
 }{
 \href{http://www.orfeo-toolbox.org/doxygen/class#1_1_1#2.html}{\code{#1::#2}}
 }{
-\href{http://www.itk.org/Doxygen46/html/class#1_1_1#2.html}{\code{#1::#2}}
+\href{http://www.itk.org/Doxygen/html/class#1_1_1#2.html}{\code{#1::#2}}
 }}
 
 % Define command to make reference to on-line Doxygen documentation
 \newcommand{\subdoxygen}[3]{
-\href{http://www.orfeo-toolbox.org/doxygen/class#1_1_1#2_1_1#3.html}{\code{#1::#2::#3}}}  
+\ifthenelse{ \equal{#1}{otb}
+}{
+\href{http://www.orfeo-toolbox.org/doxygen/class#1_1_1#2_1_1#3.html}{\code{#1::#2::#3}}
+}{
+\href{http://www.itk.org/Doxygen/html/class#1_1_1#2_1_1#3.html}{\code{#1::#2::#3}}
+}}
 
 % Define command for the standard comment introducing classes with similar functionalities
 \newcommand{\relatedClasses}{
diff --git a/Examples/Application/ApplicationExample.cxx b/Examples/Application/ApplicationExample.cxx
index 698c7d612219f770edd0e0fb7b533eef1c7a1260..007a204635ef56046dc0aa9fc4e11b2b43100619 100644
--- a/Examples/Application/ApplicationExample.cxx
+++ b/Examples/Application/ApplicationExample.cxx
@@ -28,7 +28,7 @@
 
 //  Software Guide : BeginLatex
 // This example illustrates the creation of an application.
-// A new application is a class, which derives from \doxygen{otb}{Wrapper::Application} class.
+// A new application is a class, which derives from \subdoxygen{otb}{Wrapper}{Application} class.
 // We start by including the needed header files.
 //
 //  Software Guide : EndLatex
@@ -147,7 +147,7 @@ private:
     // Software Guide : BeginLatex
     // Application parameters declaration is done using \code{AddParameter()} method.
     // \code{AddParameter()} requires Parameter type, its name and description.
-    // \doxygen{otb}{Wrapper::Application} class contains methods to set parameters characteristics.
+    // \subdoxygen{otb}{Wrapper}{Application} class contains methods to set parameters characteristics.
     // Software Guide : EndLatex
 
     //  Software Guide : BeginCodeSnippet
diff --git a/Examples/Classification/BayesianPluginClassifier.cxx b/Examples/Classification/BayesianPluginClassifier.cxx
index 792b68265f945c49827459db3e2919a47022c286..fa5d0c764af7bb3930a5d89dc867b57f61af03db 100644
--- a/Examples/Classification/BayesianPluginClassifier.cxx
+++ b/Examples/Classification/BayesianPluginClassifier.cxx
@@ -32,7 +32,7 @@
 // all the components of the classifier system and the data flow. This system
 // differs with the previous k-means clustering algorithms in several
 // ways. The biggest difference is that this classifier uses the
-// \subdoxygen{itk}{Statistics}{itkGaussianMembershipFunction} as membership functions
+// \subdoxygen{itk}{Statistics}{GaussianMembershipFunction} as membership functions
 // instead of the \subdoxygen{itk}{Statistics}{EuclideanDistanceMetric}. Since the
 // membership function is different, the membership function requires a
 // different set of parameters, mean vectors and covariance matrices. We
diff --git a/Examples/Classification/ExpectationMaximizationMixtureModelEstimator.cxx b/Examples/Classification/ExpectationMaximizationMixtureModelEstimator.cxx
index 3d16c589b8d645d41525513399908c83d4262e7b..63067f669fb86903b1f0f6cd3555b3681b24de9d 100644
--- a/Examples/Classification/ExpectationMaximizationMixtureModelEstimator.cxx
+++ b/Examples/Classification/ExpectationMaximizationMixtureModelEstimator.cxx
@@ -74,7 +74,7 @@
 // class assumes that such type of components.
 //
 // In the following example we use the \subdoxygen{itk}{Statistics}{ListSample} as
-// the sample (test and training). The \subdoxygen{itk}{Vector} is our measurement
+// the sample (test and training). The \doxygen{itk}{Vector} is our measurement
 // vector class. To store measurement vectors into two separate sample
 // container, we use the \subdoxygen{itk}{Statistics}{Subsample} objects.
 //
diff --git a/Examples/DataRepresentation/Image/ImageListExample.cxx b/Examples/DataRepresentation/Image/ImageListExample.cxx
index 81f21bc1f8ca4775d553b0085150d7cb6c682cff..d2f09626c149085c3bb2a39b845ec616d94f5daf 100644
--- a/Examples/DataRepresentation/Image/ImageListExample.cxx
+++ b/Examples/DataRepresentation/Image/ImageListExample.cxx
@@ -21,7 +21,7 @@
 
 //  Software Guide : BeginLatex
 //
-//  This example illustrates the use of the \subdoxygen{otb}{ImageList}
+//  This example illustrates the use of the \doxygen{otb}{ImageList}
 //  class. This class provides the functionnalities needed in order to
 //  integrate image lists as data objects into the OTB
 //  pipeline. Indeed, if a \code{std::list< ImageType >} was used, the
@@ -29,10 +29,10 @@
 //  effects.
 //
 //  In this example, we will only present the basic operations which
-//  can be applied on an \subdoxygen{otb}{ImageList} object.
+//  can be applied on an \doxygen{otb}{ImageList} object.
 //
 //  The first thing required to read an image from a file is to include
-//  the header file of the \subdoxygen{otb}{ImageFileReader} class.
+//  the header file of the \doxygen{otb}{ImageFileReader} class.
 //
 //  Software Guide : EndLatex
 
@@ -70,7 +70,7 @@ int main(int itkNotUsed(argc), char * argv[])
 // Software Guide : BeginLatex
 //
 // We can now define the type for the image list. The
-// \subdoxygen{otb}{ImageList} class is templated over the type of image
+// \doxygen{otb}{ImageList} class is templated over the type of image
 // contained in it. This means that all images in a list must have the
 // same type.
 //
@@ -146,7 +146,7 @@ int main(int itkNotUsed(argc), char * argv[])
 //
 // Also, iterator classes are defined in order to have an efficient
 // mean of moving through the list. Finally, the
-// \subdoxygen{otb}{ImageListToImageListFilter} is provided in order
+// \doxygen{otb}{ImageListToImageListFilter} is provided in order
 // to implement filter which operate on image lists and produce image lists.
 // Software Guide : EndLatex
 
diff --git a/Examples/DisparityMap/FineRegistrationImageFilterExample.cxx b/Examples/DisparityMap/FineRegistrationImageFilterExample.cxx
index 7e730b27f26eca50f284d3ece4ff3ddd516a926d..97fb63f85d0dc0fc792d737ffe35ef6c1c7a6d8e 100644
--- a/Examples/DisparityMap/FineRegistrationImageFilterExample.cxx
+++ b/Examples/DisparityMap/FineRegistrationImageFilterExample.cxx
@@ -125,7 +125,7 @@ int main(int argc, char** argv)
 
   // Software Guide : BeginLatex
   //
-  // Now, we declare and instantiate the \doxygen{otb}{FineCorrelationImageFilter} which is going to perform the registration:
+  // Now, we declare and instantiate the \doxygen{otb}{FineRegistrationImageFilter} which is going to perform the registration:
   //
   // Software Guide : EndLatex
 
@@ -188,7 +188,7 @@ int main(int argc, char** argv)
 
   // Software Guide : BeginLatex
   //
-  // The default matching metric used by the \doxygen{FineRegistrationImageFilter} is standard correlation.
+  // The default matching metric used by the \doxygen{otb}{FineRegistrationImageFilter} is standard correlation.
   // However, we may also use any other image-to-image metric provided by ITK. For instance, here is how we
   // would use the \doxygen{itk}{MutualInformationImageToImageMetric} (do not forget to include the proper header).
   //
diff --git a/Examples/FeatureExtraction/ExtractSegmentsExample.cxx b/Examples/FeatureExtraction/ExtractSegmentsExample.cxx
index 7fc0b46b094373b680ec6ad2f236e49b105a5b33..4e4a3706a247275de236e6a6ff5b5959094af837 100644
--- a/Examples/FeatureExtraction/ExtractSegmentsExample.cxx
+++ b/Examples/FeatureExtraction/ExtractSegmentsExample.cxx
@@ -99,7 +99,7 @@ int main(int argc, char * argv[])
 
   //  Software Guide : BeginLatex
   //
-  //  An \doxygen{ImageFileReader} class is also instantiated in order to read
+  //  An \doxygen{otb}{ImageFileReader} class is also instantiated in order to read
   //  image data from a file.
   //
   //  Software Guide : EndLatex
@@ -110,7 +110,7 @@ int main(int argc, char * argv[])
 
   //  Software Guide : BeginLatex
   //
-  // An \doxygen{ImageFileWriter} is instantiated in order to write the
+  // An \doxygen{otb}{ImageFileWriter} is instantiated in order to write the
   // output image to a file.
   //
   //  Software Guide : EndLatex
diff --git a/Examples/FeatureExtraction/LineSegmentDetectorExample.cxx b/Examples/FeatureExtraction/LineSegmentDetectorExample.cxx
index c1277a2c47ad86cba315c0b512ffee30ac989528..0cfac191b53c3e14cba9ca8df3dfe8d0dbe1d781 100644
--- a/Examples/FeatureExtraction/LineSegmentDetectorExample.cxx
+++ b/Examples/FeatureExtraction/LineSegmentDetectorExample.cxx
@@ -156,7 +156,7 @@ int main(int argc, char * argv[])
   //
   // Before calling the \code{Update()} method of the writer in order to
   // trigger the pipeline execution, we call the
-  // \doxygen{GenerateOutputInformation()} of the reader, so the LSD
+  // \code{GenerateOutputInformation()} of the reader, so the LSD
   // filter gets the information about image size and spacing.
   //
   // Software Guide : EndLatex
diff --git a/Examples/FeatureExtraction/RightAngleDetectionExample.cxx b/Examples/FeatureExtraction/RightAngleDetectionExample.cxx
index 5d7fa92df2b736d780ef931c91bbdc0cc06d468d..04eaaf308ad0151cca3ff9ea8185cd2976fc0689 100644
--- a/Examples/FeatureExtraction/RightAngleDetectionExample.cxx
+++ b/Examples/FeatureExtraction/RightAngleDetectionExample.cxx
@@ -194,7 +194,7 @@ int main(int argc, char * argv[])
   //
   // Before calling the \code{Update()} method of the writer in order to
   // trigger the pipeline execution, we call the
-  // \doxygen{GenerateOutputInformation()} of the reader, so the
+  // \code{GenerateOutputInformation()} of the reader, so the
   // filter gets the information about image size and spacing.
   //
   // Software Guide : EndLatex
diff --git a/Examples/FeatureExtraction/TouziEdgeDetectorExample.cxx b/Examples/FeatureExtraction/TouziEdgeDetectorExample.cxx
index df67b6b9b6521668822c85527c028d17240d9ecb..a68817f104594edb28fe69144dcb8d26d05b84dc 100644
--- a/Examples/FeatureExtraction/TouziEdgeDetectorExample.cxx
+++ b/Examples/FeatureExtraction/TouziEdgeDetectorExample.cxx
@@ -105,7 +105,7 @@ int main(int argc, char * argv[])
 
   //  Software Guide : BeginLatex
   //
-  //  An \doxygen{ImageFileReader} class is also instantiated in order to read
+  //  An \doxygen{otb}{ImageFileReader} class is also instantiated in order to read
   //  image data from a file.
   //
   //  Software Guide : EndLatex
@@ -116,7 +116,7 @@ int main(int argc, char * argv[])
 
   //  Software Guide : BeginLatex
   //
-  // An \doxygen{ImageFileWriter} is instantiated in order to write the
+  // An \doxygen{otb}{ImageFileWriter} is instantiated in order to write the
   // output image to a file.
   //
   //  Software Guide : EndLatex
diff --git a/Examples/Iterators/ImageSliceIteratorWithIndex.cxx b/Examples/Iterators/ImageSliceIteratorWithIndex.cxx
index 1e4d4bfce4fb14b7ebb8f4e9a113ba3af8ce8258..1c7976d96f8a0f22e648a9a955d7866a66ba016c 100644
--- a/Examples/Iterators/ImageSliceIteratorWithIndex.cxx
+++ b/Examples/Iterators/ImageSliceIteratorWithIndex.cxx
@@ -24,8 +24,8 @@
 //
 // \index{Iterators!and image slices}
 //
-// The \doxygen{ImageSliceIteratorWithIndex} class is an extension of
-// \doxygen{ImageLinearIteratorWithIndex} from iteration along lines to
+// The \doxygen{itk}{ImageSliceIteratorWithIndex} class is an extension of
+// \doxygen{itk}{ImageLinearIteratorWithIndex} from iteration along lines to
 // iteration along both lines \emph{and planes} in an image.
 // A \emph{slice} is a 2D
 // plane spanned by two vectors pointing along orthogonal coordinate axes.  The
diff --git a/Examples/Iterators/NeighborhoodIterators5.cxx b/Examples/Iterators/NeighborhoodIterators5.cxx
index f3792036a1c160923ec3ae8823a6606e4d70792b..b182309bf8f2845a57cdcb6ec2fe8429823c8333 100644
--- a/Examples/Iterators/NeighborhoodIterators5.cxx
+++ b/Examples/Iterators/NeighborhoodIterators5.cxx
@@ -46,9 +46,9 @@
 // 2, stride = 3, end = 8)}, that represents the neighborhood offsets $(1,
 // -1)$, $(1, 0)$, $(1, 1)$ (see Figure~\ref{fig:NeighborhoodIteratorFig2}). If we
 // pass this slice as an extra argument to the
-// \doxygen{NeighborhoodInnerProduct} function, then the inner product is taken
+// \doxygen{itk}{NeighborhoodInnerProduct} function, then the inner product is taken
 // only along that slice.  This ``sliced'' inner product with a 1D
-// \doxygen{DerivativeOperator} gives the desired derivative.
+// \doxygen{itk}{DerivativeOperator} gives the desired derivative.
 //
 // The previous separable Gaussian filtering example can be rewritten using
 // slices and slice-based inner products.  In general, slice-based processing
@@ -57,7 +57,7 @@
 // Section~\ref{sec:NeighborhoodExample4} becomes impractical or inefficient.
 // Good examples of slice-based neighborhood processing can be found in any of
 // the ND anisotropic diffusion function objects, such as
-// \doxygen{CurvatureNDAnisotropicDiffusionFunction}.
+// \doxygen{itk}{CurvatureNDAnisotropicDiffusionFunction}.
 //
 // Software Guide : EndLatex
 
diff --git a/Examples/Learning/SEMModelEstimatorExample.cxx b/Examples/Learning/SEMModelEstimatorExample.cxx
index e13d2e659d88bf498447e242405fcb13d13af18e..65ec4960477aef75eff45c0653e45cc550a4d71f 100644
--- a/Examples/Learning/SEMModelEstimatorExample.cxx
+++ b/Examples/Learning/SEMModelEstimatorExample.cxx
@@ -32,11 +32,11 @@
 // \doxygen{otb}{SEMClassifier}. This class performs a stochastic version
 // of the EM algorithm, but instead of inheriting from
 // \doxygen{itk}{ExpectationMaximizationMixtureModelEstimator}, we chose to
-// inherit from \subdoxygen{itk}{Statistics}{ListSample< TSample >},
+// inherit from \subdoxygen{itk}{Statistics}{ListSample},
 // in the same way as \doxygen{otb}{SVMClassifier}.
 //
 // The program begins with \doxygen{otb}{VectorImage} and outputs
-// \doxygen{itb}{Image}. Then appropriate header files have to be included:
+// \doxygen{otb}{Image}. Then appropriate header files have to be included:
 //
 // Software Guide : EndLatex
 
@@ -144,7 +144,7 @@ int main(int argc, char * argv[])
 // When an initial segmentation is available, the classifier may use it
 // as image (of type \code{OutputImageType}) or as a
 // \doxygen{itk}{SampleClassifier} result (of type
-// \subdoxygen{itk}{Statistics}{MembershipSample< SampleType >}).
+// \subdoxygen{itk}{Statistics}{MembershipSample}).
 //  Software Guide : EndLatex
 
 //  Software Guide : BeginCodeSnippet
@@ -205,7 +205,7 @@ int main(int argc, char * argv[])
 //  Software Guide : BeginLatex
 //
 //  The segmentation may outputs a result of type
-// \subdoxygen{itk}{Statistics}{MembershipSample< SampleType >} as it is the
+// \subdoxygen{itk}{Statistics}{MembershipSample} as it is the
 // case for the \doxygen{otb}{SVMClassifier}. But when using
 // \code{GetOutputImage} the output is directly an Image.
 //
diff --git a/Examples/Learning/SOMClassifierExample.cxx b/Examples/Learning/SOMClassifierExample.cxx
index d1681051e359e773286fc129d3a833cd991d4c94..cbd6f2d31e3643f431dd1c565165d6f3d77ee3a0 100644
--- a/Examples/Learning/SOMClassifierExample.cxx
+++ b/Examples/Learning/SOMClassifierExample.cxx
@@ -77,7 +77,7 @@ int main(int argc, char* argv[])
 // As for the SOM learning step, we must define the types for the
 // \code{otb::SOMMap}, and therefore, also for the distance to be
 // used. We will also define the type for the SOM reader, which is
-// actually an \subdoxygen{otb}{ImageFileReader} which the appropriate
+// actually an \doxygen{otb}{ImageFileReader} which the appropriate
 // image type.
 //
 //  Software Guide : EndLatex
@@ -94,7 +94,7 @@ int main(int argc, char* argv[])
 //  Software Guide : BeginLatex
 //
 //  The classification will be performed by the
-//  \subdoxygen{otb}{SOMClassifier}, which, as most of the
+//  \doxygen{otb}{SOMClassifier}, which, as most of the
 //  classifiers, works on
 //  \subdoxygen{itk}{Statistics}{ListSample}s. In order to be able
 //  to perform an image classification, we will need to use the
@@ -218,7 +218,7 @@ int main(int argc, char* argv[])
 //
 //  Software Guide : BeginLatex
 //
-//  We also declare an \subdoxygen{itk}{ImageRegionIterator} in order
+//  We also declare an \doxygen{itk}{ImageRegionIterator} in order
 //  to fill the output image with the class labels.
 //
 //  Software Guide : EndLatex
diff --git a/Examples/Learning/SOMExample.cxx b/Examples/Learning/SOMExample.cxx
index 9f9d164e942f2c0a5af26d40dd295e75a84cbcf7..814214c4935de5c9701917f9a993422cdf793fc2 100644
--- a/Examples/Learning/SOMExample.cxx
+++ b/Examples/Learning/SOMExample.cxx
@@ -118,7 +118,7 @@ int main(int itkNotUsed(argc), char* argv[])
 //
 //  Software Guide : BeginLatex
 //
-// We can now define the type for the map. The \subdoxygen{otb}{SOMMap}
+// We can now define the type for the map. The \doxygen{otb}{SOMMap}
 // class is templated over the neuron type -- \code{PixelType} here
 // --, the distance type and the number of dimensions. Note that the
 // number of dimensions of the map could be different from the one of
diff --git a/Examples/Segmentation/VectorConfidenceConnected.cxx b/Examples/Segmentation/VectorConfidenceConnected.cxx
index 357577cb68e2c0577b09acd4ae9c97f92489e397..3e4fa502838288f5065efb5378c47fcb0ac46ed7 100644
--- a/Examples/Segmentation/VectorConfidenceConnected.cxx
+++ b/Examples/Segmentation/VectorConfidenceConnected.cxx
@@ -42,12 +42,13 @@
 //  This example illustrates the use of the confidence connected concept
 //  applied to images with vector pixel types. The confidence connected
 //  algorithm is implemented for vector images in the class
-//  \doxygen{VectorConfidenceConnected}. The basic difference between the
+//  \doxygen{itk}{VectorConfidenceConnectedImageFilter}. The basic difference
+//  between the
 //  scalar and vector version is that the vector version uses the covariance
 //  matrix instead of a variance, and a vector mean instead of a scalar mean.
 //  The membership of a vector pixel value to the region is measured using the
 //  Mahalanobis distance as implemented in the class
-//  \subdoxygen{Statistics}{MahalanobisDistanceThresholdImageFunction}.
+//  \subdoxygen{itk}{Statistics}{MahalanobisDistanceThresholdImageFunction}.
 //
 //  Software Guide : EndLatex
 
@@ -108,7 +109,7 @@ int main( int argc, char *argv[] )
   //  Software Guide : BeginLatex
   //
   //  We now declare the type of the region growing filter. In this case it
-  //  is the \doxygen{VectorConfidenceConnectedImageFilter}.
+  //  is the \doxygen{itk}{VectorConfidenceConnectedImageFilter}.
   //
   //  Software Guide : EndLatex
 
@@ -211,7 +212,7 @@ int main( int argc, char *argv[] )
   //  anatomical structure to be segmented. A small neighborhood around the
   //  seed point will be used to compute the initial mean and standard
   //  deviation for the inclusion criterion. The seed is passed in the form
-  //  of a \doxygen{Index} to the \code{SetSeed()} method.
+  //  of a \doxygen{itk}{Index} to the \code{SetSeed()} method.
   //
   //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetSeed()}
   //  \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetInitialNeighborhoodRadius()}
diff --git a/Examples/Simulation/LAIAndPROSAILToSensorResponse.cxx b/Examples/Simulation/LAIAndPROSAILToSensorResponse.cxx
index fa7886b540351b0d095f0ae64970943b4e09c799..e61faf0608761bb35f9e6fa8a105b6232b035c9d 100644
--- a/Examples/Simulation/LAIAndPROSAILToSensorResponse.cxx
+++ b/Examples/Simulation/LAIAndPROSAILToSensorResponse.cxx
@@ -422,7 +422,7 @@ protected:
 // Software Guide : BeginLatex
 //
 // \code{TernaryFunctorImageFilterWithNBands} class is defined here.
-// This class inherits form \doxygen{itk::TernaryFunctorImageFilter} with additional nuber of band parameters.
+// This class inherits form \doxygen{itk}{TernaryFunctorImageFilter} with additional nuber of band parameters.
 // It's implementation is done to process Label, LAI, and mask image with Simulation functor.
 // Software Guide : EndLatex
 
@@ -595,7 +595,7 @@ int main(int argc, char *argv[])
   // Software Guide : BeginLatex
   //
   // Acquisition parameters are loaded using text file. A detailed definition of acquisition parameters can
-  // be found in class \doxygen{SailModel}.
+  // be found in class \doxygen{otb}{SailModel}.
   //
   // Software Guide : EndLatex
 
diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h b/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h
index 12c94cd02c047bc2034a67cefd64c2b70fbd8227..7fdc308413d2a912eba471b90fe74576e1ef5310 100644
--- a/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h
+++ b/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h
@@ -44,6 +44,8 @@ class OGRDataSource;
 class OGRSFDriver;
 #endif
 
+class OGRFeature;
+
 #include "OTBGdalAdaptersExport.h"
 
 namespace otb
@@ -212,6 +214,15 @@ OTBGdalAdapters_EXPORT bool IsOFTInteger64(OGRFieldType type);
   OTBGdalAdapters_EXPORT
   std::vector<std::string> GetAvailableDriversAsStringVector();
 
+  /**
+   * Returns true if the field 'index' is set and not-null in the given feature
+   *
+   * Before gdal 2.2, it calls OGRFeature::IsFieldSet().
+   * After gdal 2.2, it calls OGRFeature::IsFieldSetAndNotNull()
+   */
+   OTBGdalAdapters_EXPORT
+   bool IsFieldSetAndNotNull(OGRFeature *feat, int index);
+
 }
 }
 } // end namespace otb
diff --git a/Modules/Adapters/GdalAdapters/src/CMakeLists.txt b/Modules/Adapters/GdalAdapters/src/CMakeLists.txt
index 95a01673319b92719b860e2d4da2ed755d7b1ca1..4ba50ff1e286f05842703510931bffec1d5f0f21 100644
--- a/Modules/Adapters/GdalAdapters/src/CMakeLists.txt
+++ b/Modules/Adapters/GdalAdapters/src/CMakeLists.txt
@@ -28,14 +28,9 @@ set(OTBGdalAdapters_SRC
   otbOGRDriversInit.cxx
   otbGeometriesToGeometriesFilter.cxx
   otbOGRDataSourceWrapper.cxx
+  otbOGRVersionProxy.cxx
   )
 
-if(OTB_USE_GDAL_20)
-  set(OTBGdalAdapters_SRC ${OTBGdalAdapters_SRC} otbOGRVersionProxy2x.cxx)
-else(Otb_use_gdal_20)
-  set(OTBGdalAdapters_SRC ${OTBGdalAdapters_SRC} otbOGRVersionProxy1x.cxx)
-endif(OTB_USE_GDAL_20)
-
 add_library(OTBGdalAdapters ${OTBGdalAdapters_SRC})
 target_link_libraries(OTBGdalAdapters 
   ${OTBBoost_LIBRARIES}
diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRFieldWrapper.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRFieldWrapper.cxx
index 3b54c06c60d1041f5837f1c46a7b22bb4387713f..49f95f053546c6f59190ef88ae6d28cee0f19110 100644
--- a/Modules/Adapters/GdalAdapters/src/otbOGRFieldWrapper.cxx
+++ b/Modules/Adapters/GdalAdapters/src/otbOGRFieldWrapper.cxx
@@ -37,6 +37,7 @@
 #endif
 #include "otbOGRFeatureWrapper.h"
 #include "otbJoinContainer.h"
+#include "otbOGRVersionProxy.h"
 #include <boost/array.hpp>
 /*===========================================================================*/
 /*===========================[ Static Assertions ]===========================*/
@@ -166,7 +167,7 @@ std::ostream & otb::ogr::Field::UncheckedPrintSelf(
 
 bool otb::ogr::Field::UncheckedHasBeenSet() const
 {
-  return m_Feature->IsFieldSet(m_index);
+  return otb::ogr::version_proxy::IsFieldSetAndNotNull(m_Feature.get(), m_index);
 }
 
 void otb::ogr::Field::UncheckedUnset() const
diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy2x.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy.cxx
similarity index 62%
rename from Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy2x.cxx
rename to Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy.cxx
index 2ca46ae46a00029da877f3b16ef6e03739fea4fc..22b7a612ca3f7f557eeed7abe2da3c2e1d047fe9 100644
--- a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy2x.cxx
+++ b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy.cxx
@@ -20,15 +20,26 @@
 
 #include "otbOGRVersionProxy.h"
 
+#include "itkMacro.h"
+
 #if defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wshadow"
+#if GDAL_VERSION_NUM<2000000
+#include "ogrsf_frmts.h"
+#else
 #include "gdal_priv.h"
+#endif
+#include "ogr_feature.h"
 #pragma GCC diagnostic pop
 #else
+#if GDAL_VERSION_NUM<2000000
+#include "ogrsf_frmts.h"
+#else
 #include "gdal_priv.h"
 #endif
-
+#include "ogr_feature.h"
+#endif // __GNUC__ || __clang__
 
 namespace otb
 {
@@ -37,24 +48,48 @@ namespace ogr
 namespace version_proxy
 {
 
+/*-------------------------[GDAL v2 API change]-------------------------------*/
 OTBGdalAdapters_EXPORT bool IsOFTInteger64(OGRFieldType type)
 {
+#if GDAL_VERSION_NUM<2000000
+  (void)type;
+  return false;
+#else
   return type == OFTInteger64;
+#endif
 }
 
+
 GDALDatasetType * Open(const char * filename, bool readOnly)
 {
+#if GDAL_VERSION_NUM<2000000
+  return OGRSFDriverRegistrar::Open(filename,!readOnly);
+#else
   return (GDALDatasetType *)GDALOpenEx(filename, (readOnly? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR,NULL,NULL,NULL);
+#endif
 }
 
 void Close(GDALDatasetType * dataset)
 {
+#if GDAL_VERSION_NUM<2000000
+  OGRDataSource::DestroyDataSource(dataset);
+#else
   GDALClose(dataset);
+#endif
 }
 
 GDALDatasetType * Create(GDALDriverType * driver, const char * name)
 {
+#if GDAL_VERSION_NUM<2000000
+  GDALDatasetType * ds = driver->CreateDataSource(name);
+
+  if(ds)
+    ds->SetDriver(driver);
+
+  return ds;
+#else
   return driver->Create(name,0,0,0,GDT_Unknown,NULL);
+#endif
 }
 
 bool Delete(const char * name)
@@ -67,31 +102,50 @@ bool Delete(const char * name)
     poDriver = poDS->GetDriver();
     Close(poDS);
     }
-
+#if GDAL_VERSION_NUM<2000000
+  if(poDriver && poDriver->TestCapability(ODrCDeleteDataSource))
+    {
+    OGRErr ret = poDriver->DeleteDataSource(name);
+    return (ret == OGRERR_NONE);
+    }
+#else
   if(poDriver)
     {
     OGRErr ret = poDriver->Delete(name);
-
     return (ret == OGRERR_NONE);
     }
+#endif
   return false;
 }
 
 GDALDriverType *  GetDriverByName(const char * name)
 {
+#if GDAL_VERSION_NUM<2000000
+  return OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(name);
+#else
   return GetGDALDriverManager()->GetDriverByName(name);
+#endif
 }
 
 std::string GetDatasetClassName()
 {
+#if GDAL_VERSION_NUM<2000000
+  return std::string("OGRDataSource");
+#else
   return std::string("GDALDataset");
+#endif
 }
 
 std::string GetDriverClassName()
 {
+#if GDAL_VERSION_NUM<2000000
+  return std::string("OGRSFDriver");
+#else
   return std::string("GDALDriver");
+#endif
 }
 
+#if GDAL_VERSION_NUM>=2000000
 namespace raii
 {
 // This class is used in the next function, so as to prevent any
@@ -118,11 +172,14 @@ private:
   char ** m_P;
 };
 }
+#endif
 
 std::vector<std::string> GetFileListAsStringVector(GDALDatasetType * dataset)
 {
   std::vector<std::string> ret;
-
+#if GDAL_VERSION_NUM<2000000
+  ret.push_back(std::string(dataset->GetName()));
+#else
   raii::CharPPCapsule capsule(dataset->GetFileList());
 
   std::string files_str="";
@@ -136,35 +193,62 @@ std::vector<std::string> GetFileListAsStringVector(GDALDatasetType * dataset)
       ++i;
       }
     }
+#endif
   return ret;
 }
 
 bool SyncToDisk(GDALDatasetType * dataset)
 {
+#if GDAL_VERSION_NUM<2000000
+  const OGRErr res= dataset->SyncToDisk();
+  return (res == OGRERR_NONE);
+#else
   dataset->FlushCache();
-
   return true;
+#endif
 }
 
 std::vector<std::string> GetAvailableDriversAsStringVector()
 {
   std::vector<std::string> ret;
+#if GDAL_VERSION_NUM<2000000
+  int nbDrivers = OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
 
+  for(int i = 0; i < nbDrivers;++i)
+    {
+    ret.push_back(OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i)->GetName());
+    }
+#else
   int nbDrivers = GetGDALDriverManager()->GetDriverCount();
 
   for(int i = 0; i < nbDrivers;++i)
     {
     ret.push_back(GDALGetDriverShortName(GetGDALDriverManager()->GetDriver(i)));
     }
-
+#endif
   return ret;
 }
 
 std::string GetDriverNameFromDataSource(const GDALDatasetType * ds)
 {
+#if GDAL_VERSION_NUM<2000000
+  return std::string(const_cast<GDALDatasetType *>(ds)->GetDriver()->GetName());
+#else
   return std::string(const_cast<GDALDatasetType *>(ds)->GetDriverName());
+#endif
+}
+
+/*----------------------[GDAL 2.2 change on IsFieldSet()]---------------------*/
+bool IsFieldSetAndNotNull(OGRFeature *feat, int index)
+{
+#if GDAL_VERSION_NUM<2020000
+  return feat->IsFieldSet(index);
+#else
+  return feat->IsFieldSetAndNotNull(index);
+#endif
 }
 
 }
 }
 } // end namespace
+
diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy1x.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy1x.cxx
deleted file mode 100644
index 47c915342349732a594d0a5360c1ecd8bfe1ae5e..0000000000000000000000000000000000000000
--- a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy1x.cxx
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2005-2017 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 "otbOGRVersionProxy.h"
-
-#include "itkMacro.h"
-
-#if defined(__GNUC__) || defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-#include "ogrsf_frmts.h"
-#pragma GCC diagnostic pop
-#else
-#include "ogrsf_frmts.h"
-#endif
-
-namespace otb
-{
-namespace ogr
-{
-namespace version_proxy
-{
-
-OTBGdalAdapters_EXPORT bool IsOFTInteger64(OGRFieldType itkNotUsed(type))
-{
-  return false;
-}
-
-
-GDALDatasetType * Open(const char * filename, bool readOnly)
-{
-  return OGRSFDriverRegistrar::Open(filename,!readOnly);
-}
-
-void Close(GDALDatasetType * dataset)
-{
-  OGRDataSource::DestroyDataSource(dataset);
-}
-
-GDALDatasetType * Create(GDALDriverType * driver, const char * name)
-{
-  GDALDatasetType * ds = driver->CreateDataSource(name);
-
-  if(ds)
-    ds->SetDriver(driver);
-
-  return ds;
-}
-
-bool Delete(const char * name)
-{
-  // Open dataset
-  GDALDatasetType * poDS = Open(name,false);
-  GDALDriverType * poDriver = ITK_NULLPTR;
-  if(poDS)
-    {
-    poDriver = poDS->GetDriver();
-    Close(poDS);
-    }
-
-  if(poDriver && poDriver->TestCapability(ODrCDeleteDataSource))
-    {
-
-    OGRErr ret = poDriver->DeleteDataSource(name);
-    return (ret == OGRERR_NONE);
-    }
-
-  return false;
-}
-
-GDALDriverType *  GetDriverByName(const char * name)
-{
-  return OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(name);
-}
-
-std::string GetDatasetClassName()
-{
-  return std::string("OGRDataSource");
-}
-
-std::string GetDriverClassName()
-{
-  return std::string("OGRSFDriver");
-}
-
-std::vector<std::string> GetFileListAsStringVector(GDALDatasetType * dataset)
-{
-  std::vector<std::string> ret;
-
-  ret.push_back(std::string(dataset->GetName()));
-
-  return ret;
-}
-
-bool SyncToDisk(GDALDatasetType * dataset)
-{
-  const OGRErr res= dataset->SyncToDisk();
-
-  return (res == OGRERR_NONE);
-}
-
-std::vector<std::string> GetAvailableDriversAsStringVector()
-{
-  std::vector<std::string> ret;
-
-  int nbDrivers = OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
-
-  for(int i = 0; i < nbDrivers;++i)
-    {
-    ret.push_back(OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i)->GetName());
-    }
-
-  return ret;
-}
-
-std::string GetDriverNameFromDataSource(const GDALDatasetType * ds)
-{
-  return std::string(const_cast<GDALDatasetType *>(ds)->GetDriver()->GetName());
-}
-
-}
-}
-} // end namespace
diff --git a/Modules/Applications/AppChangeDetection/app/otbMultivariateAlterationDetector.cxx b/Modules/Applications/AppChangeDetection/app/otbMultivariateAlterationDetector.cxx
index c54940788ca5b0684e436f635d02fe07d92346f4..668930e92202047b758e168f77eb37f22c381620 100644
--- a/Modules/Applications/AppChangeDetection/app/otbMultivariateAlterationDetector.cxx
+++ b/Modules/Applications/AppChangeDetection/app/otbMultivariateAlterationDetector.cxx
@@ -46,58 +46,59 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("MultivariateAlterationDetector");
-    SetDescription("Multivariate Alteration Detector");
+    SetDescription("Change detection by Multivariate Alteration Detector (MAD) algorithm");
 
     // Documentation
-    SetDocName("Multivariate alteration detector");
-    SetDocLongDescription("This application detects change between two given images.");
-    SetDocLimitations("None");
+    SetDocName("Multivariate Alteration Detector");
+    SetDocLongDescription("This application performs change detection between two multispectral"
+                          " images using the Multivariate Alteration Detector (MAD) [1]"
+                          " algorithm.\n\n"
+                          "The MAD algorithm produces a set of N change maps (where N is the"
+                          " maximum number of bands in first and second input images), with the"
+                          " following properties:\n"
+                          " - Change maps are differences of a pair of linear combinations of "
+                          " bands from image 1 and bands from image 2 chosen to maximize the "
+                          " correlation, \n"
+                          " - Each change map is orthogonal to the others.\n"
+                          " \n"
+                          "This is a statistical method which can handle different modalities"
+                          " and even different bands and number of bands between images. \n"
+                          " \n"
+                          "The application will output all change maps into a single multiband"
+                          " image. If numbers of bands in image 1 and 2 are equal, then change"
+                          " maps are sorted by increasing correlation. If number of bands is"
+                          " different, the change maps are sorted by decreasing correlation. \n"
+                          " \n"
+                          "The application will also print the following information:\n"
+                          "- Mean1 and Mean2 which are the mean values of bands for both input"
+                          " images,\n"
+                          "- V1 and V2 which are the two linear transform that are applied to"
+                          " input image 1 and input image 2 to build the change map,\n"
+                          "- Rho, the vector of correlation associated to each change map.\n"
+                          " \n"
+                          "The OTB filter used in this application has been implemented from the"
+                          " Matlab code kindly made available by the authors here [2]. Both cases"
+                          " (same and different number of bands) have been validated"
+                          " by comparing the output image to the output produced by the Matlab "
+                          " code, and the reference images for testing have been generated from "
+                          " the Matlab code using Octave." );
+
+                          
+    SetDocLimitations("Input images 1 and 2 should share exactly the same origin, spacing, size, and projection if any.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" This filter implements the Multivariate Alteration Detector, based "
-                  " on the following work: \n"
-                  " A. A. Nielsen and K. Conradsen, Multivariate alteration detection"
-                  " (mad) in multispectral, bi-temporal image data: a new approach to"
-                  " change detection studies, Remote Sens. Environ., vol. 64,"
-                  " pp. 1-19, (1998) \n"
-                  " \n"
-                  " Multivariate Alteration Detector takes two images as inputs and "
-                  " produce a set of N change maps as a VectorImage (where N is the "
-                  " maximum of number of bands in first and second image) with the "
-                  " following properties: \n"
-                  " - Change maps are differences of a pair of linear combinations of "
-                  " bands from image 1 and bands from image 2 chosen to maximize the "
-                  " correlation. \n"
-                  " - Each change map is orthogonal to the others. \n"
-                  " \n"
-                  " This is a statistical method which can handle different modalities "
-                  " and even different bands and number of bands between images. \n"
-                  " \n"
-                  " If numbers of bands in image 1 and 2 are equal, then change maps "
-                  " are sorted by increasing correlation. If number of bands is "
-                  " different, the change maps are sorted by decreasing correlation. \n"
-                  " \n"
-                  " The GetV1() and GetV2() methods allow retrieving the linear "
-                  " combinations used to generate the Mad change maps as a vnl_matrix of "
-                  " double, and the GetRho() method allows retrieving the correlation "
-                  " associated to each Mad change maps as a vnl_vector. \n"
-                  " \n"
-                  " This filter has been implemented from the Matlab code kindly made "
-                  " available by the authors here: \n"
-                  " http://www2.imm.dtu.dk/~aa/software.html \n"
-                  " \n"
-                  " Both cases (same and different number of bands) have been validated "
-                  " by comparing the output image to the output produced by the Matlab "
-                  " code, and the reference images for testing have been generated from "
-                  " the Matlab code using Octave." );
-
-    AddDocTag(Tags::FeatureExtraction);
+    SetDocSeeAlso("[1] Nielsen, A. A., & Conradsen, K. (1997). Multivariate alteration"
+                  "detection (MAD) in multispectral, bi-temporal image data: A new"
+                  "approach to change detection studies.\n"
+                  "[2] http://www2.imm.dtu.dk/~aa/software.html");
+
+    AddDocTag(Tags::ChangeDetection);
 
     AddParameter(ParameterType_InputImage,  "in1", "Input Image 1");
-    SetParameterDescription("in1","Image which describe initial state of the scene.");
+    SetParameterDescription("in1","Multiband image of the scene before perturbations");
     AddParameter(ParameterType_InputImage,  "in2", "Input Image 2");
-    SetParameterDescription("in2","Image which describe scene after perturbations.");
+    SetParameterDescription("in2","Mutliband image of the scene after perturbations.");
     AddParameter(ParameterType_OutputImage, "out", "Change Map");
-    SetParameterDescription("out","Image of detected changes.");
+    SetParameterDescription("out","Multiband image containing change maps. Each map will be in range [-1,1], so a floating point output type is advised.");
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppClassification/app/CMakeLists.txt b/Modules/Applications/AppClassification/app/CMakeLists.txt
index 881f0b600f27b359744915784e84d334885d984f..cfa104e5902c882cb2634b2f9269b8f86b54bd14 100644
--- a/Modules/Applications/AppClassification/app/CMakeLists.txt
+++ b/Modules/Applications/AppClassification/app/CMakeLists.txt
@@ -149,3 +149,6 @@ otb_create_application(
   NAME           VectorClassifier
   SOURCES        otbVectorClassifier.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
+# Mantis-1427 : temporary fix
+add_dependencies(${otb-module}-all otbapp_ImageEnvelope)
diff --git a/Modules/Applications/AppClassification/app/otbComputeImagesStatistics.cxx b/Modules/Applications/AppClassification/app/otbComputeImagesStatistics.cxx
index fbb8bef4b1d27b6b4ea6739a02d018f6e4f8d745..0956eb7a0068264402c218687efd3c89feacfc76 100644
--- a/Modules/Applications/AppClassification/app/otbComputeImagesStatistics.cxx
+++ b/Modules/Applications/AppClassification/app/otbComputeImagesStatistics.cxx
@@ -48,12 +48,19 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("ComputeImagesStatistics");
-    SetDescription("Computes global mean and standard deviation for each band from a set of images and optionally saves the results in an XML file.");
     SetDocName("Compute Images second order statistics");
-    SetDocLongDescription("This application computes a global mean and standard deviation for each band of a set of images and optionally saves the results in an XML file. The output XML is intended to be used an input for the TrainImagesClassifier application to normalize samples before learning.");
-    SetDocLimitations("Each image of the set must contain the same bands as the others (i.e. same types, in the same order).");
+    SetDescription("Computes global mean and standard deviation for each band "
+      "from a set of images and optionally saves the results in an XML file.");
+    SetDocLongDescription("This application computes a global mean and standard deviation "
+      "for each band of a set of images and optionally saves the results in an XML file."
+      " The output XML is intended to be used an input "
+      "for the TrainImagesClassifier application to normalize samples before learning. "
+      "You can also normalize the image with the XML file in the ImageClassifier application.");
+
+    SetDocLimitations("Each image of the set must contain the same bands as the others"
+                      " (i.e. same types, in the same order).");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("Documentation of the TrainImagesClassifier application.");
+    SetDocSeeAlso("Documentation of the TrainImagesClassifier and ImageClassifier application.");
 
     AddDocTag(Tags::Learning);
     AddDocTag(Tags::Analysis);
diff --git a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
index 15c821e9b090661314c066b678fa1651a61886bf..b31ae21c16d927de64135bdd47b1f07ebb9d595e 100644
--- a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
+++ b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
@@ -108,7 +108,7 @@ private:
         "confusion matrix file for the Dempster Shafer fusion.\n"
         "  - Input pixels with the NODATA label are not handled in the fusion of classification maps. Moreover, pixels for which all the input classifiers are set to NODATA "
         "keep this value in the output fused image.\n"
-        "  - In case of number of votes equality, the UNDECIDED label is attributed to the pixel.\n");
+        "  - In case of number of votes equality, the UNDECIDED label is attributed to the pixel.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("ImageClassifier application");
diff --git a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
index 47ba61e9b705da15b83794d55ecb3be5284a569c..1f94d2714355e37db5137cfd85d3de72b3927e57 100644
--- a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
@@ -50,7 +50,8 @@ public:
   itkTypeMacro(ImageClassifier, otb::Application);
 
   /** Filters typedef */
-  typedef UInt16ImageType                                                                      OutputImageType;
+  //typedef UInt16ImageType                                                                    OutputImageType;
+  typedef Int32ImageType                                                                       OutputImageType;
   typedef UInt8ImageType                                                                       MaskImageType;
   typedef itk::VariableLengthVector<FloatVectorImageType::InternalPixelType>                   MeasurementType;
   typedef otb::StatisticsXMLFileReader<MeasurementType>                                        StatisticsReader;
@@ -79,7 +80,7 @@ private:
 
     // Documentation
     SetDocName("Image Classification");
-    SetDocLongDescription("This application performs an image classification based on a model file produced by the TrainImagesClassifier application. Pixels of the output image will contain the class labels decided by the classifier (maximal class label = 65535). The input pixels can be optionally centered and reduced according to the statistics file produced by the ComputeImagesStatistics application. An optional input mask can be provided, in which case only input image pixels whose corresponding mask value is greater than 0 will be classified. The remaining of pixels will be given the label 0 in the output image.");
+    SetDocLongDescription("This application performs an image classification based on a model file produced by the TrainImagesClassifier application. Pixels of the output image will contain the class labels decided by the classifier (maximal class label = 65535). The input pixels can be optionally centered and reduced according to the statistics file produced by the ComputeImagesStatistics application. An optional input mask can be provided, in which case only input image pixels whose corresponding mask value is greater than 0 will be classified. By default, the remaining of pixels will be given the label 0 in the output image.");
 
     SetDocLimitations("The input image must have the same type, order and number of bands than the images used to produce the statistics file and the SVM model file. If a statistics file was used during training by the TrainImagesClassifier, it is mandatory to use the same statistics file for classification. If an input mask is used, its size must match the input image size.");
     SetDocAuthors("OTB-Team");
@@ -101,6 +102,15 @@ private:
     SetParameterDescription("imstat", "A XML file containing mean and standard deviation to center and reduce samples before classification (produced by ComputeImagesStatistics application).");
     MandatoryOff("imstat");
 
+    AddParameter(ParameterType_Int, "nodatalabel", "Label mask value");
+    SetParameterDescription("nodatalabel", "By default, "
+      "hidden pixels will have the assigned label 0 in the output image. "
+      "It's possible to define the label mask by another value, "
+      "but be careful to not take a label from another class (max. 65535).");
+
+    SetDefaultParameterInt("nodatalabel", 0);
+    MandatoryOff("nodatalabel");
+
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
     SetParameterDescription( "out", "Output image containing class labels");
     SetDefaultOutputPixelType( "out", ImagePixelType_uint8);
@@ -165,6 +175,8 @@ private:
     m_ClassificationFilter = ClassificationFilterType::New();
     m_ClassificationFilter->SetModel(m_Model);
 
+    m_ClassificationFilter->SetDefaultLabel(GetParameterInt("nodatalabel"));
+
     // Normalize input image if asked
     if(IsParameterEnabled("imstat")  )
       {
diff --git a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
index 36eeb318fadd983426556b41c0336d21a0366448..173daeec99126cd7cf288890d5c6d009b3a41b71 100644
--- a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
+++ b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
@@ -18,536 +18,500 @@
  * limitations under the License.
  */
 
-
-#include "otbWrapperApplication.h"
+#include "otbWrapperCompositeApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
-#include "otbVectorImage.h"
-#include "otbStreamingTraits.h"
-#include "itkImageRegionConstIterator.h"
-#include "itkListSample.h"
-#include "itkWeightedCentroidKdTreeGenerator.h"
-#include "itkKdTreeBasedKmeansEstimator.h"
-#include "otbStreamingShrinkImageFilter.h"
-#include "otbChangeLabelImageFilter.h"
-#include "otbRAMDrivenStrippedStreamingManager.h"
-
-#include "otbChangeLabelImageFilter.h"
-#include "itkLabelToRGBImageFilter.h"
-#include "otbReliefColormapFunctor.h"
-#include "itkScalarToRGBColormapImageFilter.h"
-
+#include "otbOGRDataToSamplePositionFilter.h"
 
 namespace otb
 {
-
-
 namespace Wrapper
 {
 
-namespace Functor
-{
-template <class TSample, class TLabel> class KMeansFunctor
-{
-public:
-  /** operator */
-  TLabel operator ()(const TSample& sample) const
-  {
-    typename CentroidMapType::const_iterator it = m_CentroidsMap.begin();
-
-    if (it == m_CentroidsMap.end())
-      {
-      return 0;
-      }
-
-    TLabel resp = it->first;
-    double minDist = m_Distance->Evaluate(sample, it->second);
-    ++it;
-
-    while (it != m_CentroidsMap.end())
-      {
-      double dist = m_Distance->Evaluate(sample, it->second);
-
-      if (dist < minDist)
-        {
-        resp = it->first;
-        minDist = dist;
-        }
-      ++it;
-      }
-    return resp;
-  }
-
-  /** Add a new centroid */
-  void AddCentroid(const TLabel& label, const TSample& centroid)
-  {
-    m_CentroidsMap[label] = centroid;
-  }
-
-  /** Constructor */
-  KMeansFunctor() : m_CentroidsMap(), m_Distance()
-  {
-    m_Distance = DistanceType::New();
-  }
-
-  bool operator !=(const KMeansFunctor& other) const
-  {
-    return m_CentroidsMap != other.m_CentroidsMap;
-  }
-
-private:
-  typedef std::map<TLabel, TSample>                   CentroidMapType;
-  typedef itk::Statistics::EuclideanDistanceMetric<TSample> DistanceType;
-
-  CentroidMapType m_CentroidsMap;
-  typename DistanceType::Pointer m_Distance;
-};
-}
-
-
-typedef FloatImageType::PixelType PixelType;
-typedef UInt16ImageType   LabeledImageType;
-
-typedef UInt16VectorImageType       VectorImageType;
-typedef VectorImageType::PixelType  VectorPixelType;
-typedef UInt8RGBImageType           RGBImageType;
-typedef RGBImageType::PixelType     RGBPixelType;
-
-
-typedef LabeledImageType::PixelType LabelType;
-
-
-typedef FloatVectorImageType::PixelType                               SampleType;
-typedef itk::Statistics::ListSample<SampleType> ListSampleType;
-typedef itk::Statistics::WeightedCentroidKdTreeGenerator<ListSampleType> TreeGeneratorType;
-typedef TreeGeneratorType::KdTreeType TreeType;
-typedef itk::Statistics::KdTreeBasedKmeansEstimator<TreeType> EstimatorType;
-typedef RAMDrivenStrippedStreamingManager<FloatVectorImageType> RAMDrivenStrippedStreamingManagerType;
-
-
-typedef itk::ImageRegionConstIterator<FloatVectorImageType> IteratorType;
-typedef itk::ImageRegionConstIterator<UInt8ImageType> LabeledIteratorType;
-
-typedef otb::StreamingShrinkImageFilter<FloatVectorImageType,
-     FloatVectorImageType>              ImageSamplingFilterType;
-
-typedef otb::StreamingShrinkImageFilter<UInt8ImageType,
-    UInt8ImageType>              MaskSamplingFilterType;
-typedef Functor::KMeansFunctor<SampleType, LabelType> KMeansFunctorType;
-typedef itk::UnaryFunctorImageFilter<FloatVectorImageType,
-    LabeledImageType, KMeansFunctorType>     KMeansFilterType;
-
-
-// Manual label LUT
- typedef otb::ChangeLabelImageFilter
- <LabeledImageType, VectorImageType>    ChangeLabelFilterType;
-
- // Continuous LUT mapping
-  typedef itk::ScalarToRGBColormapImageFilter<LabeledImageType, RGBImageType>      ColorMapFilterType;
-
-
-  typedef otb::Functor::ReliefColormapFunctor
-   <LabelType, RGBPixelType>           ReliefColorMapFunctorType;
-
-  typedef otb::ImageMetadataInterfaceBase ImageMetadataInterfaceType;
-
-
-class KMeansClassification: public Application
+class KMeansApplicationBase : public CompositeApplication
 {
 public:
   /** Standard class typedefs. */
-  typedef KMeansClassification Self;
-  typedef Application Superclass;
+  typedef KMeansApplicationBase Self;
+  typedef CompositeApplication Superclass;
   typedef itk::SmartPointer<Self> Pointer;
   typedef itk::SmartPointer<const Self> ConstPointer;
 
   /** Standard macro */
-  itkNewMacro(Self);
+  itkTypeMacro( KMeansApplicationBase, Superclass )
 
-  itkTypeMacro(KMeansClassification, otb::Application);
-
-private:
-  void DoInit() ITK_OVERRIDE
+protected:
+  void InitKMParams()
   {
-    SetName("KMeansClassification");
-    SetDescription("Unsupervised KMeans image classification");
+    AddApplication("ImageEnvelope", "imgenvelop", "mean shift smoothing");
+    AddApplication("PolygonClassStatistics", "polystats", "Polygon Class Statistics");
+    AddApplication("SampleSelection", "select", "Sample selection");
+    AddApplication("SampleExtraction", "extraction", "Sample extraction");
+
+    AddApplication("TrainVectorClassifier", "training", "Model training");
+    AddApplication("ComputeImagesStatistics", "imgstats", "Compute Images second order statistics");
+    AddApplication("ImageClassifier", "classif", "Performs a classification of the input image");
+
+    ShareParameter("in", "imgenvelop.in");
+    ShareParameter("out", "classif.out");
+
+    InitKMSampling();
+    InitKMClassification();
+
+    // init at the end cleanup
+    AddParameter( ParameterType_Empty, "cleanup", "Temporary files cleaning" );
+    EnableParameter( "cleanup" );
+    SetParameterDescription( "cleanup",
+                           "If activated, the application will try to clean all temporary files it created" );
+    MandatoryOff( "cleanup" );
+  }
 
-    SetDocName("Unsupervised KMeans image classification");
-    SetDocLongDescription("Performs unsupervised KMeans image classification.");
-    SetDocLimitations("None");
-    SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+  void InitKMSampling()
+  {
+    AddParameter(ParameterType_Int, "nc", "Number of classes");
+    SetParameterDescription("nc", "Number of modes, which will be used to generate class membership.");
+    SetDefaultParameterInt("nc", 5);
 
-    AddDocTag(Tags::Learning);
-	AddDocTag(Tags::Segmentation);
-	
-    AddParameter(ParameterType_InputImage, "in", "Input Image");
-    SetParameterDescription("in", "Input image to classify.");
-    AddParameter(ParameterType_OutputImage, "out", "Output Image");
-    SetParameterDescription("out", "Output image containing the class indexes.");
-    SetDefaultOutputPixelType("out",ImagePixelType_uint8);
-
-    AddRAMParameter();
-
-    AddParameter(ParameterType_InputImage, "vm", "Validity Mask");
-    SetParameterDescription("vm", "Validity mask. Only non-zero pixels will be used to estimate KMeans modes.");
-    MandatoryOff("vm");
     AddParameter(ParameterType_Int, "ts", "Training set size");
     SetParameterDescription("ts", "Size of the training set (in pixels).");
     SetDefaultParameterInt("ts", 100);
     MandatoryOff("ts");
-    AddParameter(ParameterType_Int, "nc", "Number of classes");
-    SetParameterDescription("nc", "Number of modes, which will be used to generate class membership.");
-    SetDefaultParameterInt("nc", 5);
+
     AddParameter(ParameterType_Int, "maxit", "Maximum number of iterations");
     SetParameterDescription("maxit", "Maximum number of iterations for the learning step.");
     SetDefaultParameterInt("maxit", 1000);
     MandatoryOff("maxit");
-    AddParameter(ParameterType_Float, "ct", "Convergence threshold");
-    SetParameterDescription("ct", "Convergence threshold for class centroid  (L2 distance, by default 0.0001).");
-    SetDefaultParameterFloat("ct", 0.0001);
-    MandatoryOff("ct");
+
     AddParameter(ParameterType_OutputFilename, "outmeans", "Centroid filename");
     SetParameterDescription("outmeans", "Output text file containing centroid positions");
     MandatoryOff("outmeans");
 
-    AddRANDParameter();
-
-    // Doc example parameter settings
-    SetDocExampleParameterValue("in", "QB_1_ortho.tif");
-    SetDocExampleParameterValue("ts", "1000");
-    SetDocExampleParameterValue("nc", "5");
-    SetDocExampleParameterValue("maxit", "1000");
-    SetDocExampleParameterValue("ct", "0.0001");
-    SetDocExampleParameterValue("out", "ClassificationFilterOutput.tif");
-
-    SetOfficialDocLink();
+    ShareKMSamplingParameters();
+    ConnectKMSamplingParams();
   }
 
-  void DoUpdateParameters() ITK_OVERRIDE
+  void InitKMClassification()
   {
-    // test of input image //
-    if (HasValue("in"))
-      {
-      // input image
-      FloatVectorImageType::Pointer inImage = GetParameterImage("in");
+    ShareKMClassificationParams();
+    ConnectKMClassificationParams();
+  }
 
-      RAMDrivenStrippedStreamingManagerType::Pointer streamingManager = RAMDrivenStrippedStreamingManagerType::New();
-      int availableRAM = GetParameterInt("ram");
-      streamingManager->SetAvailableRAMInMB(availableRAM);
-      float bias = 1.5; // empirical value
-      streamingManager->SetBias(bias);
-      FloatVectorImageType::RegionType largestRegion = inImage->GetLargestPossibleRegion();
-      FloatVectorImageType::SizeType largestRegionSize = largestRegion.GetSize();
-      streamingManager->PrepareStreaming(inImage, largestRegion);
+  void ShareKMSamplingParameters()
+  {
+    ShareParameter("ram", "polystats.ram");
+    ShareParameter("sampler", "select.sampler");
+    ShareParameter("vm", "polystats.mask", "Validity Mask",
+      "Validity mask, only non-zero pixels will be used to estimate KMeans modes.");
+  }
 
-      unsigned long nbDivisions = streamingManager->GetNumberOfSplits();
-      unsigned long largestPixNb = largestRegionSize[0] * largestRegionSize[1];
+  void ShareKMClassificationParams()
+  {
+    ShareParameter("nodatalabel", "classif.nodatalabel", "Label mask value",
+      "By default, hidden pixels will have the assigned label 0 in the output image. "
+      "It's possible to define the label mask by another value, "
+      "but be careful to not take a label from another class. "
+      "This application initalize the labels from 0 to N-1, "
+      "N is the number of class (defined by 'nc' parameter).");
+  }
 
-      unsigned long maxPixNb = largestPixNb / nbDivisions;
+  void ConnectKMSamplingParams()
+  {
+    Connect("polystats.in", "imgenvelop.in");
 
-      if (GetParameterInt("ts") > static_cast<int> (maxPixNb))
-        {
-        otbAppLogWARNING("The available RAM is too small to process this sample size of " << GetParameterInt("ts") <<
-            " pixels. The sample size will be reduced to " << maxPixNb << " pixels." << std::endl);
-        this->SetParameterInt("ts",maxPixNb, false);
-        }
+    Connect("select.in", "polystats.in");
+    Connect("select.vec", "polystats.vec");
+    Connect("select.ram", "polystats.ram");
 
-      this->SetMaximumParameterIntValue("ts", maxPixNb);
-      }
+    Connect("extraction.in", "select.in");
+    Connect("extraction.field", "select.field");
+    Connect("extraction.vec", "select.out");
+    Connect("extraction.ram", "polystats.ram");
   }
 
-  void DoExecute() ITK_OVERRIDE
+  void ConnectKMClassificationParams()
   {
-    GetLogger()->Debug("Entering DoExecute\n");
+    Connect("training.cfield", "extraction.field");
+    Connect("training.io.stats","imgstats.out");
 
-    m_InImage = GetParameterImage("in");
-    m_InImage->UpdateOutputInformation();
-    UInt8ImageType::Pointer maskImage;
+    Connect("classif.in", "imgenvelop.in");
+    Connect("classif.model", "training.io.out");
+    Connect("classif.ram", "polystats.ram");
+    Connect("classif.imstat", "imgstats.out");
+  }
 
-    std::ostringstream message("");
+  void ConnectKMClassificationMask()
+  {
+    otbAppLogINFO("Using input mask ...");
+    Connect("select.mask", "polystats.mask");
+    Connect("classif.mask", "select.mask");
+  }
 
-    int nbsamples = GetParameterInt("ts");
-    const unsigned int nbClasses = GetParameterInt("nc");
+  void ComputeImageEnvelope(const std::string &vectorFileName)
+  {
+    GetInternalApplication("imgenvelop")->SetParameterString("out", vectorFileName, false);
+    GetInternalApplication("imgenvelop")->ExecuteAndWriteOutput();
+  }
 
-    /*******************************************/
-    /*           Sampling data                 */
-    /*******************************************/
+  void ComputeAddField(const std::string &vectorFileName,
+                       const std::string &fieldName)
+  {
+    otbAppLogINFO("add field in the layer ...");
+    otb::ogr::DataSource::Pointer ogrDS;
+    ogrDS = otb::ogr::DataSource::New(vectorFileName, otb::ogr::DataSource::Modes::Update_LayerUpdate);
+    otb::ogr::Layer layer = ogrDS->GetLayer(0);
+
+    OGRFieldDefn classField(fieldName.c_str(), OFTInteger);
+    classField.SetWidth(classField.GetWidth());
+    classField.SetPrecision(classField.GetPrecision());
+    ogr::FieldDefn classFieldDefn(classField);
+    layer.CreateField(classFieldDefn);
+
+    otb::ogr::Layer::const_iterator it = layer.cbegin();
+    otb::ogr::Layer::const_iterator itEnd = layer.cend();
+    for( ; it!=itEnd ; ++it)
+    {
+      ogr::Feature dstFeature(layer.GetLayerDefn());
+      dstFeature.SetFrom( *it, TRUE);
+      dstFeature.SetFID(it->GetFID());
+      dstFeature[fieldName].SetValue<int>(0);
+      layer.SetFeature(dstFeature);
+    }
+    const OGRErr err = layer.ogr().CommitTransaction();
+    if (err != OGRERR_NONE)
+      itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << layer.ogr().GetName() << ".");
+    ogrDS->SyncToDisk();
+  }
 
-    otbAppLogINFO("-- SAMPLING DATA --"<<std::endl);
+  void ComputePolygonStatistics(const std::string &statisticsFileName,
+                                const std::string &fieldName)
+  {
+    std::vector<std::string> fieldList = {fieldName};
 
-    // Update input images information
-    m_InImage->UpdateOutputInformation();
+    GetInternalApplication("polystats")->SetParameterStringList("field", fieldList, false);
+    GetInternalApplication("polystats")->SetParameterString("out", statisticsFileName, false);
 
-    bool maskFlag = IsParameterEnabled("vm");
-    if (maskFlag)
-      {
-      otbAppLogINFO("sample choice using mask "<<std::endl);
-      maskImage = GetParameterUInt8Image("vm");
-      maskImage->UpdateOutputInformation();
-      if (m_InImage->GetLargestPossibleRegion() != maskImage->GetLargestPossibleRegion())
-        {
-        GetLogger()->Error("Mask image and input image have different sizes.");
-        return;
-        }
-      }
+    ExecuteInternal("polystats");
+  }
 
-    // Training sample lists
-    ListSampleType::Pointer sampleList = ListSampleType::New();
-    sampleList->SetMeasurementVectorSize(m_InImage->GetNumberOfComponentsPerPixel());
+  void SelectAndExtractSamples(const std::string &statisticsFileName,
+                               const std::string &fieldName,
+                               const std::string &sampleFileName,
+                               int NBSamples)
+  {
+    /* SampleSelection */
+    GetInternalApplication("select")->SetParameterString("out", sampleFileName, false);
 
-    //unsigned int init_means_index = 0;
+    UpdateInternalParameters("select");
+    GetInternalApplication("select")->SetParameterString("instats", statisticsFileName, false);
+    GetInternalApplication("select")->SetParameterString("field", fieldName, false);
 
-    // Sample dimension and max dimension
-    const unsigned int nbComp = m_InImage->GetNumberOfComponentsPerPixel();
-    unsigned int sampleSize = nbComp;
-    unsigned int totalSamples = 0;
+    GetInternalApplication("select")->SetParameterString("strategy", "constant", false);
+    GetInternalApplication("select")->SetParameterInt("strategy.constant.nb", NBSamples, false);
 
-    // sampleSize = std::min(nbComp, maxDim);
+    if( IsParameterEnabled("rand"))
+      GetInternalApplication("select")->SetParameterInt("rand", GetParameterInt("rand"), false);
 
-    EstimatorType::ParametersType initialMeans(nbComp * nbClasses);
-    initialMeans.Fill(0);
+    // select sample positions
+    ExecuteInternal("select");
 
-    // use image and mask shrink
+    /* SampleExtraction */
+    UpdateInternalParameters("extraction");
 
-    ImageSamplingFilterType::Pointer imageSampler = ImageSamplingFilterType::New();
-    imageSampler->SetInput(m_InImage);
+    GetInternalApplication("extraction")->SetParameterString("outfield", "prefix", false);
+    GetInternalApplication("extraction")->SetParameterString("outfield.prefix.name", "value_", false);
 
-    double theoricNBSamplesForKMeans = nbsamples;
+    // extract sample descriptors
+    GetInternalApplication("extraction")->ExecuteAndWriteOutput();
+  }
 
-    const double upperThresholdNBSamplesForKMeans = 1000 * 1000;
-    const double actualNBSamplesForKMeans = std::min(theoricNBSamplesForKMeans, upperThresholdNBSamplesForKMeans);
+  void TrainKMModel(FloatVectorImageType *image,
+                    const std::string &sampleTrainFileName,
+                    const std::string &modelFileName)
+  {
+    std::vector<std::string> extractOutputList = {sampleTrainFileName};
+    GetInternalApplication("training")->SetParameterStringList("io.vd", extractOutputList, false);
+    UpdateInternalParameters("training");
+
+    // set field names
+    std::string selectPrefix = GetInternalApplication("extraction")->GetParameterString("outfield.prefix.name");
+    unsigned int nbBands = image->GetNumberOfComponentsPerPixel();
+    std::vector<std::string> selectedNames;
+    for( unsigned int i = 0; i < nbBands; i++ )
+      {
+      std::ostringstream oss;
+      oss << i;
+      selectedNames.push_back( selectPrefix + oss.str() );
+      }
+    GetInternalApplication("training")->SetParameterStringList("feat", selectedNames, false);
 
-    otbAppLogINFO(<< actualNBSamplesForKMeans << " is the maximum sample size that will be used." << std::endl);
+    GetInternalApplication("training")->SetParameterString("classifier", "sharkkm", false);
+    GetInternalApplication("training")->SetParameterInt("classifier.sharkkm.maxiter",
+                                                        GetParameterInt("maxit"), false);
+    GetInternalApplication("training")->SetParameterInt("classifier.sharkkm.k",
+                                                        GetParameterInt("nc"), false);
 
-    const double shrinkFactor = vcl_floor(
-                                          vcl_sqrt(
-                                                   m_InImage->GetLargestPossibleRegion().GetNumberOfPixels()
-                                                       / actualNBSamplesForKMeans));
-    imageSampler->SetShrinkFactor(shrinkFactor);
-    imageSampler->Update();
+    if( IsParameterEnabled("rand"))
+      GetInternalApplication("training")->SetParameterInt("rand", GetParameterInt("rand"), false);
+    GetInternalApplication("training")->GetParameterByKey("v")->SetActive(false);
 
-    MaskSamplingFilterType::Pointer maskSampler;
-    LabeledIteratorType m_MaskIt;
-    if (maskFlag)
-      {
-      maskSampler = MaskSamplingFilterType::New();
-      maskSampler->SetInput(maskImage);
-      maskSampler->SetShrinkFactor(shrinkFactor);
-      maskSampler->Update();
-      m_MaskIt = LabeledIteratorType(maskSampler->GetOutput(), maskSampler->GetOutput()->GetLargestPossibleRegion());
-      m_MaskIt.GoToBegin();
-      }
-    // Then, build the sample list
+    GetInternalApplication("training")->SetParameterString("io.out", modelFileName, false);
 
-    IteratorType it(imageSampler->GetOutput(), imageSampler->GetOutput()->GetLargestPossibleRegion());
+    ExecuteInternal( "training" );
+    otbAppLogINFO("output model : " << GetInternalApplication("training")->GetParameterString("io.out"));
+  }
 
-    it.GoToBegin();
+  void ComputeImageStatistics(const std::string &imageFileName,
+                                               const std::string &imagesStatsFileName)
+  {
+    std::vector<std::string> imageFileNameList = {imageFileName};
+    GetInternalApplication("imgstats")->SetParameterStringList("il", imageFileNameList, false);
+    GetInternalApplication("imgstats")->SetParameterString("out", imagesStatsFileName, false);
 
-    SampleType min;
-    SampleType max;
-    SampleType sample;
-    //first sample
+    ExecuteInternal( "imgstats" );
+    otbAppLogINFO("image statistics file : " << GetInternalApplication("imgstats")->GetParameterString("out"));
+  }
 
-    itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randGen=itk::Statistics::MersenneTwisterRandomVariateGenerator::GetInstance();
 
-    //randGen->Initialize();
+  void KMeansClassif()
+  {
+    ExecuteInternal( "classif" );
+  }
 
-    if (maskFlag)
+  void CreateOutMeansFile(FloatVectorImageType *image,
+                          const std::string &modelFileName,
+                          unsigned int nbClasses)
+  {
+    if (IsParameterEnabled("outmeans"))
+    {
+      unsigned int nbBands = image->GetNumberOfComponentsPerPixel();
+      unsigned int nbElements = nbClasses * nbBands;
+      // get the line in model file that contains the centroids positions
+      std::ifstream infile(modelFileName);
+      if(!infile)
       {
-      while (!it.IsAtEnd() && !m_MaskIt.IsAtEnd() && (m_MaskIt.Get() <= 0))
-        {
-        ++it;
-        ++m_MaskIt;
-        }
-
-      // If the mask is empty after the subsampling
-      if (m_MaskIt.IsAtEnd())
-        {
-        GetLogger()->Error("The mask image is empty after subsampling. Please increase the training set size.");
-        return;
-        }
+        itkExceptionMacro(<< "File : " << modelFileName << " couldn't be opened");
       }
 
-    min = it.Get();
-    max = it.Get();
-    sample = it.Get();
+      // get the end line with the centroids
+      std::string line, centroidLine;
+      while(std::getline(infile,line))
+      {
+        if (!line.empty())
+          centroidLine = line;
+      }
 
-    sampleList->PushBack(sample);
+      std::vector<std::string> centroidElm;
+      boost::split(centroidElm,centroidLine,boost::is_any_of(" "));
 
-    ++it;
+      // remove the first elements, not the centroids positions
+      int nbWord = centroidElm.size();
+      int beginCentroid = nbWord-nbElements;
+      centroidElm.erase(centroidElm.begin(), centroidElm.begin()+beginCentroid);
 
-    if (maskFlag)
-      {
-      ++m_MaskIt;
-      }
+      // write in the output file
+      std::ofstream outfile;
+      outfile.open(GetParameterString("outmeans"));
 
-    totalSamples = 1;
-    bool selectSample;
-    while (!it.IsAtEnd())
+      for (unsigned int i = 0; i < nbClasses; i++)
       {
-      if (maskFlag)
+        for (unsigned int j = 0; j < nbBands; j++)
         {
-        selectSample = (m_MaskIt.Get() > 0);
-        ++m_MaskIt;
+          outfile << std::setw(8) << centroidElm[i * nbBands + j] << " ";
         }
-      else selectSample = true;
+        outfile << std::endl;
+      }
+    }
+  }
 
-      if (selectSample)
-        {
-        totalSamples++;
+  class KMeansFileNamesHandler
+    {
+    public :
+      KMeansFileNamesHandler(const std::string &outPath)
+      {
+        tmpVectorFile = outPath + "_imgEnvelope.shp";
+        polyStatOutput = outPath + "_polyStats.xml";
+        sampleOutput = outPath + "_sampleSelect.shp";
+        modelFile = outPath + "_model.txt";
+        imgStatOutput = outPath + "_imgstats.xml";
+      }
 
-        sample = it.Get();
+      void clear()
+      {
+        RemoveFile(tmpVectorFile);
+        RemoveFile(polyStatOutput);
+        RemoveFile(sampleOutput);
+        RemoveFile(modelFile);
+        RemoveFile(imgStatOutput);
+      }
 
-        sampleList->PushBack(sample);
+      std::string tmpVectorFile;
+      std::string polyStatOutput;
+      std::string sampleOutput;
+      std::string modelFile;
+      std::string imgStatOutput;
 
-        for (unsigned int i = 0; i < nbComp; ++i)
+    private:
+      bool RemoveFile(const std::string &filePath)
+      {
+        bool res = true;
+        if( itksys::SystemTools::FileExists( filePath.c_str() ) )
           {
-          if (min[i] > sample[i])
+          size_t posExt = filePath.rfind( '.' );
+          if( posExt != std::string::npos && filePath.compare( posExt, std::string::npos, ".shp" ) == 0 )
             {
-            min[i] = sample[i];
+            std::string shxPath = filePath.substr( 0, posExt ) + std::string( ".shx" );
+            std::string dbfPath = filePath.substr( 0, posExt ) + std::string( ".dbf" );
+            std::string prjPath = filePath.substr( 0, posExt ) + std::string( ".prj" );
+            RemoveFile( shxPath );
+            RemoveFile( dbfPath );
+            RemoveFile( prjPath );
             }
-          if (max[i] < sample[i])
+          res = itksys::SystemTools::RemoveFile( filePath.c_str() );
+          if( !res )
             {
-            max[i] = sample[i];
+            //otbAppLogINFO( <<"Unable to remove file  "<<filePath );
             }
           }
-        }
-      ++it;
+        return res;
       }
 
-    // Next, initialize centroids by random sampling in the generated
-    // list of samples
+    };
 
-    for (unsigned int classIndex = 0; classIndex < nbClasses; ++classIndex)
-      {
-      SampleType newCentroid = sampleList->GetMeasurementVector(randGen->GetIntegerVariate(sampleList->Size()-1));
+};
 
-      for (unsigned int compIndex = 0; compIndex < sampleSize; ++compIndex)
-        {
-        initialMeans[compIndex + classIndex * sampleSize] = newCentroid[compIndex];
-        }
-      }
-    otbAppLogINFO(<< totalSamples << " samples will be used as estimator input." << std::endl);
 
-    /*******************************************/
-    /*           Learning                      */
-    /*******************************************/
+class KMeansClassification: public KMeansApplicationBase
+{
+public:
+  /** Standard class typedefs. */
+  typedef KMeansClassification Self;
+  typedef KMeansApplicationBase Superclass;
+  typedef itk::SmartPointer<Self> Pointer;
+  typedef itk::SmartPointer<const Self> ConstPointer;
 
-    otbAppLogINFO("-- LEARNING --" << std::endl);
-    otbAppLogINFO("Initial centroids are: " << std::endl);
+  /** Standard macro */
+  itkNewMacro(Self);
 
-    message.str("");
-    message << std::endl;
-    for (unsigned int i = 0; i < nbClasses; i++)
-      {
-      message << "Class " << i << ": ";
-      for (unsigned int j = 0; j < sampleSize; j++)
-        {
-        message << std::setw(8) << initialMeans[i * sampleSize + j] << "   ";
-        }
-      message << std::endl;
-      }
-    message << std::endl;
-    GetLogger()->Info(message.str());
-    message.str("");
-    otbAppLogINFO("Starting optimization." << std::endl);
-    EstimatorType::Pointer estimator = EstimatorType::New();
+  itkTypeMacro(Self, Superclass);
 
-    TreeGeneratorType::Pointer treeGenerator = TreeGeneratorType::New();
-    treeGenerator->SetSample(sampleList);
+private:
+  void DoInit() ITK_OVERRIDE
+  {
+    SetName("KMeansClassification");
+    SetDescription("Unsupervised KMeans image classification");
 
-    treeGenerator->SetBucketSize(10000);
-    treeGenerator->Update();
+    SetDocName("Unsupervised KMeans image classification");
+    SetDocLongDescription("Performs unsupervised KMeans image classification."
+      "KMeansClassification is a composite application, "
+      "using an existing training and classification application."
+      "The SharkKMeans model is used.\n"
+      "The steps of this composite application :\n"
+        "1) ImageEnveloppe : create a shapefile (1 polygon),\n"
+        "2) PolygonClassStatistics : compute the statistics,\n"
+        "3) SampleSelection : select the samples by constant strategy in the shapefile "
+            "(1000000 samples max),\n"
+        "4) SamplesExtraction : extract the samples descriptors (update of SampleSelection output file),\n"
+        "5) ComputeImagesStatistics : compute images second order statistics,\n"
+        "6) TrainVectorClassifier : train the SharkKMeans model,\n"
+        "7) ImageClassifier : performs the classification of the input image "
+            "according to a model file.\n\n"
+        "It's possible to choice random/periodic modes of the SampleSelection application.\n"
+        "If you want keep the temporary files (sample selected, model file, ...), "
+        "initialize cleanup parameter.\n"
+        "For more information on shark KMeans algorithm [1].");
 
-    estimator->SetParameters(initialMeans);
-    estimator->SetKdTree(treeGenerator->GetOutput());
-    int maxIt = GetParameterInt("maxit");
-    estimator->SetMaximumIteration(maxIt);
-    estimator->SetCentroidPositionChangesThreshold(GetParameterFloat("ct"));
-    estimator->StartOptimization();
+    SetDocLimitations("None");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso("ImageEnveloppe PolygonClassStatistics SampleSelection SamplesExtraction "
+      "PolygonClassStatistics TrainVectorClassifier ImageClassifier\n"
+      "[1] http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html");
 
-    EstimatorType::ParametersType estimatedMeans = estimator->GetParameters();
+    AddDocTag(Tags::Learning);
+    AddDocTag(Tags::Segmentation);
 
-    otbAppLogINFO("Optimization completed." );
-    if (estimator->GetCurrentIteration() == maxIt)
-      {
-      otbAppLogWARNING("The estimator reached the maximum iteration number." << std::endl);
-      }
-    message.str("");
-    message << "Estimated centroids are: " << std::endl;
-    message << std::endl;
-    for (unsigned int i = 0; i < nbClasses; i++)
-      {
-      message << "Class " << i << ": ";
-      for (unsigned int j = 0; j < sampleSize; j++)
-        {
-        message << std::setw(8) << estimatedMeans[i * sampleSize + j] << "   ";
-        }
-      message << std::endl;
-      }
+    // Perform initialization
+    ClearApplications();
 
-    message << std::endl;
-    message << "Learning completed." << std::endl;
-    message << std::endl;
-    GetLogger()->Info(message.str());
+    // initialisation parameters and synchronizes parameters
+    Superclass::InitKMParams();
 
-    /*******************************************/
-    /*           Classification                */
-    /*******************************************/
-    otbAppLogINFO("-- CLASSIFICATION --" << std::endl);
+    AddRANDParameter();
 
-    // Finally, update the KMeans filter
-    KMeansFunctorType functor;
+    // Doc example parameter settings
+    SetDocExampleParameterValue("in", "QB_1_ortho.tif");
+    SetDocExampleParameterValue("ts", "1000");
+    SetDocExampleParameterValue("nc", "5");
+    SetDocExampleParameterValue("maxit", "1000");
+    SetDocExampleParameterValue("out", "ClassificationFilterOutput.tif uint8");
 
-    for (unsigned int classIndex = 0; classIndex < nbClasses; ++classIndex)
-      {
-      SampleType centroid(sampleSize);
+    SetOfficialDocLink();
+  }
 
-      for (unsigned int compIndex = 0; compIndex < sampleSize; ++compIndex)
-        {
-        centroid[compIndex] = estimatedMeans[compIndex + classIndex * sampleSize];
-        }
-      functor.AddCentroid(classIndex, centroid);
-      }
+  void DoUpdateParameters() ITK_OVERRIDE
+  {
+  }
 
-    m_KMeansFilter = KMeansFilterType::New();
-    m_KMeansFilter->SetFunctor(functor);
-    m_KMeansFilter->SetInput(m_InImage);
+  void DoExecute() ITK_OVERRIDE
+  {
+    if (IsParameterEnabled("vm") && HasValue("vm")) Superclass::ConnectKMClassificationMask();
 
-    // optional saving option -> lut
+    KMeansFileNamesHandler fileNames(GetParameterString("out"));
 
-    if (IsParameterEnabled("outmeans"))
-      {
-      std::ofstream file;
-      file.open(GetParameterString("outmeans").c_str());
-      for (unsigned int i = 0; i < nbClasses; i++)
-        {
+    const std::string fieldName = "field";
 
-        for (unsigned int j = 0; j < sampleSize; j++)
-          {
-          file << std::setw(8) << estimatedMeans[i * sampleSize + j] << " ";
-          }
-        file << std::endl;
-        }
+    // Create an image envelope
+    Superclass::ComputeImageEnvelope(fileNames.tmpVectorFile);
+    // Add a new field at the ImageEnvelope output file
+    Superclass::ComputeAddField(fileNames.tmpVectorFile, fieldName);
 
-      file.close();
-      }
+    // Compute PolygonStatistics app
+    UpdateKMPolygonClassStatisticsParameters(fileNames.tmpVectorFile);
+    Superclass::ComputePolygonStatistics(fileNames.polyStatOutput, fieldName);
+
+    // Compute number of sample max for KMeans
+    const int theoricNBSamplesForKMeans = GetParameterInt("ts");
+    const int upperThresholdNBSamplesForKMeans = 1000 * 1000;
+    const int actualNBSamplesForKMeans = std::min(theoricNBSamplesForKMeans,
+                                                  upperThresholdNBSamplesForKMeans);
+    otbAppLogINFO(<< actualNBSamplesForKMeans << " is the maximum sample size that will be used." \
+                  << std::endl);
+
+    // Compute SampleSelection and SampleExtraction app
+    Superclass::SelectAndExtractSamples(fileNames.polyStatOutput, fieldName,
+                                        fileNames.sampleOutput,
+                                        actualNBSamplesForKMeans);
+
+    // Compute Images second order statistics
+    Superclass::ComputeImageStatistics(GetParameterString("in"), fileNames.imgStatOutput);
+
+    // Compute a train model with TrainVectorClassifier app
+    Superclass::TrainKMModel(GetParameterImage("in"), fileNames.sampleOutput,
+                             fileNames.modelFile);
+
+    // Compute a classification of the input image according to a model file
+    Superclass::KMeansClassif();
 
-    SetParameterOutputImage("out", m_KMeansFilter->GetOutput());
+    // Create the output text file containing centroids positions
+    Superclass::CreateOutMeansFile(GetParameterImage("in"), fileNames.modelFile, GetParameterInt("nc"));
 
+    // Remove all tempory files
+    if( IsParameterEnabled( "cleanup" ) )
+      {
+      otbAppLogINFO( <<"Final clean-up ..." );
+      fileNames.clear();
+      }
   }
 
-  // KMeans filter
-  KMeansFilterType::Pointer           m_KMeansFilter;
-  FloatVectorImageType::Pointer       m_InImage;
+  void UpdateKMPolygonClassStatisticsParameters(const std::string &vectorFileName)
+  {
+    GetInternalApplication( "polystats" )->SetParameterString( "vec", vectorFileName, false );
+    UpdateInternalParameters( "polystats" );
+  }
 
 };
 
-
 }
 }
 
 OTB_APPLICATION_EXPORT(otb::Wrapper::KMeansClassification)
 
-
diff --git a/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx b/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx
index 6eb8ee539b14b8faa821bc6211ddc41c6afd8118..889e909cc54301fb53eeb952783e9d1f4325fa20 100644
--- a/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx
+++ b/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx
@@ -110,7 +110,7 @@ private:
       "  * strategy = smallest class\n\n"
       "    - if mim = proportional, then the smallest class size (computed globally) is used for the strategy constant+proportional.\n\n"
       "    - if mim = equal       , then the smallest class size (computed globally) is used for the strategy constant+equal.\n\n"
-      "    - if mim = custom      , then the smallest class is computed and used for each image separately.\n\n"
+      "    - if mim = custom      , then the smallest class is computed and used for each image separately."
       );
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
diff --git a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx
index c1600ebce7e4730d13136682d8d602a583671e7b..ff4f4b01e4be8c30476b4aef78dadaf9819e606f 100644
--- a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx
+++ b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx
@@ -85,7 +85,7 @@ private:
       "different for each type of geometry :\n"
       "  - polygon: select pixels whose center is inside the polygon\n"
       "  - lines  : select pixels intersecting the line\n"
-      "  - points : select closest pixel to the point\n");
+      "  - points : select closest pixel to the point");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
diff --git a/Modules/Applications/AppClassification/app/otbSOMClassification.cxx b/Modules/Applications/AppClassification/app/otbSOMClassification.cxx
index 18e12db92ef7836209082b73816c04196be2c9bf..86572e90ad0eebd83dbc8ec8ee3e338677984af6 100644
--- a/Modules/Applications/AppClassification/app/otbSOMClassification.cxx
+++ b/Modules/Applications/AppClassification/app/otbSOMClassification.cxx
@@ -254,6 +254,10 @@ private:
     itk::RandomPermutation randPerm(numberOfStreamDivisions);
     unsigned int index = 0;
 
+    // reset seed and step once (itk::RandomPermutation may have used it)
+    randomGen->SetSeed(GetParameterInt("rand"));
+    randomGen->GetVariateWithClosedRange();
+
     // TODO : maybe change the approach: at the moment, the sampling process is able to pick a sample twice or more
     while (totalSamples < nbsamples)
     {
diff --git a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx
index 0437978311aff3e1de752907edf94bcc05bd6333..b41f20470f2ac4fe5d2321011cc6c806a66ebb03 100644
--- a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx
+++ b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx
@@ -120,7 +120,7 @@ private:
       "polygons, lines, points. \nThe behavior of this application is different for each type of geometry : \n\n"
       "  - polygon: select points whose center is inside the polygon\n"
       "  - lines  : select points intersecting the line\n"
-      "  - points : select closest point to the provided point\n");
+      "  - points : select closest point to the provided point");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
index 21d3b58552dcd0799d2849632d57093238a7d489..1d1d387c131d3c49fe9402f108e6f1880dd24792 100644
--- a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
@@ -110,9 +110,12 @@ protected:
     contingencyTableCalculator->Compute(performanceLabeledListSample->Begin(),
                                         performanceLabeledListSample->End(),predictedListSample->Begin(), predictedListSample->End());
 
-    otbAppLogINFO( "Training performances:" );
-
-    otbAppLogINFO(<<"Contingency table: reference labels (rows) vs. produced labels (cols)\n"<<contingencyTableCalculator->BuildContingencyTable());
+    if(IsParameterEnabled("v"))
+    {
+      otbAppLogINFO( "Training performances:" );
+      otbAppLogINFO(<<"Contingency table: reference labels (rows) vs. produced labels (cols)\n"
+        <<contingencyTableCalculator->BuildContingencyTable());
+    }
 
     return contingencyTableCalculator->BuildContingencyTable();
   }
diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
index 61d3a691f4560c46d2f76427f49ca7423cd159b8..7fd0efa838a4af62aeedaadf7f1b307d6079b234 100644
--- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
@@ -89,39 +89,52 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("VectorClassifier");
-    SetDescription("Performs a classification of the input vector data according to a model file."
-      "Features of the vector data output will contain the class labels decided by the classifier (maximal class label = 65535).");
+    SetDescription("Performs a classification of the input vector data according to a model file.");
 
     SetDocName("Vector Classification");
     SetDocAuthors("OTB-Team");
-    SetDocLongDescription("This application performs a vector data classification based on a model file produced by the TrainVectorClassifier application.");
+    SetDocLongDescription("This application performs a vector data classification "
+      "based on a model file produced by the TrainVectorClassifier application."
+      "Features of the vector data output will contain the class labels decided by the classifier "
+      "(maximal class label = 65535). \n"
+      "There are two modes: \n"
+        "1) Update mode: add of the 'cfield' field containing the predicted class in the input file. \n"
+        "2) Write mode: copies the existing fields of the input file in the output file "
+           " and add the 'cfield' field containing the predicted class. \n"
+      "If you have declared the output file, the write mode applies. "
+      "Otherwise, the input file update mode will be applied.");
+
     SetDocLimitations("Shapefiles are supported. But the SQLite format is only supported in update mode.");
     SetDocSeeAlso("TrainVectorClassifier");
     AddDocTag(Tags::Learning);
 
     AddParameter(ParameterType_InputVectorData, "in", "Name of the input vector data");
-    SetParameterDescription("in","The input vector data to classify.");
+    SetParameterDescription("in","The input vector data file to classify.");
 
     AddParameter(ParameterType_InputFilename, "instat", "Statistics file");
     SetParameterDescription("instat", "A XML file containing mean and standard deviation to center"
-      "and reduce samples before classification (produced by ComputeImagesStatistics application).");
+      "and reduce samples before classification, produced by ComputeImagesStatistics application.");
     MandatoryOff("instat");
 
     AddParameter(ParameterType_InputFilename, "model", "Model file");
-    SetParameterDescription("model", "A model file (produced by TrainVectorClassifier application,"
-      "maximal class label = 65535).");
+    SetParameterDescription("model", "Model file produced by TrainVectorClassifier application.");
 
-    AddParameter(ParameterType_String,"cfield","Field containing the predicted class");
+    AddParameter(ParameterType_String,"cfield","Field class");
     SetParameterDescription("cfield","Field containing the predicted class."
-      "Only geometries with this field available will be taken into account.");
+      "Only geometries with this field available will be taken into account.\n"
+      "The field is added either in the input file (if 'out' off) or in the output file.\n"
+      "Caution, the 'cfield' must not exist in the input file if you are updating the file.");
     SetParameterString("cfield","predicted", false);
 
-    AddParameter(ParameterType_ListView, "feat", "Field names to be calculated."); //
-    SetParameterDescription("feat","List of field names in the input vector data used as features for training."); //
+    AddParameter(ParameterType_ListView, "feat", "Field names to be calculated.");
+    SetParameterDescription("feat","List of field names in the input vector data used as features for training. "
+      "Put the same field names as the TrainVectorClassifier application.");
 
     AddParameter(ParameterType_Empty, "confmap",  "Confidence map");
-    SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model : \n"
-      "  - LibSVM : difference between the two highest probabilities (needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n"
+    SetParameterDescription( "confmap", "Confidence map of the produced classification. "
+      "The confidence index depends on the model : \n"
+      "  - LibSVM : difference between the two highest probabilities "
+           "(needs a model with probability estimates, so that classes probabilities can be computed for each sample)\n"
       "  - OpenCV\n"
       "    * Boost : sum of votes\n"
       "    * DecisionTree : (not supported)\n"
@@ -129,8 +142,9 @@ private:
       "    * KNearestNeighbors : number of neighbors with the same label\n"
       "    * NeuralNetwork : difference between the two highest responses\n"
       "    * NormalBayes : (not supported)\n"
-      "    * RandomForest : Confidence (proportion of votes for the majority class). Margin (normalized difference of the votes of the 2 majority classes) is not available for now.\n"
-      "    * SVM : distance to margin (only works for 2-class models)\n");
+      "    * RandomForest : Confidence (proportion of votes for the majority class). "
+             "Margin (normalized difference of the votes of the 2 majority classes) is not available for now.\n"
+      "    * SVM : distance to margin (only works for 2-class models).\n");
     MandatoryOff("confmap");
 
     AddParameter(ParameterType_OutputFilename, "out", "Output vector data file containing class labels");
@@ -142,7 +156,7 @@ private:
     SetDocExampleParameterValue("in", "vectorData.shp");
     SetDocExampleParameterValue("instat", "meanVar.xml");
     SetDocExampleParameterValue("model", "svmModel.svm");
-    SetDocExampleParameterValue("out", "svmModel.svm");
+    SetDocExampleParameterValue("out", "vectorDataLabeledVector.shp");
     SetDocExampleParameterValue("feat", "perimeter  area  width");
     SetDocExampleParameterValue("cfield", "predicted");
 
diff --git a/Modules/Applications/AppClassification/include/otbTrainBoost.txx b/Modules/Applications/AppClassification/include/otbTrainBoost.txx
index 44093ecd5990eb1b8a7fad10ffe9f4c98dc0051d..46cbbbd12560b459c95a3264116ac189b75398fc 100644
--- a/Modules/Applications/AppClassification/include/otbTrainBoost.txx
+++ b/Modules/Applications/AppClassification/include/otbTrainBoost.txx
@@ -39,11 +39,28 @@ namespace Wrapper
     //BoostType
     AddParameter(ParameterType_Choice, "classifier.boost.t", "Boost Type");
     AddChoice("classifier.boost.t.discrete", "Discrete AdaBoost");
-    AddChoice("classifier.boost.t.real", "Real AdaBoost (technique using confidence-rated predictions "
-                                                "and working well with categorical data)");
-    AddChoice("classifier.boost.t.logit", "LogitBoost (technique producing good regression fits)");
-    AddChoice("classifier.boost.t.gentle", "Gentle AdaBoost (technique setting less weight on outlier data points "
-                                               "and, for that reason, being often good with regression data)");
+    SetParameterDescription("classifier.boost.t.discrete",
+      "This procedure trains the classifiers on weighted versions of the training "
+      "sample, giving higher weight to cases that are currently misclassified. "
+      "This is done for a sequence of weighter samples, and then the final "
+      "classifier is defined as a linear combination of the classifier from "
+      "each stage.");
+    AddChoice("classifier.boost.t.real",
+      "Real AdaBoost (technique using confidence-rated predictions "
+      "and working well with categorical data)");
+    SetParameterDescription("classifier.boost.t.real",
+      "Adaptation of the Discrete Adaboost algorithm with Real value");
+    AddChoice("classifier.boost.t.logit",
+      "LogitBoost (technique producing good regression fits)");
+    SetParameterDescription("classifier.boost.t.logit",
+      "This procedure is an adaptive Newton algorithm for fitting an additive "
+      "logistic regression model. Beware it can produce numeric instability.");
+    AddChoice("classifier.boost.t.gentle",
+      "Gentle AdaBoost (technique setting less weight on outlier data points "
+      "and, for that reason, being often good with regression data)");
+    SetParameterDescription("classifier.boost.t.gentle",
+      "A modified version of the Real Adaboost algorithm, using Newton stepping "
+      "rather than exact optimization at each step.");
     SetParameterString("classifier.boost.t", "real", false);
     SetParameterDescription("classifier.boost.t", "Type of Boosting algorithm.");
     //Do not expose SplitCriteria
@@ -54,9 +71,11 @@ namespace Wrapper
     //WeightTrimRate
     AddParameter(ParameterType_Float, "classifier.boost.r", "Weight Trim Rate");
     SetParameterFloat("classifier.boost.r",0.95, false);
-    SetParameterDescription("classifier.boost.r","A threshold between 0 and 1 used to save computational time. "
-                            "Samples with summary weight <= (1 - weight_trim_rate) do not participate in the next iteration of training. "
-                            "Set this parameter to 0 to turn off this functionality.");
+    SetParameterDescription("classifier.boost.r",
+      "A threshold between 0 and 1 used to save computational time. "
+      "Samples with summary weight <= (1 - weight_trim_rate) do not participate in"
+      " the next iteration of training. Set this parameter to 0 to turn off this "
+      "functionality.");
     //MaxDepth : Not sure that this parameter has to be exposed.
     AddParameter(ParameterType_Int, "classifier.boost.m", "Maximum depth of the tree");
     SetParameterInt("classifier.boost.m",1, false);
diff --git a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx
index 3517791928b5d4be87c03d6e7ec72707f29d4525..9803a91a7a8a03f46f9b5bd8443d3d12a112926a 100644
--- a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx
+++ b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.txx
@@ -35,8 +35,8 @@ LearningApplicationBase<TInputValue,TOutputValue>
 {
   AddChoice("classifier.dt", "Decision Tree classifier");
   SetParameterDescription("classifier.dt",
-                          "This group of parameters allows setting Decision Tree classifier parameters. "
-                          "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/decision_trees.html}.");
+    "This group of parameters allows setting Decision Tree classifier parameters. "
+    "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/decision_trees.html}.");
   //MaxDepth
   AddParameter(ParameterType_Int, "classifier.dt.max", "Maximum depth of the tree");
 #ifdef OTB_OPENCV_3
@@ -44,23 +44,25 @@ LearningApplicationBase<TInputValue,TOutputValue>
 #else
   SetParameterInt("classifier.dt.max",65535, false);
 #endif
-  SetParameterDescription(
-      "classifier.dt.max", "The training algorithm attempts to split each node while its depth is smaller than the maximum "
-      "possible depth of the tree. The actual depth may be smaller if the other termination criteria are met, and/or "
-      "if the tree is pruned.");
+  SetParameterDescription("classifier.dt.max",
+   "The training algorithm attempts to split each node while its depth is smaller "
+   "than the maximum possible depth of the tree. The actual depth may be smaller "
+   "if the other termination criteria are met, and/or if the tree is pruned.");
 
   //MinSampleCount
   AddParameter(ParameterType_Int, "classifier.dt.min", "Minimum number of samples in each node");
   SetParameterInt("classifier.dt.min",10, false);
-  SetParameterDescription("classifier.dt.min", "If the number of samples in a node is smaller than this parameter, "
-                          "then this node will not be split.");
+  SetParameterDescription("classifier.dt.min",
+    "If the number of samples in a node is smaller "
+    "than this parameter, then this node will not be split.");
 
   //RegressionAccuracy
   AddParameter(ParameterType_Float, "classifier.dt.ra", "Termination criteria for regression tree");
   SetParameterFloat("classifier.dt.ra",0.01, false);
-  SetParameterDescription("classifier.dt.min", "If all absolute differences between an estimated value in a node "
-                          "and the values of the train samples in this node are smaller than this regression accuracy parameter, "
-                          "then the node will not be split.");
+  SetParameterDescription("classifier.dt.ra",
+    "If all absolute differences between an estimated value in a node "
+    "and the values of the train samples in this node are smaller than this "
+    "regression accuracy parameter, then the node will not be split further.");
 
   //UseSurrogates : don't need to be exposed !
   //AddParameter(ParameterType_Empty, "classifier.dt.sur", "Surrogate splits will be built");
@@ -68,11 +70,12 @@ LearningApplicationBase<TInputValue,TOutputValue>
 
   //MaxCategories
   AddParameter(ParameterType_Int, "classifier.dt.cat",
-               "Cluster possible values of a categorical variable into K <= cat clusters to find a suboptimal split");
+    "Cluster possible values of a categorical variable into K <= cat clusters to find a "
+    "suboptimal split");
   SetParameterInt("classifier.dt.cat",10, false);
-  SetParameterDescription(
-      "classifier.dt.cat",
-      "Cluster possible values of a categorical variable into K <= cat clusters to find a suboptimal split.");
+  SetParameterDescription("classifier.dt.cat",
+      "Cluster possible values of a categorical variable into K <= cat clusters to find a "
+      "suboptimal split.");
 
   //CVFolds
   AddParameter(ParameterType_Int, "classifier.dt.f", "K-fold cross-validations");
@@ -82,18 +85,20 @@ LearningApplicationBase<TInputValue,TOutputValue>
 #else
   SetParameterInt("classifier.dt.f",10, false);
 #endif
-  SetParameterDescription(
-      "classifier.dt.f", "If cv_folds > 1, then it prunes a tree with K-fold cross-validation where K is equal to cv_folds.");
+  SetParameterDescription("classifier.dt.f",
+    "If cv_folds > 1, then it prunes a tree with K-fold cross-validation where K "
+    "is equal to cv_folds.");
 
   //Use1seRule
   AddParameter(ParameterType_Empty, "classifier.dt.r", "Set Use1seRule flag to false");
-  SetParameterDescription(
-      "classifier.dt.r",
-      "If true, then a pruning will be harsher. This will make a tree more compact and more resistant to the training data noise but a bit less accurate.");
+  SetParameterDescription("classifier.dt.r",
+      "If true, then a pruning will be harsher. This will make a tree more compact and more "
+      "resistant to the training data noise but a bit less accurate.");
 
   //TruncatePrunedTree
   AddParameter(ParameterType_Empty, "classifier.dt.t", "Set TruncatePrunedTree flag to false");
-  SetParameterDescription("classifier.dt.t", "If true, then pruned branches are physically removed from the tree.");
+  SetParameterDescription("classifier.dt.t",
+    "If true, then pruned branches are physically removed from the tree.");
 
   //Priors are not exposed.
 
diff --git a/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx b/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx
index 82d5bd8410dad7927c42fdd7a091c63f7e6d930b..18b9f4d39a8926abf645647bec30273d2b98e3b5 100644
--- a/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx
+++ b/Modules/Applications/AppClassification/include/otbTrainLibSVM.txx
@@ -103,7 +103,7 @@ namespace Wrapper
     SetParameterDescription("classifier.libsvm.nu",
         "Cost parameter Nu, in the range 0..1, the larger the value, "
         "the smoother the decision.");
-    
+
     // It seems that it miss a nu parameter for the nu-SVM use. 
     AddParameter(ParameterType_Empty, "classifier.libsvm.opt", "Parameters optimization");
     MandatoryOff("classifier.libsvm.opt");
@@ -120,11 +120,6 @@ namespace Wrapper
         "The distance between feature vectors from the training set and "
         "the fitting hyper-plane must be less than Epsilon. For outliers"
         "the penalty mutliplier is set by C.");
-      // AddParameter(ParameterType_Float, "classifier.libsvm.nu", "Nu");
-      // SetParameterFloat("classifier.libsvm.nu",0.5, false);
-      // SetParameterDescription("classifier.libsvm.nu", 
-      //   "Cost parameter Nu, in the range 0..1, the larger the value, "
-      //   "the smoother the decision.");
       }
   }
 
@@ -214,4 +209,4 @@ namespace Wrapper
 } //end namespace wrapper
 } //end namespace otb
 
-#endif
\ No newline at end of file
+#endif
diff --git a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx
index fb8287c4996640bb745046f0b22955e9d79c15e0..2bcd26f3a7f08dbae692c8e36e75e6713e8bacc8 100644
--- a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx
+++ b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.txx
@@ -36,95 +36,125 @@ LearningApplicationBase<TInputValue,TOutputValue>
 {
   AddChoice("classifier.ann", "Artificial Neural Network classifier");
   SetParameterDescription("classifier.ann",
-                          "This group of parameters allows setting Artificial Neural Network classifier parameters. "
-                          "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/neural_networks.html}.");
+    "This group of parameters allows setting Artificial Neural Network "
+    "classifier parameters. See complete documentation here "
+    "\\url{http://docs.opencv.org/modules/ml/doc/neural_networks.html}.");
 
   //TrainMethod
   AddParameter(ParameterType_Choice, "classifier.ann.t", "Train Method Type");
-  AddChoice("classifier.ann.t.reg", "RPROP algorithm");
   AddChoice("classifier.ann.t.back", "Back-propagation algorithm");
+  SetParameterDescription("classifier.ann.t.back",
+    "Method to compute the gradient of the loss function and adjust weights "
+    "in the network to optimize the result.");
+  AddChoice("classifier.ann.t.reg", "Resilient Back-propagation algorithm");
+  SetParameterDescription("classifier.ann.t.reg",
+    "Almost the same as the Back-prop algorithm exept that it does not "
+    "take into account the magnitude of the partial derivative (coordinate "
+    "of the gradient) but only its sign.");
+
   SetParameterString("classifier.ann.t", "reg", false);
-  SetParameterDescription("classifier.ann.t", "Type of training method for the multilayer perceptron (MLP) neural network.");
+  SetParameterDescription("classifier.ann.t", 
+    "Type of training method for the multilayer perceptron (MLP) neural network.");
 
   //LayerSizes
   //There is no ParameterType_IntList, so i use a ParameterType_StringList and convert it.
   /*std::vector<std::string> layerSizes;
    layerSizes.push_back("100");
    layerSizes.push_back("100"); */
-  AddParameter(ParameterType_StringList, "classifier.ann.sizes", "Number of neurons in each intermediate layer");
+  AddParameter(ParameterType_StringList, "classifier.ann.sizes", 
+    "Number of neurons in each intermediate layer");
   //SetParameterStringList("classifier.ann.sizes", layerSizes);
   SetParameterDescription("classifier.ann.sizes",
-                          "The number of neurons in each intermediate layer (excluding input and output layers).");
+    "The number of neurons in each intermediate layer (excluding input and output layers).");
 
   //ActivateFunction
-  AddParameter(ParameterType_Choice, "classifier.ann.f", "Neuron activation function type");
+  AddParameter(ParameterType_Choice, "classifier.ann.f", 
+    "Neuron activation function type");
   AddChoice("classifier.ann.f.ident", "Identity function");
   AddChoice("classifier.ann.f.sig", "Symmetrical Sigmoid function");
   AddChoice("classifier.ann.f.gau", "Gaussian function (Not completely supported)");
   SetParameterString("classifier.ann.f", "sig", false);
-  SetParameterDescription("classifier.ann.f", "Neuron activation function.");
+  SetParameterDescription("classifier.ann.f", 
+    "This function determine whether the output of the node is positive or not "
+    "depending on the output of the transfert function.");
 
   //Alpha
-  AddParameter(ParameterType_Float, "classifier.ann.a", "Alpha parameter of the activation function");
+  AddParameter(ParameterType_Float, "classifier.ann.a", 
+    "Alpha parameter of the activation function");
   SetParameterFloat("classifier.ann.a",1., false);
   SetParameterDescription("classifier.ann.a",
-                          "Alpha parameter of the activation function (used only with sigmoid and gaussian functions).");
+    "Alpha parameter of the activation function (used only with sigmoid and gaussian functions).");
 
   //Beta
-  AddParameter(ParameterType_Float, "classifier.ann.b", "Beta parameter of the activation function");
+  AddParameter(ParameterType_Float, "classifier.ann.b", 
+    "Beta parameter of the activation function");
   SetParameterFloat("classifier.ann.b",1., false);
   SetParameterDescription("classifier.ann.b",
-                          "Beta parameter of the activation function (used only with sigmoid and gaussian functions).");
+    "Beta parameter of the activation function (used only with sigmoid and gaussian functions).");
 
   //BackPropDWScale
   AddParameter(ParameterType_Float, "classifier.ann.bpdw",
-               "Strength of the weight gradient term in the BACKPROP method");
+    "Strength of the weight gradient term in the BACKPROP method");
   SetParameterFloat("classifier.ann.bpdw",0.1, false);
-  SetParameterDescription(
-      "classifier.ann.bpdw",
-      "Strength of the weight gradient term in the BACKPROP method. The recommended value is about 0.1.");
+  SetParameterDescription("classifier.ann.bpdw",
+    "Strength of the weight gradient term in the BACKPROP method. The "
+    "recommended value is about 0.1.");
 
   //BackPropMomentScale
   AddParameter(ParameterType_Float, "classifier.ann.bpms",
-               "Strength of the momentum term (the difference between weights on the 2 previous iterations)");
+    "Strength of the momentum term (the difference between weights on the 2 previous iterations)");
   SetParameterFloat("classifier.ann.bpms",0.1, false);
-  SetParameterDescription(
-      "classifier.ann.bpms",
-      "Strength of the momentum term (the difference between weights on the 2 previous iterations). "
-      "This parameter provides some inertia to smooth the random fluctuations of the weights. "
-      "It can vary from 0 (the feature is disabled) to 1 and beyond. The value 0.1 or so is good enough.");
+  SetParameterDescription("classifier.ann.bpms",
+    "Strength of the momentum term (the difference between weights on the 2 previous "
+    "iterations). This parameter provides some inertia to smooth the random "
+    "fluctuations of the weights. It can vary from 0 (the feature is disabled) "
+    "to 1 and beyond. The value 0.1 or so is good enough.");
 
   //RegPropDW0
   AddParameter(ParameterType_Float, "classifier.ann.rdw",
-               "Initial value Delta_0 of update-values Delta_{ij} in RPROP method");
+    "Initial value Delta_0 of update-values Delta_{ij} in RPROP method");
   SetParameterFloat("classifier.ann.rdw",0.1, false);
-  SetParameterDescription("classifier.ann.rdw", "Initial value Delta_0 of update-values Delta_{ij} in RPROP method (default = 0.1).");
+  SetParameterDescription("classifier.ann.rdw",
+    "Initial value Delta_0 of update-values Delta_{ij} in RPROP method (default = 0.1).");
 
   //RegPropDWMin
-  AddParameter(ParameterType_Float, "classifier.ann.rdwm", "Update-values lower limit Delta_{min} in RPROP method");
+  AddParameter(ParameterType_Float, "classifier.ann.rdwm",
+    "Update-values lower limit Delta_{min} in RPROP method");
   SetParameterFloat("classifier.ann.rdwm",1e-7, false);
-  SetParameterDescription(
-      "classifier.ann.rdwm",
-      "Update-values lower limit Delta_{min} in RPROP method. It must be positive (default = 1e-7).");
+  SetParameterDescription("classifier.ann.rdwm",
+    "Update-values lower limit Delta_{min} in RPROP method. It must be positive "
+    "(default = 1e-7).");
 
   //TermCriteriaType
   AddParameter(ParameterType_Choice, "classifier.ann.term", "Termination criteria");
   AddChoice("classifier.ann.term.iter", "Maximum number of iterations");
+  SetParameterDescription("classifier.ann.term.iter", 
+    "Set the number of iterations allowed to the network for its "
+    "training. Training will stop regardless of the result when this "
+    "number is reached");
   AddChoice("classifier.ann.term.eps", "Epsilon");
+  SetParameterDescription("classifier.ann.term.eps", 
+    "Training will focus on result and will stop once the precision is"
+    "at most epsilon");
   AddChoice("classifier.ann.term.all", "Max. iterations + Epsilon");
+  SetParameterDescription("classifier.ann.term.all", 
+    "Both termination criteria are used. Training stop at the first reached");
   SetParameterString("classifier.ann.term", "all", false);
   SetParameterDescription("classifier.ann.term", "Termination criteria.");
 
   //Epsilon
-  AddParameter(ParameterType_Float, "classifier.ann.eps", "Epsilon value used in the Termination criteria");
+  AddParameter(ParameterType_Float, "classifier.ann.eps",
+    "Epsilon value used in the Termination criteria");
   SetParameterFloat("classifier.ann.eps",0.01, false);
-  SetParameterDescription("classifier.ann.eps", "Epsilon value used in the Termination criteria.");
+  SetParameterDescription("classifier.ann.eps",
+    "Epsilon value used in the Termination criteria.");
 
   //MaxIter
   AddParameter(ParameterType_Int, "classifier.ann.iter",
-               "Maximum number of iterations used in the Termination criteria");
+    "Maximum number of iterations used in the Termination criteria");
   SetParameterInt("classifier.ann.iter",1000, false);
-  SetParameterDescription("classifier.ann.iter", "Maximum number of iterations used in the Termination criteria.");
+  SetParameterDescription("classifier.ann.iter",
+    "Maximum number of iterations used in the Termination criteria.");
 
 }
 
@@ -143,12 +173,12 @@ LearningApplicationBase<TInputValue,TOutputValue>
 
   switch (GetParameterInt("classifier.ann.t"))
     {
-    case 0: // RPROP
-      classifier->SetTrainMethod(CvANN_MLP_TrainParams::RPROP);
-      break;
-    case 1: // BACKPROP
+    case 0: // BACKPROP
       classifier->SetTrainMethod(CvANN_MLP_TrainParams::BACKPROP);
       break;
+    case 1: // RPROP
+      classifier->SetTrainMethod(CvANN_MLP_TrainParams::RPROP);
+      break;
     default: // DEFAULT = RPROP
       classifier->SetTrainMethod(CvANN_MLP_TrainParams::RPROP);
       break;
diff --git a/Modules/Applications/AppClassification/include/otbTrainSVM.txx b/Modules/Applications/AppClassification/include/otbTrainSVM.txx
index 4c4729e7c5b1cea810941871b6ac37a06ff97aff..ac9524faa26de64a04e4a98b008b101f225cc8ca 100644
--- a/Modules/Applications/AppClassification/include/otbTrainSVM.txx
+++ b/Modules/Applications/AppClassification/include/otbTrainSVM.txx
@@ -53,6 +53,7 @@ namespace Wrapper
       }
     AddParameter(ParameterType_Choice, "classifier.svm.k", "SVM Kernel Type");
     AddChoice("classifier.svm.k.linear", "Linear");
+
     AddChoice("classifier.svm.k.rbf", "Gaussian radial basis function");
     AddChoice("classifier.svm.k.poly", "Polynomial");
     AddChoice("classifier.svm.k.sigmoid", "Sigmoid");
@@ -60,52 +61,71 @@ namespace Wrapper
     SetParameterDescription("classifier.svm.k", "SVM Kernel Type.");
     AddParameter(ParameterType_Float, "classifier.svm.c", "Cost parameter C");
     SetParameterFloat("classifier.svm.c",1.0, false);
-    SetParameterDescription(
-        "classifier.svm.c",
-        "SVM models have a cost parameter C (1 by default) to control the trade-off between training errors and forcing rigid margins.");
+    SetParameterDescription("classifier.svm.c",
+        "SVM models have a cost parameter C (1 by default) to control the trade-off"
+        " between training errors and forcing rigid margins.");
     AddParameter(ParameterType_Float, "classifier.svm.nu",
                  "Parameter nu of a SVM optimization problem (NU_SVC / ONE_CLASS)");
     SetParameterFloat("classifier.svm.nu",0.0, false);
-    SetParameterDescription("classifier.svm.nu", "Parameter nu of a SVM optimization problem.");
+    SetParameterDescription("classifier.svm.nu", 
+      "Parameter nu of a SVM optimization problem.");
     if (this->m_RegressionFlag)
       {
       AddParameter(ParameterType_Float, "classifier.svm.p", "Parameter epsilon of a SVM optimization problem (EPS_SVR)");
       SetParameterFloat("classifier.svm.p",1.0, false);
       SetParameterDescription("classifier.svm.p", "Parameter epsilon of a SVM optimization problem (EPS_SVR).");
 
-      AddParameter(ParameterType_Choice, "classifier.svm.term", "Termination criteria");
-      SetParameterDescription("classifier.svm.term","Termination criteria for iterative algorithm");
-      AddChoice("classifier.svm.term.iter", "Stops when maximum iteration is reached.");
-      AddChoice("classifier.svm.term.eps", "Stops when accuracy is lower than epsilon.");
-      AddChoice("classifier.svm.term.all", "Stops when either iteration or epsilon criteria is true");
+      AddParameter(ParameterType_Choice, 
+        "classifier.svm.term", "Termination criteria");
+      SetParameterDescription("classifier.svm.term",
+        "Termination criteria for iterative algorithm");
+      AddChoice("classifier.svm.term.iter", 
+        "Stops when maximum iteration is reached.");
+      AddChoice("classifier.svm.term.eps", 
+        "Stops when accuracy is lower than epsilon.");
+      AddChoice("classifier.svm.term.all", 
+        "Stops when either iteration or epsilon criteria is true");
 
       AddParameter(ParameterType_Float, "classifier.svm.iter", "Maximum iteration");
       SetParameterFloat("classifier.svm.iter",1000, false);
-      SetParameterDescription("classifier.svm.iter", "Maximum number of iterations (corresponds to the termination criteria 'iter').");
+      SetParameterDescription("classifier.svm.iter", 
+        "Maximum number of iterations (corresponds to the termination criteria 'iter').");
 
-      AddParameter(ParameterType_Float, "classifier.svm.eps", "Epsilon accuracy threshold");
+      AddParameter(ParameterType_Float, "classifier.svm.eps", 
+        "Epsilon accuracy threshold");
       SetParameterFloat("classifier.svm.eps",FLT_EPSILON, false);
-      SetParameterDescription("classifier.svm.eps", "Epsilon accuracy (corresponds to the termination criteria 'eps').");
+      SetParameterDescription("classifier.svm.eps", 
+        "Epsilon accuracy (corresponds to the termination criteria 'eps').");
       }
-    AddParameter(ParameterType_Float, "classifier.svm.coef0", "Parameter coef0 of a kernel function (POLY / SIGMOID)");
+    AddParameter(ParameterType_Float, "classifier.svm.coef0", 
+      "Parameter coef0 of a kernel function (POLY / SIGMOID)");
     SetParameterFloat("classifier.svm.coef0",0.0, false);
-    SetParameterDescription("classifier.svm.coef0", "Parameter coef0 of a kernel function (POLY / SIGMOID).");
+    SetParameterDescription("classifier.svm.coef0", 
+      "Parameter coef0 of a kernel function (POLY / SIGMOID).");
     AddParameter(ParameterType_Float, "classifier.svm.gamma",
                  "Parameter gamma of a kernel function (POLY / RBF / SIGMOID)");
     SetParameterFloat("classifier.svm.gamma",1.0, false);
-    SetParameterDescription("classifier.svm.gamma", "Parameter gamma of a kernel function (POLY / RBF / SIGMOID).");
-    AddParameter(ParameterType_Float, "classifier.svm.degree", "Parameter degree of a kernel function (POLY)");
+    SetParameterDescription("classifier.svm.gamma", 
+      "Parameter gamma of a kernel function (POLY / RBF / SIGMOID).");
+    AddParameter(ParameterType_Float, "classifier.svm.degree", 
+      "Parameter degree of a kernel function (POLY)");
     SetParameterFloat("classifier.svm.degree",1.0, false);
-    SetParameterDescription("classifier.svm.degree", "Parameter degree of a kernel function (POLY).");
-    AddParameter(ParameterType_Empty, "classifier.svm.opt", "Parameters optimization");
+    SetParameterDescription("classifier.svm.degree", 
+      "Parameter degree of a kernel function (POLY).");
+    AddParameter(ParameterType_Empty, "classifier.svm.opt", 
+      "Parameters optimization");
     MandatoryOff("classifier.svm.opt");
-    SetParameterDescription("classifier.svm.opt", "SVM parameters optimization flag.\n-If set to True, then the optimal SVM parameters will be estimated. "
-                            "Parameters are considered optimal by OpenCV when the cross-validation estimate of the test set error is minimal. "
-                            "Finally, the SVM training process is computed 10 times with these optimal parameters over subsets corresponding to 1/10th of "
-                            "the training samples using the k-fold cross-validation (with k = 10).\n-If set to False, the SVM classification process will be "
-                            "computed once with the currently set input SVM parameters over the training samples.\n-Thus, even with identical input SVM "
-                            "parameters and a similar random seed, the output SVM models will be different according to the method used (optimized or not) "
-                            "because the samples are not identically processed within OpenCV.");
+    SetParameterDescription("classifier.svm.opt", "SVM parameters optimization flag.\n"
+      "-If set to True, then the optimal SVM parameters will be estimated. "
+      "Parameters are considered optimal by OpenCV when the cross-validation estimate of "
+      "the test set error is minimal. Finally, the SVM training process is computed "
+      "10 times with these optimal parameters over subsets corresponding to 1/10th of "
+      "the training samples using the k-fold cross-validation (with k = 10).\n-If set "
+      "to False, the SVM classification process will be computed once with the "
+      "currently set input SVM parameters over the training samples.\n-Thus, even "
+      "with identical input SVM parameters and a similar random seed, the output "
+      "SVM models will be different according to the method used (optimized or not) "
+      "because the samples are not identically processed within OpenCV.");
   }
 
   template <class TInputValue, class TOutputValue>
diff --git a/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx b/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx
index e24c4165de2b6a1b1bf57c672e5ec69a1ef825a2..2c3575c2ead20381438f9f66d5cd9c65c1723132 100644
--- a/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx
+++ b/Modules/Applications/AppClassification/include/otbTrainVectorBase.txx
@@ -31,54 +31,70 @@ void TrainVectorBase::DoInit()
 {
   // Common Parameters for all Learning Application
   AddParameter( ParameterType_Group, "io", "Input and output data" );
-  SetParameterDescription( "io", "This group of parameters allows setting input and output data." );
+  SetParameterDescription( "io", 
+    "This group of parameters allows setting input and output data." );
 
   AddParameter( ParameterType_InputVectorDataList, "io.vd", "Input Vector Data" );
   SetParameterDescription( "io.vd",
-                           "Input geometries used for training (note : all geometries from the layer will be used)" );
+    "Input geometries used for training (note : all geometries from the layer will be used)" );
 
   AddParameter( ParameterType_InputFilename, "io.stats", "Input XML image statistics file" );
   MandatoryOff( "io.stats" );
-  SetParameterDescription( "io.stats", "XML file containing mean and variance of each feature." );
+  SetParameterDescription( "io.stats", 
+    "XML file containing mean and variance of each feature." );
 
   AddParameter( ParameterType_OutputFilename, "io.out", "Output model" );
-  SetParameterDescription( "io.out", "Output file containing the model estimated (.txt format)." );
+  SetParameterDescription( "io.out", 
+    "Output file containing the model estimated (.txt format)." );
 
   AddParameter( ParameterType_Int, "layer", "Layer Index" );
-  SetParameterDescription( "layer", "Index of the layer to use in the input vector file." );
+  SetParameterDescription( "layer", 
+    "Index of the layer to use in the input vector file." );
   MandatoryOff( "layer" );
   SetDefaultParameterInt( "layer", 0 );
 
   AddParameter(ParameterType_ListView,  "feat", "Field names for training features.");
-  SetParameterDescription("feat","List of field names in the input vector data to be used as features for training.");
+  SetParameterDescription("feat",
+    "List of field names in the input vector data to be used as features for training.");
 
   // Add validation data used to compute confusion matrix or contingency table
   AddParameter( ParameterType_Group, "valid", "Validation data" );
-  SetParameterDescription( "valid", "This group of parameters defines validation data." );
+  SetParameterDescription( "valid", 
+    "This group of parameters defines validation data." );
 
-  AddParameter( ParameterType_InputVectorDataList, "valid.vd", "Validation Vector Data" );
+  AddParameter( ParameterType_InputVectorDataList, "valid.vd", 
+    "Validation Vector Data" );
   SetParameterDescription( "valid.vd", "Geometries used for validation "
           "(must contain the same fields used for training, all geometries from the layer will be used)" );
   MandatoryOff( "valid.vd" );
 
   AddParameter( ParameterType_Int, "valid.layer", "Layer Index" );
-  SetParameterDescription( "valid.layer", "Index of the layer to use in the validation vector file." );
+  SetParameterDescription( "valid.layer", 
+    "Index of the layer to use in the validation vector file." );
   MandatoryOff( "valid.layer" );
   SetDefaultParameterInt( "valid.layer", 0 );
 
   // Add class field if we used validation
-  AddParameter( ParameterType_ListView, "cfield", "Field containing the class integer label for supervision" );
-  SetParameterDescription( "cfield", "Field containing the class id for supervision. "
-          "The values in this field shall be cast into integers. "
-          "Only geometries with this field available will be taken into account." );
+  AddParameter( ParameterType_ListView, "cfield",
+    "Field containing the class integer label for supervision" );
+  SetParameterDescription( "cfield", 
+    "Field containing the class id for supervision. "
+    "The values in this field shall be cast into integers. "
+    "Only geometries with this field available will be taken into account." );
   SetListViewSingleSelectionMode( "cfield", true );
 
   // Add a new parameter to compute confusion matrix / contingency table
-  AddParameter( ParameterType_OutputFilename, "io.confmatout", "Output confusion matrix or contingency table" );
-  SetParameterDescription( "io.confmatout", "Output file containing the confusion matrix or contingency table (.csv format)."
-          "The contingency table is output when we unsupervised algorithms is used otherwise the confusion matrix is output." );
+  AddParameter( ParameterType_OutputFilename, "io.confmatout", 
+    "Output confusion matrix or contingency table" );
+  SetParameterDescription( "io.confmatout", 
+    "Output file containing the confusion matrix or contingency table (.csv format)."
+    "The contingency table is output when we unsupervised algorithms is used otherwise the confusion matrix is output." );
   MandatoryOff( "io.confmatout" );
 
+  AddParameter(ParameterType_Empty, "v", "Verbose mode");
+  EnableParameter("v");
+  SetParameterDescription("v", "Verbose mode, display the contingency table result.");
+  MandatoryOff("v");
 
   // Doc example parameter settings
   SetDocExampleParameterValue( "io.vd", "vectorData.shp" );
@@ -273,7 +289,7 @@ TrainVectorBase::ExtractSamplesWithLabel(std::string parameterName, std::string
 
         input->PushBack( mv );
 
-        if( feature.ogr().IsFieldSet( cFieldIndex ) && cFieldIndex != -1 )
+        if(cFieldIndex>=0 && ogr::Field(feature,cFieldIndex).HasBeenSet())
           target->PushBack( feature.ogr().GetFieldAsInteger( cFieldIndex ) );
         else
           target->PushBack( 0 );
diff --git a/Modules/Applications/AppClassification/otb-module.cmake b/Modules/Applications/AppClassification/otb-module.cmake
index ca0c9281275d233b7dcb441d667fb295d5580755..efd9cb32d789831e5b673f398ea2af866cf29503 100644
--- a/Modules/Applications/AppClassification/otb-module.cmake
+++ b/Modules/Applications/AppClassification/otb-module.cmake
@@ -53,6 +53,7 @@ otb_module(OTBAppClassification
   TEST_DEPENDS
     OTBTestKernel
     OTBCommandLine
+    OTBAppProjection
 
   DESCRIPTION
     "${DOCUMENTATION}"
diff --git a/Modules/Applications/AppClassification/test/CMakeLists.txt b/Modules/Applications/AppClassification/test/CMakeLists.txt
index aa7e33d744d5eda1191e327bcc5ea8afe13da102..fae1474266db959a03a6accd01b14b43f00f4ec0 100644
--- a/Modules/Applications/AppClassification/test/CMakeLists.txt
+++ b/Modules/Applications/AppClassification/test/CMakeLists.txt
@@ -629,20 +629,24 @@ if(OTB_DATA_USE_LARGEINPUT)
 endif()
 
 #----------- KMeansClassification TESTS ----------------
-otb_test_application(NAME apTvClKMeansImageClassification
-  APP  KMeansClassification
-  OPTIONS -in ${INPUTDATA}/qb_RoadExtract.img
-  -vm ${INPUTDATA}/qb_RoadExtract_mask.png
-  -ts 30000
-  -nc 5
-  -maxit 10000
-  -ct 0.0000001
-  -rand 121212
-  -out ${TEMP}/apTvClKMeansImageClassificationFilterOutput.tif
-  VALID   --compare-image ${NOTOL}
-  ${OTBAPP_BASELINE}/apTvClKMeansImageClassificationFilterOutput.tif
-  ${TEMP}/apTvClKMeansImageClassificationFilterOutput.tif )
-
+if(OTB_USE_SHARK)
+  otb_test_application(NAME apTvClKMeansImageClassification_composite
+    APP  KMeansClassification
+    OPTIONS -in ${INPUTDATA}/qb_RoadExtract.img
+    -vm ${INPUTDATA}/qb_RoadExtract_mask_binary.png
+    -ts 30000
+    -nc 5
+    -maxit 10000
+    -sampler periodic
+    -rand 121212
+    -nodatalabel 255
+    -outmeans ${TEMP}/apTvClKMeansImageClassificationFilterOutMeans.txt
+    -out ${TEMP}/apTvClKMeansImageClassificationFilterOutput.tif uint8
+    -cleanup 0
+    VALID   --compare-image ${NOTOL}
+    ${OTBAPP_BASELINE}/apTvClKMeansImageClassificationFilterOutput.tif
+    ${TEMP}/apTvClKMeansImageClassificationFilterOutput.tif )
+endif()
 
 #----------- TrainImagesClassifier TESTS ----------------
 if(OTB_USE_LIBSVM)
diff --git a/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx b/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
index c4bcb9841cc0e87bcc760520165ef7913a27c5e9..a608338ddefab721dc1c8b0a4f0f0b6f035f8c49 100644
--- a/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
+++ b/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
@@ -64,11 +64,16 @@ private:
 void DoInit() ITK_OVERRIDE
 {
 SetName("EdgeExtraction");
-SetDescription("Computes edge features on every pixel of the input image selected channel");
+SetDescription(
+  "This application computes edge features on every pixel of the input image "
+  "selected channel");
 
 // Documentation
 SetDocName("Edge Feature Extraction");
-SetDocLongDescription("This application computes edge features on a mono band image");
+SetDocLongDescription(
+  "This application computes edge features on a selected channel of the input."
+  "It uses different filter such as gradient, Sobel and Touzi");
+
 SetDocLimitations("None");
 SetDocAuthors("OTB-Team");
 SetDocSeeAlso("otb class");
@@ -77,7 +82,7 @@ AddDocTag(Tags::FeatureExtraction);
 AddDocTag("Edge");
 
 AddParameter(ParameterType_InputImage, "in",  "Input Image");
-SetParameterDescription("in", "The input image to compute the features on.");
+SetParameterDescription("in", "The input image on which the features are computed.");
 
 AddParameter(ParameterType_Int,  "channel",  "Selected Channel");
 SetParameterDescription("channel", "The selected channel index");
@@ -91,15 +96,26 @@ SetParameterDescription("filter", "Choice of edge feature");
 
 //Gradient Section
 AddChoice("filter.gradient", "Gradient");
+SetParameterDescription("filter.gradient", 
+  "This filter computes the gradient magnitude of the image at each pixel.");
 
 //Sobel Section
 AddChoice("filter.sobel", "Sobel");
+SetParameterDescription("filter.sobel", 
+  "This filter uses the Sobel operator to calculate the image gradient and "
+  "then finds the magnitude of this gradient vector.");
 
 //Touzi Section
 AddChoice("filter.touzi", "Touzi");
-AddParameter(ParameterType_Int, "filter.touzi.xradius", "The X Radius");
+SetParameterDescription("filter.touzi", 
+  "This filter is more suited for radar images. It has a spatial parameter "
+  "to avoid speckle noise perturbations. The larger the radius is, "
+  "less sensible to the speckle noise the filter is, but micro edge will be missed.");
+AddParameter(ParameterType_Int, "filter.touzi.xradius", 
+  "The X radius of the neighborhood.");
 SetDefaultParameterInt("filter.touzi.xradius", 1);
-AddParameter(ParameterType_Int, "filter.touzi.yradius", "The Y Radius");
+AddParameter(ParameterType_Int, "filter.touzi.yradius", 
+  "The Y radius of the neighborhood.");
 SetDefaultParameterInt("filter.touzi.yradius", 1);
 
 //Canny Section
diff --git a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx
index 65eb71689cf5a51cb89610765d5a7b427cc44f6b..b9eccc12eb2f02004ffe1f2156ebd65bdb55d53f 100644
--- a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx
+++ b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx
@@ -60,10 +60,19 @@ private:
 
     // Documentation
     SetDocName("Line segment detection");
-    SetDocLongDescription("This application detects locally straight contours in a image. It is based on Burns, Hanson, and Riseman method and use an a contrario validation approach (Desolneux, Moisan, and Morel). The algorithm was published by Rafael Gromponevon Gioi, Jérémie Jakubowicz, Jean-Michel Morel and Gregory Randall.\n The given approach computes gradient and level lines of the image and detects aligned points in line support region. The application allows exporting the detected lines in a vector data.");
+    SetDocLongDescription(
+      "This application detects locally straight contours in a image."
+      " It is based on Burns, Hanson, and Riseman method and use an a contrario "
+      "validation approach (Desolneux, Moisan, and Morel). The algorithm was published "
+      "by Rafael Gromponevon Gioi, Jérémie Jakubowicz, Jean-Michel Morel and "
+      "Gregory Randall. The given approach computes gradient and level lines of the "
+      "image and detects aligned points in line support region. "
+      "The application allows exporting the detected lines in a vector data.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("On Line demonstration of the LSD algorithm is available here: http://www.ipol.im/pub/algo/gjmr_line_segment_detector/\n");
+    SetDocSeeAlso(
+      "On Line demonstration of the LSD algorithm is available here: "
+      "http://www.ipol.im/pub/algo/gjmr_line_segment_detector/\n");
 
     AddDocTag(Tags::FeatureExtraction);
 
@@ -77,7 +86,9 @@ private:
     ElevationParametersHandler::AddElevationParameters(this, "elev");
 
     AddParameter(ParameterType_Empty, "norescale", "No rescaling in [0, 255]");
-    SetParameterDescription("norescale","By default, the input image amplitude is rescaled between [0,255]. Turn on this parameter to skip rescaling");
+    SetParameterDescription("norescale",
+      "By default, the input image amplitude is rescaled between [0,255]."
+      " Turn on this parameter to skip rescaling");
     MandatoryOff("norescale");
 
     AddRAMParameter();
diff --git a/Modules/Applications/AppFiltering/app/CMakeLists.txt b/Modules/Applications/AppFiltering/app/CMakeLists.txt
index 9d58ba674f60c2fcc463948685f54a9a496b3429..d7f3dcd0c3c1ce9a06b5b50bc3d4293d9e4adbcc 100644
--- a/Modules/Applications/AppFiltering/app/CMakeLists.txt
+++ b/Modules/Applications/AppFiltering/app/CMakeLists.txt
@@ -19,17 +19,11 @@
 #
 
 set(OTBAppFiltering_LINK_LIBS
-  ${OTBImageNoise_LIBRARIES}
   ${OTBImageManipulation_LIBRARIES}
   ${OTBApplicationEngine_LIBRARIES}
   ${OTBImageBase_LIBRARIES}
 )
 
-otb_create_application(
-  NAME           Despeckle
-  SOURCES        otbDespeckle.cxx
-  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
-
 otb_create_application(
   NAME           Smoothing
   SOURCES        otbSmoothing.cxx
diff --git a/Modules/Applications/AppFiltering/otb-module.cmake b/Modules/Applications/AppFiltering/otb-module.cmake
index d33a9eec90a461aadf2223cf63e60eaa5b10c4ff..5e8fc45196bb23ef0d7e19e6c062b7d7a5d3a5a2 100644
--- a/Modules/Applications/AppFiltering/otb-module.cmake
+++ b/Modules/Applications/AppFiltering/otb-module.cmake
@@ -18,11 +18,10 @@
 # limitations under the License.
 #
 
-set(DOCUMENTATION "Basic filters application.")
+set(DOCUMENTATION "Image filtering application.")
 
 otb_module(OTBAppFiltering
   DEPENDS
-    OTBImageNoise
     OTBImageManipulation
     OTBITK
     OTBApplicationEngine
diff --git a/Modules/Applications/AppFiltering/test/CMakeLists.txt b/Modules/Applications/AppFiltering/test/CMakeLists.txt
index f88934a0c03ebb59f837240e7482344f8254f3e0..9c4a8026882033f886e31cc4d222c21945eb3f1c 100644
--- a/Modules/Applications/AppFiltering/test/CMakeLists.txt
+++ b/Modules/Applications/AppFiltering/test/CMakeLists.txt
@@ -19,8 +19,6 @@
 #
 
 otb_module_test()
-#----------- Despeckle TESTS ----------------
-
 #----------- Smoothing TESTS ----------------
 otb_test_application(NAME  apTvUtSmoothingTest_InXML
                      APP  Smoothing
@@ -52,46 +50,4 @@ otb_test_application(NAME  apTvUtSmoothingTest_OutXML
                              ${TEMP}/apTvUtSmoothingTest_OutXML.tif)
                              
                              
-otb_test_application(NAME  apTvDespeckleLee
-                     APP  Despeckle
-                     OPTIONS -in ${INPUTDATA}/GomaAvant.tif
-               	             -out ${TEMP}/bfFiltreLee_05_05_12_app.tif
-                             -filter lee
-                             -filter.lee.rad 5
-                             -filter.lee.nblooks 12
-                     VALID   --compare-image ${EPSILON_7}
-                             ${BASELINE}/bfFiltreLee_05_05_12.tif
-                             ${TEMP}/bfFiltreLee_05_05_12_app.tif)
-                             
-otb_test_application(NAME  apTvDespeckleFrost
-                     APP  Despeckle
-                     OPTIONS -in ${INPUTDATA}/GomaAvant.tif
-               	             -out ${TEMP}/bfFiltreFrost_05_05_12_app.tif
-                             -filter frost
-                             -filter.frost.rad 5
-                             -filter.frost.deramp 0.1
-                     VALID   --compare-image ${EPSILON_7}
-                             ${BASELINE}/bfFiltreFrost_05_05_12_app.tif
-                             ${TEMP}/bfFiltreFrost_05_05_12_app.tif)
 
-otb_test_application(NAME  apTvDespeckleGammaMAP
-                     APP  Despeckle
-                     OPTIONS -in ${INPUTDATA}/GomaAvant.tif
-               	             -out ${TEMP}/bfFiltreGammaMAP_05_05_12_app.tif
-                             -filter gammamap
-                             -filter.gammamap.rad 5
-                             -filter.gammamap.nblooks 12
-                     VALID   --compare-image ${EPSILON_7}
-                             ${BASELINE}/bfFiltreGammaMAP_05_05_12.tif
-                             ${TEMP}/bfFiltreGammaMAP_05_05_12_app.tif)                      
-                             
-otb_test_application(NAME  apTvDespeckleKuan
-                     APP  Despeckle
-                     OPTIONS -in ${INPUTDATA}/GomaAvant.tif
-               	             -out ${TEMP}/bfFiltreKuan_05_05_12_app.tif
-                             -filter kuan
-                             -filter.kuan.rad 5
-                             -filter.kuan.nblooks 12
-                     VALID   --compare-image ${EPSILON_7}
-                             ${BASELINE}/bfFiltreKuan_05_05_12.tif
-                             ${TEMP}/bfFiltreKuan_05_05_12_app.tif)
diff --git a/Modules/Applications/AppFusion/app/CMakeLists.txt b/Modules/Applications/AppFusion/app/CMakeLists.txt
index a75c4ca00da7b4805a004aea9757694f8a1f2903..1e7a0eb91559fd30e65a87870e8af08f661c6307 100644
--- a/Modules/Applications/AppFusion/app/CMakeLists.txt
+++ b/Modules/Applications/AppFusion/app/CMakeLists.txt
@@ -35,3 +35,6 @@ otb_create_application(
   NAME           Pansharpening
   SOURCES        otbPansharpening.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
+# Mantis-1427 : temporary fix
+add_dependencies(${otb-module}-all otbapp_Superimpose)
diff --git a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx
index a16a00b234aae826d1df74d828868b7c40ec99ef..3ed9b7c18996e89e4be9c11a0e942a334d4e0077 100644
--- a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx
+++ b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx
@@ -95,22 +95,37 @@ private:
 
     // Documentation
     SetDocName("Hyperspectral data unmixing");
-    SetDocLongDescription("The application applies a linear unmixing algorithm to an hyperspectral data cube. This method supposes that the mixture between materials in the scene is macroscopic and simulates a linear mixing model of spectra.\nThe Linear Mixing Model (LMM) acknowledges that reflectance spectrum associated with each pixel is a linear combination of pure materials in the recovery area, commonly known as endmembers. Endmembers can be estimated using the VertexComponentAnalysis application.\nThe application allows one to estimate the abundance maps with several algorithms : Unconstrained Least Square (ucls), Fully Constrained Least Square (fcls), Image Space Reconstruction Algorithm (isra) and Non-negative constrained Least Square (ncls) and Minimum Dispersion Constrained Non Negative Matrix Factorization (MDMDNMF).\n");
+    SetDocLongDescription("The application applies a linear unmixing algorithm"
+    "to an hyperspectral data cube. This method supposes that the mixture between"
+    "aterials in the scene is macroscopic and simulates a linear mixing model of"
+    "spectra.\n\n"
+    "The Linear Mixing Model (LMM) acknowledges that reflectance"
+    "spectrum associated with each pixel is a linear combination of pure"
+    "materials in the recovery area, commonly known as endmembers. Endmembers can"
+    "be estimated using the VertexComponentAnalysis application.\n\n"
+    "The application allows to estimate the abundance maps with several algorithms :\n"
+    "  * Unconstrained Least Square (ucls)\n"
+                          //"  * Fully Constrained Least Square (fcls)\n"
+    "  * Image Space Reconstruction Algorithm (isra)\n"
+    "  * Non-negative constrained\n"
+    "  * Least Square (ncls)\n"
+    "  * Minimum Dispersion Constrained Non Negative Matrix Factorization (MDMDNMF)."
+    );
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("VertexComponentAnalysis");
 
-	AddDocTag("Miscellaneous");
+    AddDocTag("Miscellaneous");
     AddDocTag(Tags::Hyperspectral);
 
     AddParameter(ParameterType_InputImage,  "in",   "Input Image Filename");
-    SetParameterDescription("in","The hyperspectral data cube to unmix");
+    SetParameterDescription("in","The hyperspectral data cube input");
 
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
-    SetParameterDescription("out","The output abundance map");
+    SetParameterDescription("out","The output abundance map. The abundance fraction are stored in a multispectral image where band N corresponds to the fraction of endmembers N in each pixel.");
 
     AddParameter(ParameterType_InputImage,  "ie",   "Input endmembers");
-    SetParameterDescription("ie","The endmembers (estimated pure pixels) to use for unmixing. Must be stored as a multispectral image, where each pixel is interpreted as an endmember");
+    SetParameterDescription("ie","The endmembers (estimated pure pixels) to use for unmixing. Must be stored as a multispectral image, where each pixel is interpreted as an endmember.");
 
     AddParameter(ParameterType_Choice, "ua", "Unmixing algorithm");
     SetParameterDescription("ua", "The algorithm to use for unmixing");
diff --git a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
index b7a4110b39cccfdef8838cf1d345e94f58414bfb..1f0221e665a2291577f3d8ba4cb316624647148d 100644
--- a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
@@ -20,12 +20,13 @@
 
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
-
 #include "otbMultiChannelExtractROI.h"
 #include "otbStandardFilterWatcher.h"
 #include "otbWrapperNumericalParameter.h"
 #include "otbWrapperListViewParameter.h"
 #include "otbWrapperTypes.h"
+#include "otbOGRDataSourceToLabelImageFilter.h"
+#include <algorithm> 
 
 #include "otbWrapperElevationParametersHandler.h"
 
@@ -55,42 +56,146 @@ public:
 
   /** Filters typedef */
   typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType,
-                                      FloatVectorImageType::InternalPixelType> ExtractROIFilterType;
+                                      FloatVectorImageType::InternalPixelType> 
+                                      ExtractROIFilterType;
+
+  typedef ExtractROIFilterType::InputImageType ImageType;
 
 private:
-  void DoInit() ITK_OVERRIDE
+  void 
+  DoInit() ITK_OVERRIDE
   {
     SetName("ExtractROI");
     SetDescription("Extract a ROI defined by the user.");
 
     // Documentation
     SetDocName("Extract ROI");
-    SetDocLongDescription("This application extracts a Region Of Interest with user defined size, or reference image.");
+    SetDocLongDescription("This application extracts a Region Of Interest with "
+      "user parameters. There are four mode of extraction. The standard mode "
+      "allows the user to enter one point (upper left corner of the region to "
+      "extract) and a size. The extent mode needs two points (upper left "
+      "corner and lower right) and the radius mode need the center of the "
+      "region and the radius : it will extract the rectangle containing the "
+      "circle defined and limited by the image dimension. The fit mode "
+      "needs a reference image or vector and the dimension of the extracted "
+      "region will be the same as the extent of the reference. "
+      "Different units are available such as pixel, image physical space "
+      "or longitude and latitude.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
 
     AddDocTag(Tags::Manip);
 
+    // Set parameter input
     AddParameter(ParameterType_InputImage,  "in",   "Input Image");
-    SetParameterDescription("in", "Input image.");
+    SetParameterDescription("in", "Image to be processed.");
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
-    SetParameterDescription("out", "Output image.");
+    SetParameterDescription("out", "Region of interest from the input image");
 
-    AddRAMParameter();
 
     AddParameter(ParameterType_Choice,"mode","Extraction mode");
     AddChoice("mode.standard","Standard");
-    SetParameterDescription("mode.standard","In standard mode, extract is done according the coordinates entered by the user");
-    AddChoice("mode.fit","Fit");
-    SetParameterDescription("mode.fit","In fit mode, extract is made to best fit a reference image.");
-
-    AddParameter(ParameterType_InputImage,"mode.fit.ref","Reference image");
-    SetParameterDescription("mode.fit.ref","Reference image to define the ROI");
-
-    // Elevation
-    ElevationParametersHandler::AddElevationParameters(this,"mode.fit.elev");
+    SetParameterDescription("mode.standard",
+      "In standard mode extraction is done with 2 parameters : the "
+      "upper left corner and the size of the region, decomposed "
+      "in X and Y coordinates.");
 
+    // Fit mode : the ROI is computed through a ref vector dataset or a ref image 
+    AddChoice("mode.fit","Fit");
+    SetParameterDescription("mode.fit",
+      "In fit mode, extract is made from a reference : image or vector dataset.");
+
+    AddParameter( ParameterType_InputImage , "mode.fit.im" , 
+      "Reference image" );
+    SetParameterDescription( "mode.fit.im" ,
+      "Reference image to define the ROI" );
+    AddParameter( ParameterType_InputVectorData , "mode.fit.vect" , 
+                  "Reference vector" );
+    SetParameterDescription( "mode.fit.vect" ,
+      "The extent of the input vector file is computed and then "
+      "gives a region of interest that will be extracted." );
+
+    // Extent mode : ROI is computed with two point (upper left and lower left corners)
+    AddChoice( "mode.extent" , "Extent" );
+    SetParameterDescription( "mode.extent" ,
+      "In extent mode, the ROI is defined by two points, the upper left corner "
+      "and the lower right corner, decomposed in 2 coordinates : "
+      "X and Y. The unit for those coordinates can be set." );
+    AddParameter( ParameterType_Float , "mode.extent.ulx" ,
+                  "X coordinate of the Upper left corner" );
+    SetParameterDescription( "mode.extent.ulx" ,
+      "X coordinate of upper left corner point." );
+    AddParameter( ParameterType_Float , "mode.extent.uly" ,
+                  "Y coordinate of Upper Left corner point." );
+    SetParameterDescription( "mode.extent.uly" ,
+      "Y coordinate of upper left corner point." );
+    AddParameter( ParameterType_Float , "mode.extent.lrx" , 
+                  "X coordinate of Lower Right corner point." );
+    SetParameterDescription( "mode.extent.lrx" ,
+      "X coordinate of lower right corner point." );
+    AddParameter( ParameterType_Float , "mode.extent.lry" ,
+                  "Y coordinate of Lower Right corner point." );
+    SetParameterDescription( "mode.extent.lry" ,
+      "Y coordinate of lower right corner point." );
+    // Unit of extent mode
+    AddParameter( ParameterType_Choice , "mode.extent.unit" , "Unit" );
+    AddChoice( "mode.extent.unit.pxl" , "Pixel" );
+    SetParameterDescription("mode.extent.unit.pxl",
+      "The unit for the parameters coordinates will be the pixel, meaning the "
+      "index of the two points.");
+    AddChoice( "mode.extent.unit.phy" , "Image physical space" );
+    SetParameterDescription("mode.extent.unit.phy",
+      "The unit for the parameters coordinates will be the physical "
+      "measure of the image.");
+    AddChoice( "mode.extent.unit.lonlat" , "Longitude and latitude" );
+    SetParameterDescription("mode.extent.unit.lonlat",
+      "The unit for the parameters coordinates will be the longitude and "
+      "the latitude.");
+
+
+    // Radius mode : ROI is computed through a point and a radius
+    AddChoice( "mode.radius" , "Radius" );
+    SetParameterDescription( "mode.radius" ,
+      "In radius mode, the ROI is defined by a point and a radius. The "
+      "unit of those two parameters can be chosen independently." );
+
+    AddParameter( ParameterType_Float , "mode.radius.r" , "Radius" );
+    SetParameterDescription( "mode.radius.r" ,
+      "This is the radius parameter of the radius mode." );
+    AddParameter( ParameterType_Choice , "mode.radius.unitr" , "Radius unit" );
+    AddChoice( "mode.radius.unitr.pxl" , "Pixel" );
+    SetParameterDescription("mode.radius.unitr.pxl",
+      "The unit of the radius will be the pixel.");
+    AddChoice( "mode.radius.unitr.phy" , "Image physical space" );
+    SetParameterDescription("mode.radius.unitr.phy",
+      "The unit of the radius will be the physical measure of the image.");
+
+    AddParameter( ParameterType_Float , "mode.radius.cx" ,
+                  "X coordinate of the center" );
+    SetParameterDescription( "mode.radius.cx" ,
+      "This is the center coordinate of the radius mode, it will be either an "
+      "abscissa or a longitude." );
+    AddParameter( ParameterType_Float , "mode.radius.cy" ,
+                  "Y coordinate of the center" );
+    SetParameterDescription( "mode.radius.cx" ,
+      "This is the center coordinate of the radius mode, it will be either an "
+      "ordinate or a latitude." );
+    AddParameter( ParameterType_Choice , "mode.radius.unitc" , "Center unit" );
+    AddChoice( "mode.radius.unitc.pxl" , "Pixel" );
+    SetParameterDescription("mode.radius.unitc.pxl",
+      "The unit for the center coordinates will be the pixel");
+    AddChoice( "mode.radius.unitc.phy" , "Image physical space" );
+    SetParameterDescription("mode.radius.unitc.phy",
+      "The unit for the center coordinates will be the physical "
+      "measure of the image.");
+    AddChoice( "mode.radius.unitc.lonlat" , "Lon/Lat" );
+    SetParameterDescription("mode.radius.unitc.lonlat",
+      "The unit for the center coordinates will be the longitude and "
+      "the latitude.");
+
+
+    // Standard parameter
     AddParameter(ParameterType_Int,  "startx", "Start X");
     SetParameterDescription("startx", "ROI start x position.");
     AddParameter(ParameterType_Int,  "starty", "Start Y");
@@ -100,47 +205,86 @@ private:
     AddParameter(ParameterType_Int,  "sizey",  "Size Y");
     SetParameterDescription("sizey","size along y in pixels.");
 
+    // Channelist Parameters
+    AddParameter(ParameterType_ListView,  "cl", "Output Image channels");
+    SetParameterDescription("cl","Channels to write in the output image.");
+
+    // Elevation
+    ElevationParametersHandler::AddElevationParameters(this,"elev");
+    AddRAMParameter();
+
     // Default values
     SetDefaultParameterInt("startx", 0);
     SetDefaultParameterInt("starty", 0);
     SetDefaultParameterInt("sizex",  0);
     SetDefaultParameterInt("sizey",  0);
 
-    // Channelist Parameters
-    AddParameter(ParameterType_ListView,  "cl", "Output Image channels");
-    SetParameterDescription("cl","Channels to write in the output image.");
+    SetDefaultParameterInt("mode.extent.ulx", 0);
+    SetDefaultParameterInt("mode.extent.uly", 0);
+    SetDefaultParameterInt("mode.extent.lry", 0);
+    SetDefaultParameterInt("mode.extent.lrx", 0);
+
+    SetDefaultParameterInt("mode.radius.r", 0);
+    SetDefaultParameterInt("mode.radius.cx", 0);
+    SetDefaultParameterInt("mode.radius.cy", 0);
+
 
     // Doc example parameter settings
     SetDocExampleParameterValue("in", "VegetationIndex.hd");
-    SetDocExampleParameterValue("startx", "40");
-    SetDocExampleParameterValue("starty", "250");
-    SetDocExampleParameterValue("sizex", "150");
-    SetDocExampleParameterValue("sizey", "150");
+    SetDocExampleParameterValue("mode", "extent");
+    SetDocExampleParameterValue("mode.extent.ulx", "40");
+    SetDocExampleParameterValue("mode.extent.uly", "40");
+    SetDocExampleParameterValue("mode.extent.lrx", "150");
+    SetDocExampleParameterValue("mode.extent.lry", "150");
     SetDocExampleParameterValue("out", "ExtractROI.tif");
+    SetMinimumParameterIntValue("sizex", 0);
+    SetMinimumParameterIntValue("sizey", 0);
+    SetMinimumParameterIntValue("startx", 0);
+    SetMinimumParameterIntValue("starty", 0);
+    SetMinimumParameterFloatValue( "mode.radius.r" , 0 );
 
     SetOfficialDocLink();
   }
 
-  void DoUpdateParameters() ITK_OVERRIDE
+  void 
+  DoUpdateParameters() ITK_OVERRIDE
   {
-    // Update the sizes only if the user has not defined a size
     if ( HasValue("in") )
       {
-      ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");
-      ExtractROIFilterType::InputImageType::RegionType  largestRegion = inImage->GetLargestPossibleRegion();
+      ImageType* inImage = GetParameterImage("in");
+      ImageType::RegionType  largestRegion = inImage->GetLargestPossibleRegion();
+
+      bool userExtent = !HasUserValue( "mode.extent.ulx" ) \
+                     && !HasUserValue( "mode.extent.uly" ) \
+                     && !HasUserValue( "mode.extent.lrx" ) \
+                     && !HasUserValue( "mode.extent.lry" );
 
+      bool userRadius = !HasUserValue( "mode.radius.r" ) \
+                     && !HasUserValue( "mode.radius.cx" ) \
+                     && !HasUserValue( "mode.radius.cy" );
+
+      // Update the sizes only if the user has not defined a size
       if (!HasUserValue("sizex")  && !HasUserValue("sizey") )
         {
         SetParameterInt("sizex",largestRegion.GetSize()[0], false);
         SetParameterInt("sizey",largestRegion.GetSize()[1], false);
+
+        // Compute extent parameter with default sizex and sizey
+        if ( GetParameterString( "mode" ) == "extent" && userExtent )
+          ComputeExtentFromIndex( inImage, largestRegion );
+
+        // Compute radius parameter with default sizex and sizey
+        if ( GetParameterString( "mode" ) == "radius" && userRadius )
+          ComputeRadiusFromIndex( inImage , largestRegion );
         }
 
+
       unsigned int nbComponents = inImage->GetNumberOfComponentsPerPixel();
-      ListViewParameter *clParam = dynamic_cast<ListViewParameter*>(GetParameterByKey("cl"));
+      ListViewParameter *clParam = 
+                  dynamic_cast<ListViewParameter*>(GetParameterByKey("cl"));
       // Update the values of the channels to be selected if nbComponents is changed
       if (clParam != ITK_NULLPTR && clParam->GetNbChoices() != nbComponents)
         {
-
         ClearChoices("cl");
         for (unsigned int idx = 0; idx < nbComponents; ++idx)
           {
@@ -152,18 +296,20 @@ private:
         }
 
       // Put the limit of the index and the size relative the image
-      SetMinimumParameterIntValue("sizex", 0);
-      SetMaximumParameterIntValue("sizex", largestRegion.GetSize(0));
-
-      SetMinimumParameterIntValue("sizey", 0);
-      SetMaximumParameterIntValue("sizey", largestRegion.GetSize(1));
-
-      SetMinimumParameterIntValue("startx", 0);
+      
+      SetMaximumParameterIntValue("sizex", largestRegion.GetSize(0));      
+      SetMaximumParameterIntValue("sizey", largestRegion.GetSize(1));      
       SetMaximumParameterIntValue("startx", largestRegion.GetSize(0));
-
-      SetMinimumParameterIntValue("starty", 0);
       SetMaximumParameterIntValue("starty", largestRegion.GetSize(1));
 
+      
+      // Update the start and size parameter depending on the mode
+      if ( GetParameterString("mode") == "extent" && !userExtent)
+          ComputeIndexFromExtent();
+      if (GetParameterString("mode") == "radius" && !userRadius)
+          ComputeIndexFromRadius();
+
+      
       // Crop the roi region to be included in the largest possible
       // region
       if(!this->CropRegionOfInterest())
@@ -173,34 +319,62 @@ private:
         SetParameterInt("starty",0, false);
         this->CropRegionOfInterest();
         }
+
+      if(GetParameterString("mode")=="fit")
+        {
+        this->SetParameterRole("startx",Role_Output);
+        this->SetParameterRole("starty",Role_Output);
+        this->SetParameterRole("sizex",Role_Output);
+        this->SetParameterRole("sizey",Role_Output);
+        this->DisableParameter("startx");
+        this->DisableParameter("starty");
+        this->DisableParameter("sizex");
+        this->DisableParameter("sizey");
+        }
+
+      else if(GetParameterString("mode")=="standard" || 
+              GetParameterString("mode")=="extent" ||
+              GetParameterString("mode")== "radius" )
+        {
+        this->SetParameterRole("startx",Role_Input);
+        this->SetParameterRole("starty",Role_Input);
+        this->SetParameterRole("sizex",Role_Input);
+        this->SetParameterRole("sizey",Role_Input);
+        this->EnableParameter("startx");
+        this->EnableParameter("starty");
+        this->EnableParameter("sizex");
+        this->EnableParameter("sizey");
+        }
       }
 
-    if(GetParameterString("mode")=="fit")
+    // If not standard mode start and size parameter will be computed by the application
+    if ( GetParameterString( "mode" ) != "standard" )
       {
-      this->SetParameterRole("startx",Role_Output);
-      this->SetParameterRole("starty",Role_Output);
-      this->SetParameterRole("sizex",Role_Output);
-      this->SetParameterRole("sizey",Role_Output);
-
-      this->DisableParameter("startx");
-      this->DisableParameter("starty");
-      this->DisableParameter("sizex");
-      this->DisableParameter("sizey");
+      MandatoryOff("startx");
+      MandatoryOff("starty");
+      MandatoryOff("sizex");
+      MandatoryOff("sizey");
+      }
+    else
+      {
+      MandatoryOn("startx");
+      MandatoryOn("starty");
+      MandatoryOn("sizex");
+      MandatoryOn("sizey");
+      }
 
+    if ( GetParameterString( "mode" ) == "fit" && HasValue( "mode.fit.im" ) )
+      {
+      MandatoryOff( "mode.fit.vect" );
+      MandatoryOn( "mode.fit.im" );
       }
-    else if(GetParameterString("mode")=="standard")
+    else if ( GetParameterString( "mode" ) == "fit" && 
+              HasValue( "mode.fit.vect" ) )
       {
-      this->SetParameterRole("startx",Role_Input);
-      this->SetParameterRole("starty",Role_Input);
-      this->SetParameterRole("sizex",Role_Input);
-      this->SetParameterRole("sizey",Role_Input);
-
-      this->EnableParameter("startx");
-      this->EnableParameter("starty");
-      this->EnableParameter("sizex");
-      this->EnableParameter("sizey");
+      MandatoryOff( "mode.fit.im" );
+      MandatoryOn( "mode.fit.vect" );
       }
-  }
+  } 
 
   bool CropRegionOfInterest()
   {
@@ -209,33 +383,386 @@ private:
     region.SetSize(1,  GetParameterInt("sizey"));
     region.SetIndex(0, GetParameterInt("startx"));
     region.SetIndex(1, GetParameterInt("starty"));
-
     if ( HasValue("in") )
       {
-        if (region.Crop(GetParameterImage("in")->GetLargestPossibleRegion()))
+      if (region.Crop(GetParameterImage("in")->GetLargestPossibleRegion()))
+        {
+        SetParameterInt("sizex",region.GetSize(0), HasUserValue("sizex"));
+        SetParameterInt("sizey",region.GetSize(1), HasUserValue("sizey"));
+        SetParameterInt("startx",region.GetIndex(0), HasUserValue("startx"));
+        SetParameterInt("starty",region.GetIndex(1), HasUserValue("starty"));
+        return true;
+        }
+      }
+    return false;
+  }
+
+  void
+  ComputeIndexFromExtent()
+  {
+    assert( GetParameterString( "mode" ) == "extent" );
+    int pixelValue = -1 ;
+    // Compute standard parameter depending on the unit chosen by the user
+    if (GetParameterString( "mode.extent.unit" ) == "pxl" )
+      {
+      pixelValue = std::round( GetParameterFloat( "mode.extent.ulx" ) );
+      SetParameterInt( "startx", pixelValue , true );
+      pixelValue = std::round( GetParameterFloat( "mode.extent.lrx" ) \
+                   - pixelValue ) + 1 ;
+      SetParameterInt( "sizex", pixelValue , true );
+      pixelValue = std::round( GetParameterFloat( "mode.extent.uly" ) );
+      SetParameterInt( "starty", pixelValue , true );
+      pixelValue = std::round( GetParameterFloat( "mode.extent.lry" ) \
+                   - pixelValue ) + 1 ;
+      SetParameterInt( "sizey", pixelValue , true );
+      }
+    else if( GetParameterString( "mode.extent.unit" ) == "phy" )
+      {
+      itk::Point<float, 2> ulp,  lrp;
+      ulp[ 0 ] = GetParameterFloat( "mode.extent.ulx" );
+      ulp[ 1 ] = GetParameterFloat( "mode.extent.uly" );
+      lrp[ 0 ] = GetParameterFloat( "mode.extent.lrx" );
+      lrp[ 1 ] = GetParameterFloat( "mode.extent.lry" );
+
+      ImageType * inImage = GetParameterImage("in");
+      FloatVectorImageType::IndexType uli , lri;
+      bool startin = inImage->TransformPhysicalPointToIndex(ulp,uli);
+      bool sizein = inImage->TransformPhysicalPointToIndex(lrp,lri);
+      if ( startin )
+        {
+        SetParameterInt( "startx", uli[0] , true );
+        SetParameterInt( "starty", uli[1] , true );
+        }
+        
+      if( startin && sizein )
+        {
+        SetParameterInt( "sizex", lri[0] - uli[0] + 1, true );
+        SetParameterInt( "sizey", lri[1] - uli[1] + 1, true );
+        }
+      }
+    else if( GetParameterString( "mode.extent.unit" ) == "lonlat" )
+      {
+      RSTransformType::Pointer rsTransform = RSTransformType::New();
+      ImageType* inImage = GetParameterImage("in");
+      rsTransform->SetOutputKeywordList( inImage->GetImageKeywordlist() );
+      rsTransform->SetOutputProjectionRef( inImage->GetProjectionRef() );
+      rsTransform->InstantiateTransform();
+      itk::Point<float, 2> ulp_in,  lrp_in , ulp_out , lrp_out;
+      ulp_in[ 0 ] = GetParameterFloat( "mode.extent.ulx" );
+      ulp_in[ 1 ] = GetParameterFloat( "mode.extent.uly" );
+      lrp_in[ 0 ] = GetParameterFloat( "mode.extent.lrx" );
+      lrp_in[ 1 ] = GetParameterFloat( "mode.extent.lry" );
+      ulp_out = rsTransform->TransformPoint(ulp_in);
+      lrp_out = rsTransform->TransformPoint(lrp_in);
+
+      FloatVectorImageType::IndexType uli_out , lri_out;
+      bool startin = inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
+      bool sizein = inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);
+
+      if ( startin )
+        {
+        SetParameterInt( "startx", uli_out[0] , true );
+        SetParameterInt( "starty", uli_out[1] , true );
+        }
+            
+      if( startin && sizein )
+        {
+        SetParameterInt( "sizex", lri_out[0] - uli_out[0] + 1, true );
+        SetParameterInt( "sizey", lri_out[1] - uli_out[1] + 1, true );
+        }
+      }  
+  }
+
+  void
+  ComputeExtentFromIndex(const ImageType * input , 
+                         const ImageType::RegionType & largestRegion )
+  {
+    FloatVectorImageType::IndexType uli , lri;
+    uli.Fill(0);
+    lri[ 0 ] = largestRegion.GetSize()[0];
+    lri[ 1 ] = largestRegion.GetSize()[1];
+    if ( GetParameterString( "mode.extent.unit" ) == "pxl" )
+      {
+      SetParameterFloat("mode.extent.ulx", uli[0] , false);
+      SetParameterFloat("mode.extent.uly", uli[1] , false);
+      SetParameterFloat("mode.extent.lrx", lri[0] , false);
+      SetParameterFloat("mode.extent.lry", lri[1] , false);
+      }
+    else if ( GetParameterString( "mode.extent.unit" ) == "phy" )
+      {
+      itk::Point<float, 2> ulp,  lrp;
+
+      input->TransformIndexToPhysicalPoint(uli,ulp);
+      SetParameterFloat("mode.extent.ulx",ulp[0], false);
+      SetParameterFloat("mode.extent.uly",ulp[1], false);
+
+      input->TransformIndexToPhysicalPoint(lri,lrp);
+      SetParameterFloat("mode.extent.lrx",lrp[0], false);
+      SetParameterFloat("mode.extent.lry",lrp[1], false);  
+      }
+    else if ( GetParameterString( "mode.extent.unit" ) == "lonlat" )
+      {
+      RSTransformType::Pointer rsTransform = RSTransformType::New();
+      rsTransform->SetInputKeywordList( input->GetImageKeywordlist() );
+      rsTransform->SetInputProjectionRef( input->GetProjectionRef() );
+      rsTransform->InstantiateTransform();
+      itk::Point<float, 2> ulp_in,  lrp_in , ulp_out , lrp_out;
+      input->TransformIndexToPhysicalPoint(uli,ulp_in);
+      ulp_out = rsTransform->TransformPoint( ulp_in );
+      SetParameterFloat( "mode.extent.ulx" , ulp_out[ 0 ] , false );
+      SetParameterFloat( "mode.extent.uly" , ulp_out[ 1 ] , false );
+
+      input->TransformIndexToPhysicalPoint( lri , lrp_in );
+      lrp_out = rsTransform->TransformPoint( lrp_in );
+      SetParameterFloat( "mode.extent.lrx" , lrp_out[ 0 ] , false );
+      SetParameterFloat( "mode.extent.lry" , lrp_out[ 1 ] , false );
+      }
+  }
+
+  void
+  ComputeIndexFromRadius()
+  {
+    int pixelValue = -1;
+    assert( GetParameterString( "mode" ) == "radius" );
+    // First compute sizex sizey thanks to the radius
+    if ( HasUserValue( "mode.radius.r" ) )
+      {
+      if ( GetParameterString( "mode.radius.unitr" ) == "pxl" )
+        {
+        pixelValue = std::floor( 2 * GetParameterFloat( "mode.radius.r" ) ) + 1;
+        SetParameterInt( "sizey", pixelValue , true );
+        SetParameterInt( "sizex", pixelValue , true );
+        }
+      if ( GetParameterString( "mode.radius.unitr" ) == "phy" )
+        {
+        ImageType * inImage = GetParameterImage("in");
+        itk::Point<float, 2> radxp , radyp , ulp ;
+        FloatVectorImageType::IndexType radxi , radyi , uli;
+        uli.Fill(0);
+        inImage->TransformIndexToPhysicalPoint( uli , ulp );
+        radxp = ulp; 
+        radyp = ulp; 
+        radxp[0] += GetParameterFloat( "mode.radius.r" );
+        radyp[1] += GetParameterFloat( "mode.radius.r" );
+        bool lgtx = inImage->TransformPhysicalPointToIndex( radxp , radxi );
+        bool lgty = inImage->TransformPhysicalPointToIndex( radyp , radyi );
+        FloatVectorImageType::IndexValueType maxR = 
+                std::min( inImage->GetLargestPossibleRegion().GetSize()[0] , 
+                          inImage->GetLargestPossibleRegion().GetSize()[1] );
+        maxR = maxR / 2 - ( (maxR + 1) % 2 );
+        if ( lgtx && lgty)
+          {
+          pixelValue = std::max( radxi[0] , radyi[1] );
+          if ( maxR<pixelValue )
+            {
+            pixelValue = std::min( std::min( radxi[0] , radyi[1] ) , maxR );
+            }
+          }
+        else if ( lgtx )
           {
-            SetParameterInt("sizex",region.GetSize(0), HasUserValue("sizex"));
-            SetParameterInt("sizey",region.GetSize(1), HasUserValue("sizey"));
-            SetParameterInt("startx",region.GetIndex(0), HasUserValue("startx"));
-            SetParameterInt("starty",region.GetIndex(1), HasUserValue("starty"));
-            return true;
+          pixelValue = std::min( radxi[0] , maxR );
           }
+        else if ( lgty )
+          {
+          pixelValue = std::min( radyi[1] , maxR );
+          }
+        else
+          {
+          pixelValue = maxR;
+          }
+        SetParameterInt( "sizey", 2 * pixelValue + 1 , true );
+        SetParameterInt( "sizex", 2 * pixelValue + 1 , true );
+        }
+      }
+
+    // Then compute startx and starty
+    bool size = ( HasValue("sizex")  && HasValue("sizey") );
+    if ( size ) 
+      {
+      int radiusxi = GetParameterInt("sizex") / 2 ;
+      int radiusyi = GetParameterInt("sizey") / 2 ;
+
+      if ( GetParameterString( "mode.radius.unitc" ) == "pxl" && size )
+        {
+        pixelValue = std::round(GetParameterFloat( "mode.radius.cx" ));
+        SetParameterInt( "startx", pixelValue - radiusxi , true );
+        pixelValue = std::round(GetParameterFloat( "mode.radius.cy" ));
+        SetParameterInt( "starty", pixelValue - radiusyi , true );
+        }
+      if ( GetParameterString( "mode.radius.unitc" ) == "phy" && size ) 
+        {
+        ImageType * inImage = GetParameterImage("in");
+        itk::Point<float, 2> centerp;
+        centerp[ 0 ] = GetParameterFloat( "mode.radius.cx" );
+        centerp[ 1 ] = GetParameterFloat( "mode.radius.cy" );
+        FloatVectorImageType::IndexType centeri ;
+        bool isIn = inImage->TransformPhysicalPointToIndex( centerp , centeri );
+          if ( isIn )
+          {
+          SetParameterInt( "startx", centeri[0] - radiusxi , true );
+          SetParameterInt( "starty", centeri[1] - radiusyi , true );
+          }
+        }
+      if ( GetParameterString( "mode.radius.unitc" ) == "lonlat" && size )
+        {
+        ImageType* inImage = GetParameterImage("in");
+        RSTransformType::Pointer rsTransform = RSTransformType::New();
+        rsTransform->SetOutputKeywordList( inImage->GetImageKeywordlist() );
+        rsTransform->SetOutputProjectionRef( inImage->GetProjectionRef() );
+        rsTransform->InstantiateTransform();
+        itk::Point<float, 2> centerp_in , centerp_out;
+        centerp_in[ 0 ] = GetParameterFloat( "mode.radius.cx" );
+        centerp_in[ 1 ] = GetParameterFloat( "mode.radius.cy" );
+        centerp_out = rsTransform->TransformPoint(centerp_in);
+        FloatVectorImageType::IndexType centeri_out;
+        bool isIn = inImage->TransformPhysicalPointToIndex( centerp_out , 
+                                                            centeri_out );
+        if ( isIn )
+          {
+          SetParameterInt( "startx", centeri_out[0] - radiusxi , true );
+          SetParameterInt( "starty", centeri_out[1] - radiusyi , true );
+          }
+        }
+      }
+  }
+
+  void
+  ComputeRadiusFromIndex(const ImageType * input , 
+                         const ImageType::RegionType & largestRegion)
+  {
+    FloatVectorImageType::IndexType centeri , helpRxi, helpRyi;
+    centeri[ 0 ] = largestRegion.GetSize()[0] / 2  \
+                   - (largestRegion.GetSize()[0] + 1)%2;
+    centeri[ 1 ] = largestRegion.GetSize()[1] / 2  \
+                   - (largestRegion.GetSize()[1] + 1)%2;
+    helpRxi[ 0 ] = centeri[ 0 ];
+    helpRxi[ 1 ] = 0;
+    helpRyi[ 0 ] = 0;
+    helpRyi[ 1 ] = centeri[ 1 ];
+    if ( GetParameterString("mode.radius.unitr") == "pxl" )
+      {
+      int rad = std::min( centeri[ 0 ], centeri[ 1 ] );
+      SetParameterFloat( "mode.radius.r" , rad , false );
+      }
+    if ( GetParameterString("mode.radius.unitr") == "phy" )
+      {
+      itk::Point<float, 2> centerp , helpRxp, helpRyp;
+      input->TransformIndexToPhysicalPoint(centeri,centerp);
+      input->TransformIndexToPhysicalPoint(helpRxi,helpRxp);
+      input->TransformIndexToPhysicalPoint(helpRyi,helpRyp);
+      float rad = std::min( helpRxp[0] - helpRyp[0] , helpRyp[1] - helpRxp[1] );
+      SetParameterFloat( "mode.radius.r" , rad , false );
+      }
+    if ( GetParameterString("mode.radius.unitc") == "pxl" )
+      {
+      SetParameterFloat( "mode.radius.cx" , centeri[0] , false );
+      SetParameterFloat( "mode.radius.cy" , centeri[1] , false) ;
+      }
+    if ( GetParameterString("mode.radius.unitc") == "phy" )
+      {
+      itk::Point<float, 2> centerp , helpRp;
+      input->TransformIndexToPhysicalPoint(centeri,centerp);
+      SetParameterFloat( "mode.radius.cx" , centerp[0] , false );
+      SetParameterFloat( "mode.radius.cy" , centerp[1] , false) ;
+      }
+    if ( GetParameterString("mode.radius.unitc") == "lonlat" )
+      {
+      RSTransformType::Pointer rsTransform = RSTransformType::New();
+      rsTransform->SetInputKeywordList( input->GetImageKeywordlist() );
+      rsTransform->SetInputProjectionRef( input->GetProjectionRef() );
+      rsTransform->InstantiateTransform();
+      itk::Point<float, 2> centerp_in,  centerp_out;
+      input->TransformIndexToPhysicalPoint(centeri,centerp_in);
+      centerp_out = rsTransform->TransformPoint( centerp_in );
+      SetParameterFloat( "mode.radius.cx" , centerp_out[ 0 ] , false );
+      SetParameterFloat( "mode.radius.cy" , centerp_out[ 1 ] , false );
       }
-    return false;
   }
 
-  void DoExecute() ITK_OVERRIDE
+  void 
+  DoExecute() ITK_OVERRIDE
   {
-    ExtractROIFilterType::InputImageType* inImage = GetParameterImage("in");
+    ImageType* inImage = GetParameterImage("in");
     inImage->UpdateOutputInformation();
 
+    if ( HasValue( "mode.fit.vect" ) && GetParameterString("mode") == "fit" )
+      {
+      otb::ogr::DataSource::Pointer ogrDS;
+      ogrDS = otb::ogr::DataSource::New(GetParameterString("in") ,
+                                        otb::ogr::DataSource::Modes::Read);
+      double ulx, uly, lrx, lry;
+      bool extentAvailable = true;
+      std::string inputProjectionRef = "";
+      // First try to get the extent in the metadata
+      try
+        {
+        inputProjectionRef = ogrDS->GetGlobalExtent(ulx,uly,lrx,lry);
+        }
+      catch(const itk::ExceptionObject&)
+        {
+        extentAvailable = false;
+        }
+      // If no extent available force the computation of the extent
+      if (!extentAvailable)
+        {
+        try
+          {
+          inputProjectionRef = ogrDS->GetGlobalExtent(ulx,uly,lrx,lry,true);
+          extentAvailable = true;
+          }
+        catch(itk::ExceptionObject & err)
+          {
+          extentAvailable = false;
+
+          otbAppLogFATAL(<<"Failed to retrieve the spatial extent of the dataset "
+                           "in force mode. The spatial extent is mandatory when "
+                           "orx, ory, spx and spy parameters are not set, consider "
+                           "setting them. Error from library: "<<err.GetDescription());
+          }
+        }
+
+      if (extentAvailable)
+        {
+        RSTransformType::Pointer rsTransform = RSTransformType::New();
+        rsTransform->SetInputProjectionRef(inputProjectionRef);
+        rsTransform->SetOutputKeywordList( inImage->GetImageKeywordlist() );
+        rsTransform->SetOutputProjectionRef( inImage->GetProjectionRef() );
+        rsTransform->InstantiateTransform();
+
+        itk::Point<float, 2> ulp_in,  lrp_in , ulp_out , lrp_out;
+        ulp_in[ 0 ] = ulx ;
+        ulp_in[ 1 ] = uly ;
+        lrp_in[ 0 ] = lrx ;
+        lrp_in[ 1 ] = lry ;
+        ulp_out = rsTransform->TransformPoint(ulp_in);
+        lrp_out = rsTransform->TransformPoint(lrp_in);
+
+        FloatVectorImageType::IndexType uli_out , lri_out;
+        bool startin , sizein ;
+        startin = inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
+        sizein = inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);
+
+        if ( startin )
+            {
+            SetParameterInt( "startx", uli_out[0] , false );
+            SetParameterInt( "starty", uli_out[1] , false );
+            }
+                
+        if( startin && sizein )
+            {
+            SetParameterInt( "sizey", lri_out[1] - uli_out[1] + 1 , false );
+            SetParameterInt( "sizex", lri_out[0] - uli_out[0] + 1 , false );
+            }
+        }
+        
+      }
 
-    if(GetParameterString("mode")=="fit")
+    if( HasValue( "mode.fit.im" ) && GetParameterString( "mode" ) == "fit" )
       {
       // Setup the DEM Handler
-      otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"mode.fit.elev");
+      otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev");
 
-      FloatVectorImageType::Pointer referencePtr = this->GetParameterImage("mode.fit.ref");
+      FloatVectorImageType::Pointer referencePtr = this->GetParameterImage("mode.fit.im");
       referencePtr->UpdateOutputInformation();
 
       RSTransformType::Pointer rsTransform = RSTransformType::New();
@@ -278,11 +805,15 @@ private:
 
       FloatVectorImageType::IndexType uli, lri;
 
-      uli[0] = std::min(std::min(uli_out[0],uri_out[0]),std::min(lli_out[0],lri_out[0]));
-      uli[1] = std::min(std::min(uli_out[1],uri_out[1]),std::min(lli_out[1],lri_out[1]));
+      uli[0] = std::min( std::min( uli_out[0] , uri_out[0] ) , 
+                         std::min( lli_out[0] , lri_out[0] ) );
+      uli[1] = std::min( std::min( uli_out[1] , uri_out[1] ) ,
+                         std::min( lli_out[1] , lri_out[1] ) );
 
-      lri[0] = std::max(std::max(uli_out[0],uri_out[0]),std::max(lli_out[0],lri_out[0]));
-      lri[1] = std::max(std::max(uli_out[1],uri_out[1]),std::max(lli_out[1],lri_out[1]));
+      lri[0] = std::max( std::max( uli_out[0] , uri_out[0] ) ,
+                         std::max( lli_out[0] , lri_out[0] ) );
+      lri[1] = std::max( std::max( uli_out[1] , uri_out[1] ) ,
+                         std::max( lli_out[1] , lri_out[1] ) );
 
       SetParameterInt("startx",uli[0]);
       SetParameterInt("starty",uli[1]);
diff --git a/Modules/Applications/AppImageUtils/otb-module.cmake b/Modules/Applications/AppImageUtils/otb-module.cmake
index 72e63db6e8fa76b5edae021ced6df391f936065d..6b378f1f31adc8b54cab8249c2ec2a95f208de00 100644
--- a/Modules/Applications/AppImageUtils/otb-module.cmake
+++ b/Modules/Applications/AppImageUtils/otb-module.cmake
@@ -22,6 +22,7 @@ set(DOCUMENTATION "Image utils and handling application.")
 
 otb_module(OTBAppImageUtils
   DEPENDS
+    OTBConversion
     OTBApplicationEngine
     OTBBoostAdapters
     OTBCarto
diff --git a/Modules/Applications/AppImageUtils/test/CMakeLists.txt b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
index 32d54bdef86587cee770865836d895c76a361462..1117d032186bd937d516522ce449924bdc63e8f2 100644
--- a/Modules/Applications/AppImageUtils/test/CMakeLists.txt
+++ b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
@@ -77,6 +77,26 @@ otb_test_application(NAME apTvUtExtractROISizeTooBig
                              ${INPUTDATA}/couleurs_extrait.png
                              ${TEMP}/apTvUtExtractROISizeTooBig.tif)
 
+otb_test_application(NAME apTvUtExtractROISizeTooBigExtent
+                     APP  ExtractROI
+                     OPTIONS -in ${INPUTDATA}/couleurs_extrait.png
+                             -out ${TEMP}/apTvUtExtractROISizeTooBigExtent.tif
+                             -mode extent
+                             -mode.extent.lrx 1000000
+                     VALID   --compare-image ${NOTOL}
+                             ${INPUTDATA}/couleurs_extrait.png
+                             ${TEMP}/apTvUtExtractROISizeTooBigExtent.tif)
+
+otb_test_application(NAME apTvUtExtractROISizeTooBigRadius
+                     APP  ExtractROI
+                     OPTIONS -in ${INPUTDATA}/couleurs_extrait.png
+                             -out ${TEMP}/apTvUtExtractROISizeTooBigRadius.tif
+                             -mode radius
+                             -mode.radius.r 1000000
+                     VALID   --compare-image ${NOTOL}
+                             ${INPUTDATA}/couleurs_extrait.png
+                             ${TEMP}/apTvUtExtractROISizeTooBigRadius.tif)
+
 otb_test_application(NAME apTvUtExtractROISizeNULL
                      APP  ExtractROI
                      OPTIONS -in ${INPUTDATA}/couleurs_extrait.png
diff --git a/Modules/Applications/AppMathParser/app/otbBandMath.cxx b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
index 7a03d84c69aa80382941c2e6d5b60b538f2532fa..f8ecc1bafb051cc231cf61b14c3d2ea7f0669fb1 100644
--- a/Modules/Applications/AppMathParser/app/otbBandMath.cxx
+++ b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
@@ -55,38 +55,72 @@ public:
 private:
   void DoInit() ITK_OVERRIDE
   {
-    SetName("BandMath");
-    SetDescription("Perform a mathematical operation on monoband images");
-
-    SetDocName("Band Math");
-    SetDocLongDescription("This application performs a mathematical operation on monoband images."
-      "Mathematical formula interpretation is done via MuParser libraries.\n"
-      "For MuParser version superior to 2.0 uses '&&' and '||' logical operators, and ternary operator 'boolean_expression ? if_true : if_false'\n"
-      "For older version of MuParser (prior to v2) use 'and' and 'or' logical operators, and ternary operator 'if(; ; )'.\n"
-      "The list of features and operators is available on MuParser website: http://muparser.sourceforge.net/\n"
+    SetName( "BandMath" );
+
+    SetDescription(
+      "Outputs a monoband image which is the result of a mathematical operation "
+      "on several multi-band images."
+    );
+
+    SetDocName( "Band Math" );
+
+    SetDocLongDescription(
+      "This application performs a mathematical operation on several multi-band "
+      "images and outputs the result into a monoband image. Evaluation of the "
+      "mathematical formula is done by the muParser libraries.\n\n"
+
+      "muParser version superior to 2.0, provides the '&&' and '||' logical "
+      "operators, and a ternary operator 'boolean_expression ? if_true : "
+      "if_false'.\n\n"
+
+      "Older versions of muParser (prior to v-2.0) provides only the 'and' and "
+      "'or' logical operators, and a ternary operator 'if(; ; )'.\n\n"
+
+      "The list of features and operators is available on the muParser website [1]."
       );
 
-    SetDocLimitations("None");
-    SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
-    AddDocTag("Miscellaneous");
+    SetDocLimitations( "None" );
+    SetDocAuthors( "OTB-Team" );
+    SetDocSeeAlso("[1] http://muparser.sourceforge.net/");
+    AddDocTag( "Miscellaneous" );
 
-    AddParameter(ParameterType_InputImageList,  "il",   "Input image list");
-    SetParameterDescription("il", "Image list to perform computation on.");
+    AddParameter( ParameterType_InputImageList, "il", "Input image-list" );
+    SetParameterDescription(
+      "il",
+      "Image-list of operands to the mathematical expression."
+    );
 
-    AddParameter(ParameterType_OutputImage, "out", "Output Image");
-    SetParameterDescription("out","Output image.");
+    AddParameter( ParameterType_OutputImage, "out", "Output Image" );
+    SetParameterDescription(
+      "out",
+      "Output image which is the result of the mathematical expressions on input"
+      " image-list operands.");
 
     AddRAMParameter();
 
-    AddParameter(ParameterType_String, "exp", "Expression");
-    SetParameterDescription("exp",
-                            "The mathematical expression to apply. \nUse im1b1 for the first band, im1b2 for the second one...");
+    AddParameter( ParameterType_String, "exp", "Expression");
+    SetParameterDescription(
+      "exp",
+      "The muParser mathematical expression to apply on input images.\n"
+      "Use im1b1 as first band of first image, im1b2 for the second band of "
+      "first image.\n"
+      "Use im2b1 as first band of second image, im2b2 for the second band of "
+      "second image.\n"
+      "etc."
+    );
 
     // Doc example parameter settings
-    SetDocExampleParameterValue("il", "verySmallFSATSW_r.tif verySmallFSATSW_nir.tif verySmallFSATSW.tif");
-    SetDocExampleParameterValue("out", "apTvUtBandMathOutput.tif");
-    SetDocExampleParameterValue("exp", "\"cos(im1b1) > cos(im2b1) ? im3b1 : im3b2\"");
+    SetDocExampleParameterValue(
+      "il",
+      "verySmallFSATSW_r.tif verySmallFSATSW_nir.tif verySmallFSATSW.tif"
+    );
+    SetDocExampleParameterValue(
+      "out",
+      "apTvUtBandMathOutput.tif"
+    );
+    SetDocExampleParameterValue(
+      "exp", "'cos( im1b1 ) > cos( im2b1 ) ? im3b1 : im3b2'"
+    );
 
     SetOfficialDocLink();
   }
@@ -222,5 +256,3 @@ private:
 } // namespace otb
 
 OTB_APPLICATION_EXPORT(otb::Wrapper::BandMath)
-
-
diff --git a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
index ef5ed35775a42984592332e274417f1faca2f40a..06da000b882e6c8215e602e79ca01baad1bd9877 100644
--- a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
+++ b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
@@ -57,121 +57,221 @@ public:
 private:
   void DoInit() ITK_OVERRIDE
   {
-    SetName("BandMathX");
-    SetDescription("This application performs mathematical operations on multiband images.\n"
-      "Mathematical formula interpretation is done via muParserX library : http://articles.beltoforion.de/article.php?a=muparserx");
-
-    SetDocName("Band Math X");
-    SetDocLongDescription("The goal of this documentation is to give the user some hints about the syntax used in this application.\n"
-      "The syntax is mainly constrained by the muparserx library, which can be considered as the core of the application.\n"
-      "\n\n"
-      "- Fundamentals:\n\n"
-      "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). \n"
-      "The following list summaries the available variables for input #0 (and so on for every input): \n"
-      "\n"
-      "im1                                -->   a pixel from first input, made of n components (n bands)\n"
-      "im1bj                             -->   jth component of a pixel from first input (first band is indexed by 1)\n"
-      "im1bjNkxp                     -->   a neighbourhood ('N') of pixels of the jth component from first input, of size kxp\n"
-      "im1PhyX and im1PhyY  -->   spacing of first input in X and Y directions (horizontal and vertical)\n"
-      "im1bjMean im1bjMin im1bjMax im1bjSum im1bjVar  -->   mean, min, max, sum, variance of jth band from first input (global statistics)\n"
-      "\nMoreover, we also have the following generic variables:\n"
-      "idxX and idxY        -->   indices of the current pixel\n"
-      "\n"
-      "Always keep in mind that this application only addresses mathematically well-defined formulas.\n"
-      "For instance, it is not possible to add vectors of different dimensions (this implies the addition of a row vector with a column vector),\n"
-      "or add a scalar to a vector or a matrix, or divide two vectors, and so on...\n"
-      "Thus, it is important to remember that a pixel of n components is always represented as a row vector.\n"
-      "\n"
-      "Example :\n\n"
-      "                   im1 + im2       (1)\n"
-      "\nrepresents the addition of pixels from first and second inputs. This expression is consistent only if\n"
-      "both inputs have the same number of bands.\n"
-      "Note that it is also possible to use the following expressions to obtain the same result:\n"
-      "\n"
-      "                   im1b1 + im2b1 \n"
-      "                   im1b2 + im2b2       (2)\n"
-      "                   ..."
-      "\n\nNevertheless, the first expression is by far much pleaseant. We call this new functionality the 'batch mode'\n"
-      "(performing the same operation in a band-to-band fashion).\n"
-
-      "\n\n"
-      "- Operations involving neighborhoods of pixels:\n\n"
-      "Another new fonctionnality is the possibility to perform operations that involve neighborhoods of pixels.\n"
-      "Variable related to such neighborhoods are always defined following the pattern imIbJNKxP, where: \n"
-      "- I is an number identifying the image input (remember, input #0 = im1, and so on)\n"
-      "- J is an number identifying the band (remember, first band is indexed by 1)\n"
-      "- KxP are two numbers that represent the size of the neighborhood (first one is related to the horizontal direction)\n"
-      "All neighborhood are centered, thus K and P must be odd numbers.\n"
-      "Many operators come with this new functionality: dotpr, mean var median min max...\n"
-      "For instance, if im1 represents the pixel of 3 bands image:\n\n"
-      "               im1 - mean(im1b1N5x5,im1b2N5x5,im1b3N5x5)       (3)\n"
-      "\ncould represent a high pass filter (Note that by implying three neighborhoods, the operator mean returns a row vector of three components.\n"
-      "It is a typical behaviour for many operators of this application).\n"
-
-      "\n\n"
-      "- Operators:\n\n"
+    SetName( "BandMathX" );
+
+    SetDescription(
+      "This application performs mathematical operations on several multiband images.\n"
+    );
+
+    SetDocName( "Band Math X" );
+
+    SetDocLongDescription(
+      "This application performs a mathematical operation on several multi-band "
+      "images and outputs the result into an image (multi- or mono-band, as "
+      "opposed to the BandMath OTB-application). The mathematical formula is "
+      "done by the muParserX libraries.\n\n"
+
+      "The list of features and the syntax of muParserX is available at [1].\n\n"
+
+      "As opposed to muParser (and thus the BandMath OTB-application [2]), "
+      "muParserX supports vector expressions which allows to output multi-band "
+      "images.\n\n"
+
+      "Hereafter is a brief reference of the muParserX syntax\n\n"
+
+      "Fundamentals\n"
+      "------------\n\n"
+
+      "The i-th input image is identified by the 'im<i+1>' (e.g. 'im1') prefix "
+      "(please, note the indexing from 1 to N, for N inputs).\n\n"
+
+      "The following list summarizes the available variables of input #0:\n\n"
+
+      "im1\n"
+      "  a pixel from 1st input, made of n components (n bands).\n\n"
+
+      "im1b2\n"
+      "  the 2nd component of a pixel from 1st input (band index is 1-based).\n\n"
+
+      "im1b2N3x4\n"
+      "  a 3x4 pixels 'N'eighbourhood of a pixel the 2nd component of a pixel "
+      "from the 1st input.\n\n"
+
+      "im1PhyX\n"
+      "  horizontal (X-axis) spacing of the 1st input.\n\n"
+
+      "im1PhyY\n"
+      "  vertical spacing of the 1st input input.\n\n"
+
+      "im1b2Mean\n"
+      "  mean of the 2nd component of the 1st input (global statistics)\n\n"
+
+      "im1b2Min\n"
+      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
+
+      "im1b2Max\n"
+      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
+
+      "im1b2Sum\n"
+      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
+
+      "im1b2Var\n"
+      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
+
+      "idxX, idxY\n"
+      "  indices of the current pixel (generic variables)\n\n"
+
+      "Always keep in mind that this application only addresses mathematically "
+      "well-defined formulas. For instance, it is not possible to add vectors of"
+      " different dimensions (e.g. addition of a row vector with a column vector"
+      "), or a scalar to a vector or matrix, or divide two vectors, etc.\n\n"
+
+      "Thus, it is important to remember that a pixel of n components is always "
+      "represented as a row vector.\n\n"
+
+      "Example:\n"
+      "  im1 + im2 (1)\n"
+      "  represents the addition of pixels from the 1st and 2nd inputs. This "
+      "expression is consistent only if both inputs have the same number of "
+      "bands.\n\n"
+
+      "Please, note that it is also possible to use the following expressions"
+      " to obtain the same result:\n"
+      "  im1b1 + im2b1\n"
+      "  im1b2 + im2b2 (2)\n"
+      "  ...\n\n"
+
+      "Nevertheless, the first expression is by far much pleaseant. We call "
+      "this new functionality the 'batch mode' (performing the same operation "
+      "in a band-to-band fashion).\n\n"
+
+      "Operations involving neighborhoods of pixels\n"
+      "--------------------------------------------\n\n"
+
+      "Another new feature is the possibility to perform operations that "
+      "involve neighborhoods of pixels. Variables related to such neighborhoods "
+      "are always defined following the imIbJNKxP pattern, where:\n"
+      "- I is an number identifying the image input (remember, input #0 = im1, "
+      "and so on)\n"
+      "- J is an number identifying the band (remember, first band is indexed by"
+      "1)\n"
+      "- KxP are two numbers that represent the size of the neighborhood (first "
+      "one is related to the horizontal direction)\n\n"
+
+      "NB: All neighborhood are centered, thus K and P must be odd numbers.\n\n"
+
+      "Many operators come with this new functionality:\n"
+      "- dotpr\n"
+      "- mean\n"
+      "- var\n"
+      "- median\n"
+      "- min\n"
+      "- max\n"
+      "- etc.\n\n"
+
+      "For instance, if im1 represents the pixel of 3 bands image:\n"
+      "  im1 - mean( im1b1N5x5, im1b2N5x5, im1b3N5x5 ) (3)\n\n"
+      "could represent a high pass filter (note that by implying three "
+      "neighborhoods, the operator mean returns a row vector of three components"
+      ". It is a typical behaviour for many operators of this application).\n\n"
+
       "In addition to the previous operators, other operators are available:\n"
-      "- existing operators/functions from muParserX, that were not originally defined for vectors and\n"
-      "matrices (for instance cos, sin, ...). These new operators/ functions keep the original names to which we added the prefix 'v' for vector (vcos, vsin, ...).\n"
-      "- mult, div and pow operators, that perform element-wise multiplication, division or exponentiation of vector/matrices (for instance im1 div im2)\n"
-      "- mlt, dv and pw operators, that perform multiplication, division or exponentiation of vector/matrices by a scalar (for instance im1 dv 2.0)\n"
-      "- bands, which is a very useful operator. It allows selecting specific bands from an image, and/or to rearrange them in a new vector;\n"
-      "for instance bands(im1,{1,2,1,1}) produces a vector of 4 components made of band 1, band 2, band 1 and band 1 values from the first input.\n"
-      "Note that curly brackets must be used in order to select the desired band indices.\n"
-      "... and so on.\n"
-
-      "\n\n"
-      "- Application itself:\n\n"
-      "The application takes the following parameters :\n"
-      "- Setting the list of inputs can be done with the 'il' parameter.\n"
-      "- Setting expressions can be done with the 'exp' parameter (see also limitations section below).\n"
-      "- Setting constants can be done with the 'incontext' parameter. User must provide a txt file with a specific syntax: #type name value\n"
-      "An example of such a file is given below:\n\n"
-      "#F expo 1.1\n"
-      "#M kernel1 { 0.1 , 0.2 , 0.3; 0.4 , 0.5 , 0.6; 0.7 , 0.8 , 0.9; 1 , 1.1 , 1.2; 1.3 , 1.4 , 1.5 }\n"
-      "\nAs we can see,  #I/#F allows the definition of an integer/float constant, whereas #M allows the definition of a vector/matrix.\n"
-      "In the latter case, elements of a row must be separated by commas, and rows must be separated by semicolons.\n"
-      "It is also possible to define expressions within the same txt file, with the pattern #E expr. For instance (two expressions; see also limitations section below):\n\n"
-      "#E $dotpr(kernel1,im1b1N3x5); im2b1^expo$\n"
-      "\n- The 'outcontext' parameter allows saving user's constants and expressions (context).\n"
-      "- Setting the output image can be done with the 'out' parameter (multi-outputs is not implemented yet).\n"
-      "\n\n"
-      "Finally, we strongly recommend that the reader takes a look at the cookbook, where additional information can be found (http://www.orfeo-toolbox.org/packages/OTBCookBook.pdf).\n"
-
-);
-
-    SetDocLimitations("The application is currently unable to produce one output image per expression, contrary to otbBandMathXImageFilter.\n"
-                      "Separating expressions by semi-colons (; ) will concatenate their results into a unique multiband output image. ");
-    SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
-    AddDocTag("Miscellaneous");
-
-    AddParameter(ParameterType_InputImageList,  "il",   "Input image list");
-    SetParameterDescription("il", "Image list to perform computation on.");
-
-    AddParameter(ParameterType_OutputImage, "out", "Output Image");
-    SetParameterDescription("out","Output image.");
+      "- existing operators/functions from muParserX, that were not originally "
+      "defined for vectors and matrices (e.g. cos, sin). These new "
+      "operators/functions keep the original names to which we added the prefix "
+      "'v' for vector (vcos, vsin, etc.)\n"
+      "- mult, div and pow operators, that perform element-wise multiplication, "
+      "division or exponentiation of vector/matrices (e.g. im1 div im2).\n"
+      "- mlt, dv and pw operators, that perform multiplication, division or "
+      "exponentiation of vector/matrices by a scalar (e.g. im1 dv 2.0).\n"
+      "- bands, which is a very useful operator. It allows selecting specific "
+      "bands from an image, and/or to rearrange them in a new vector (e.g."
+      "bands( im1, { 1, 2, 1, 1 } ) produces a vector of 4 components made of "
+      "band 1, band 2, band 1 and band 1 values from the first input.\n\n"
+      "Note that curly brackets must be used in order to select the desired band"
+      "indices.\n\n"
+
+      "The application itself\n"
+      "----------------------\n\n"
+
+      "The application takes the following parameters:\n"
+      "-il          Sets the list of inputs\n"
+      "-ext         Sets the mathematical expression (see also limitations "
+      "section below).\n"
+      "-incontext   Sets the text filename containing constants values (syntax: "
+      "'#type name value')\n\n"
+
+      "An example of such a file is given below:\n"
+      "  #F expo 1.1\n"
+      "  #M kernel1 { 0.1 , 0.2 , 0.3; 0.4 , 0.5 , 0.6; 0.7 , 0.8 , 0.9; 1 , 1.1"
+      ", 1.2; 1.3 , 1.4 , 1.5 }\n\n"
+
+      "As we can see, #I/#F allows the definition of an integer/float constant, "
+      "whereas #M allows the definition of a vector/matrix. In the latter case, "
+      "elements of a row must be separated by commas, and rows must be separated"
+      " by semicolons.\n\n"
+
+      "It is also possible to define expressions within the same txt file, with "
+      "#E <expr> (see limitations, below). For instance:\n"
+      "  #E $dotpr( kernel1, im1b1N3x5 ); im2b1^expo$\n\n"
+
+      "-outcontext  Output usesr's constants and expressions (context).\n"
+      "-out         Sets output image (multi-outputs is not implemented yet).\n"
+      "\n"
 
-    AddRAMParameter();
+      "Finally, we strongly recommend to read the OTB Cookbook which can be "
+      "found at: http://www.orfeo-toolbox.org/packages/OTBCookBook.pdf"
+    );
+
+    SetDocLimitations(
+      "The application is currently unable to produce one output image per "
+      "expression, contrary to otbBandMathXImageFilter.\n\n"
+      "Separating expressions by semi-colons ';' will concatenate their results "
+      "into a unique multiband output image."
+    );
+    SetDocAuthors( "OTB-Team" );
+    SetDocSeeAlso("[1] http://articles.beltoforion.de/article.php?a=muparserx\n"
+      "[2] BandMath");
+    AddDocTag( "Miscellaneous" );
 
-    AddParameter(ParameterType_String, "exp", "Expressions");
-    SetParameterDescription("exp",
-                            "Mathematical expression to apply.");
+    AddParameter( ParameterType_InputImageList, "il", "Input image-list" );
+    SetParameterDescription( "il", "Image-list to perform computation on." );
 
-    AddParameter(ParameterType_InputFilename, "incontext", "Import context");
-    SetParameterDescription("incontext",
-                            "A txt file containing user's constants and expressions.");
-    MandatoryOff("incontext");
+    AddParameter( ParameterType_OutputImage, "out", "Output Image" );
+    SetParameterDescription( "out", "Output image." );
+
+    AddRAMParameter();
 
-    AddParameter(ParameterType_OutputFilename, "outcontext", "Export context");
-    SetParameterDescription("outcontext",
-                            "A txt file where to save user's constants and expressions.");
-    MandatoryOff("outcontext");
+    AddParameter( ParameterType_String, "exp", "Expressions" );
+    SetParameterDescription(
+      "exp",
+      "Mathematical expression to apply."
+    );
+
+    AddParameter( ParameterType_InputFilename, "incontext", "Import context" );
+    SetParameterDescription(
+      "incontext",
+      "A txt file containing user's constants and expressions."
+    );
+    MandatoryOff( "incontext" );
+
+    AddParameter( ParameterType_OutputFilename, "outcontext", "Export context" );
+    SetParameterDescription(
+      "outcontext",
+      "A txt file where to save user's constants and expressions."
+    );
+    MandatoryOff( "outcontext" );
 
     // Doc example parameter settings
-    SetDocExampleParameterValue("il", "verySmallFSATSW_r.tif verySmallFSATSW_nir.tif verySmallFSATSW.tif");
-    SetDocExampleParameterValue("out", "apTvUtBandMathOutput.tif");
-    SetDocExampleParameterValue("exp", "\"cos(im1b1)+im2b1*im3b1-im3b2+ndvi(im3b3, im3b4)\"");
+    SetDocExampleParameterValue(
+      "il",
+      "verySmallFSATSW_r.tif verySmallFSATSW_nir.tif verySmallFSATSW.tif"
+    );
+    SetDocExampleParameterValue( "out", "apTvUtBandMathOutput.tif");
+    SetDocExampleParameterValue(
+      "exp",
+      "'cos( im1b1 ) + im2b1 * im3b1 - im3b2 + ndvi( im3b3, im3b4 )'"
+    );
 
     SetOfficialDocLink();
   }
diff --git a/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx b/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx
index 3593b85ed6b34fcbd4decaae1f40fa182dd95f46..79d9464a202674a8df71e89e6125ccb5d7aa07a2 100644
--- a/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx
+++ b/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx
@@ -103,7 +103,7 @@ private:
                                    "The output image can be :"
                                    "- A :math:`N` multi band image for the opening/closing normal or derivative profiles.\n"
                                    "- A mono band image for the opening/closing characteristics.\n"
-                                   "- A labeled image for the classification\n" );
+                                   "- A labeled image for the classification." );
     SetDocLimitations( "Generation of the morphological profile is not streamable, pay attention to this fact when setting the radius initial size and step of the structuring element." );
     SetDocAuthors( "OTB-Team" );
     SetDocSeeAlso( "otbMorphologicalOpeningProfileFilter, otbMorphologicalClosingProfileFilter, otbProfileToProfileDerivativeFilter, otbProfileDerivativeToMultiScaleCharacteristicsFilter, otbMultiScaleConvexOrConcaveClassificationFilter, classes" );
diff --git a/Modules/Applications/AppProjection/app/otbImageEnvelope.cxx b/Modules/Applications/AppProjection/app/otbImageEnvelope.cxx
index 4dcee6f2347d56c1c837f2d28b7ed558562fbb55..cda6b1fc64307e1a0fabc79c508d934b03156a1c 100644
--- a/Modules/Applications/AppProjection/app/otbImageEnvelope.cxx
+++ b/Modules/Applications/AppProjection/app/otbImageEnvelope.cxx
@@ -56,21 +56,25 @@ private:
 
     // Documentation
     SetDocName("Image Envelope");
-    SetDocLongDescription("Build a vector data containing the polygon of the image envelope.");
+    SetDocLongDescription("Build a vector data containing the image envelope polygon. "
+      "Useful for some projection, you can set the polygon with more points with the sr parameter. "
+      "This filter supports user-specified output projection. "
+      "If no projection is defined, the standard WGS84 projection will be used.");
+
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
 
     AddDocTag(Tags::Geometry);
 
-    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
-    SetParameterDescription("in", "Input image.");
+    AddParameter(ParameterType_InputImage, "in", "Input Image");
+    SetParameterDescription("in", "Input image filename.");
 
-    AddParameter(ParameterType_OutputVectorData,  "out",   "Output Vector Data");
-    SetParameterDescription("out", "Vector data file containing the envelope");
+    AddParameter(ParameterType_OutputVectorData, "out", "Output Vector Data");
+    SetParameterDescription("out", "Vector data file containing the envelope.");
 
     AddParameter(ParameterType_Int, "sr", "Sampling Rate");
-    SetParameterDescription("sr", "Sampling rate for image edges (in pixel)");
+    SetParameterDescription("sr", "Sampling rate for image edges (in pixel).");
     SetDefaultParameterInt("sr",0);
     MandatoryOff("sr");
     DisableParameter("sr");
diff --git a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
index d38349f8eab904fec0c2b4bba68648015bcc0295..4a91dda2f5183e34a8bd470684302805b54d5609 100644
--- a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
+++ b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
@@ -52,7 +52,7 @@ private:
 
     // Documentation
     SetDocName("SAR Radiometric calibration");
-    SetDocLongDescription("The objective of SAR calibration is to provide imagery in which the pixel values can be directly related to the radar backscatter of the scene. This application allows computing Sigma Naught (Radiometric Calibration) for TerraSAR-X, Sentinel1 L1 and Radarsat-2 sensors. Metadata are automatically retrieved from image products.The application supports complex and non-complex images (SLC or detected products).\n");
+    SetDocLongDescription("The objective of SAR calibration is to provide imagery in which the pixel values can be directly related to the radar backscatter of the scene. This application allows computing Sigma Naught (Radiometric Calibration) for TerraSAR-X, Sentinel1 L1 and Radarsat-2 sensors. Metadata are automatically retrieved from image products.The application supports complex and non-complex images (SLC or detected products).");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
diff --git a/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx b/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx
index 98bbd5924b8ffb5520adcfd53ceaa7d0389755ef..01e09464a313ffdabb1871be4266b8ade73948a0 100644
--- a/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx
+++ b/Modules/Applications/AppSARCalibration/app/otbSARDeburst.cxx
@@ -47,23 +47,38 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("SARDeburst");
-    SetDescription("This application performs a deburst operation by removing redundant lines. \n");
+    SetDescription("This application performs deburst of Sentinel1 IW SLC images by removing redundant lines.\n");
 
     // Documentation
     SetDocName("SAR Deburst");
-    SetDocLongDescription("This application performs a deburst operation by removing redundant lines between burst. This operation is useful when dealing with Sentinel1 IW SLC products, where each subswath is composed of several overlapping burst separated by black lines. Lines to remove are computed by SAR sensor model in OSSIM plugins. The output image is smaller in azimuth direction than the input line, because of removed lines. Note that the output sensor model is updated accordingly. This deburst filter is the perfect preprocessing step to orthorectify S1 IW SLC product with OTB without suffering from artifacts caused by bursts separation.\n");
-    SetDocLimitations("Only Sentinel1 IW SLC products are supported for now.");
+    SetDocLongDescription("Sentinel1 IW SLC products are composed of several burst overlapping in"
+                          " azimuth time for each subswath, separated by black lines [1]. The deburst"
+                          " operation consist in generating a continuous image in terms of azimuth"
+                          " time, by removing black separation lines as well as redundant lines"
+                          " between bursts.\n\n"
+                          
+                          "Note that the output sensor model is updated accordingly. This deburst"
+                          " operation is the perfect preprocessing step to orthorectify S1 IW SLC"
+                          " product with OTB [2] without suffering from artifacts caused by"
+                          " bursts separation.");
+    
+    SetDocLimitations("Only Sentinel1 IW SLC products are supported for now. Processing of"
+                      " other Sentinel1 modes or TerrasarX images will result in no changes in"
+                      " the image and metadata. Images from other sensors will lead to an"
+                      " error.");
+    
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("OrthoRectification");
+    SetDocSeeAlso("[1] Sentinel1 User Handbook, p. 52: https://sentinel.esa.int/documents/247904/685163/Sentinel-1_User_Handbook\n"
+                  "[2] OrthoRectification application");
 
-    AddDocTag(Tags::Calibration);
     AddDocTag(Tags::SAR);
+    AddDocTag(Tags::Calibration);
 
-    AddParameter(ParameterType_InputImage,  "in", "Input Image");
-    SetParameterDescription("in", "Input image");
+    AddParameter(ParameterType_InputImage,  "in", "Input Sentinel1 IW SLC Image");
+    SetParameterDescription("in", "Raw Sentinel1 IW SLC image, or any extract of such made by OTB (geom file needed)");
 
     AddParameter(ParameterType_OutputImage,  "out", "Output Image");
-    SetParameterDescription("out", "Output deburst image");
+    SetParameterDescription("out", "Deburst image, with updated geom file that can be further used by Orthorectification application. If the input image is a raw Sentinel1 product, uint16 output type should be used (encoding of S1 product). Otherwise, output type should match type of input image.");
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
index 8d0e99cffc0c68bc3239114eb1c76bf031a0e2b3..155795417f8c78b96317cd7676e4ed1294be90b4 100644
--- a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
+++ b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
@@ -97,7 +97,7 @@ private:
                           "In the coherent case, only the Pauli decomposition is available.\n"
                           "In the incoherent case, there the decompositions available : Huynen, Barnes, and H-alpha-A.\n"   
 						  "User must provide three one-band complex images HH, HV or VH, and VV (mono-static case <=> HV = VH).\n"
-						  "Incoherent decompositions consist in averaging 3x3 complex coherency/covariance matrices; the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize.\n "
+						  "Incoherent decompositions consist in averaging 3x3 complex coherency/covariance matrices; the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize."
 						  );
 						  
 						  
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
index e558ac68a08f7c3751a843556588c65860ca2e17..9c8c06211234eef4f9f8207c1762e6f10fbe88fb 100644
--- a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
@@ -222,7 +222,7 @@ private:
     
     "11 sinclairtomueller --> Sinclair matrix to Mueller matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 16 real channels)\n"
     "12 muellertomcovariance --> Mueller matrix to covariance matrix (input : 16 real channels | output : 6 complex channels)\n"
-    "13 muellertopoldegandpower --> Mueller matrix to polarization degree and power (input : 16 real channels | output : 4 real channels)\n"
+    "13 muellertopoldegandpower --> Mueller matrix to polarization degree and power (input : 16 real channels | output : 4 real channels)"
 
  );
 						  
diff --git a/Modules/Applications/AppSARPolarSynth/test/CMakeLists.txt b/Modules/Applications/AppSARPolarSynth/test/CMakeLists.txt
index e77967b05c1ca08b7f9d908a5ebce567a2273572..ebdaca7c686939019b1e019b25515494e919043d 100644
--- a/Modules/Applications/AppSARPolarSynth/test/CMakeLists.txt
+++ b/Modules/Applications/AppSARPolarSynth/test/CMakeLists.txt
@@ -23,7 +23,7 @@ otb_module_test()
 
 otb_test_application(NAME  apTvSARPolarSynth
                      APP  SARPolarSynth
-                     OPTIONS -in ${INPUTDATA}/RSAT2_AltonaExtract_1000_1000_100_100.hdr
+                     OPTIONS -in ${INPUTDATA}/RSAT2_AltonaExtract_1000_1000_100_100.tif
                	             -out ${TEMP}/resApMultiPolarimetricSynthesis1.tif
                              -psii 10.0 
                              -khii 0.0
diff --git a/Modules/Applications/AppSARUtils/app/CMakeLists.txt b/Modules/Applications/AppSARUtils/app/CMakeLists.txt
index f0e7132c08c68baa6c95c2bc7dd114974e26278f..6f0e019f716c745c675961dc0e61923595171dd3 100644
--- a/Modules/Applications/AppSARUtils/app/CMakeLists.txt
+++ b/Modules/Applications/AppSARUtils/app/CMakeLists.txt
@@ -1,5 +1,8 @@
 set(OTBAppSARUtils_LINK_LIBS
   ${OTBSARUtils_LIBRARIES}
+  {OTBImageNoise_LIBRARIES}
+  ${OTBImageBase_LIBRARIES}
+  ${OTBITK_LIBRARIES}
   ${OTBApplicationEngine_LIBRARIES}
 )
 
@@ -7,3 +10,8 @@ otb_create_application(
   NAME           ComputeModulusAndPhase
   SOURCES        otbComputeModulusAndPhase.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
+otb_create_application(
+  NAME           Despeckle
+  SOURCES        otbDespeckle.cxx
+  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
diff --git a/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx b/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx
index a1ec51a1d3df70c47a5bb4016b7f93d6fd98395d..39db311e799737b730973d68c5156d273366896b 100644
--- a/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx
+++ b/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx
@@ -20,11 +20,11 @@
 
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
-#include <otbMultiToMonoChannelExtractROI.h>
+#include "otbMultiToMonoChannelExtractROI.h"
 
 #include "itkComplexToPhaseImageFilter.h"
 #include "itkComplexToModulusImageFilter.h"
-#include <itkMacro.h>
+#include "itkMacro.h"
 
 namespace otb
 {
@@ -68,21 +68,26 @@ private:
       "complex SAR image. The input should be a single band image with "
       "complex pixels."
     );
-    SetDocLimitations("None");
+    SetDocLimitations("The application takes as input single band image with complex pixels.");
     SetDocAuthors("Alexia Mondot (alexia.mondot@c-s.fr) and Mickael Savinaud (mickael.savinaud@c-s.fr)");
-    SetDocSeeAlso("SARPolarMatrixConvert, SARPolarSynth");
-    AddDocTag(Tags::SAR);
+    SetDocSeeAlso("Despeckle, SARPolarMatrixConvert, SARPolarSynth");
 
+    AddDocTag(Tags::SAR);
+    AddDocTag(Tags::Manip);
     // Input images
     AddParameter(ParameterType_ComplexInputImage,  "in",   "Input Image");
     SetParameterDescription("in", "Input image (complex single band)");
 
     // Outputs
     AddParameter(ParameterType_OutputImage, "modulus", "Modulus");
-    SetParameterDescription("modulus", "Modulus of the input: sqrt(real*real + imag*imag).");
-
+    SetParameterDescription("modulus", "Modulus of the input image computes with the\n"
+                            "following formula: :math:`\\sqrt{real*real + imag*imag}` where real and imag \n"
+                            "are respectively the real and the imaginary part of the input complex image.\n");
+    
     AddParameter(ParameterType_OutputImage, "phase", "Phase");
-    SetParameterDescription("phase", "Phase of the input: atan2(imag, real).");
+    SetParameterDescription("phase", "Phase of the input image computes with the following formula:\n"
+    ":math:`\\tan^{-1}(\\frac{imag}{real})` where real and imag are respectively the real and\n"
+    "the imaginary part of the input complex image.");
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppFiltering/app/otbDespeckle.cxx b/Modules/Applications/AppSARUtils/app/otbDespeckle.cxx
similarity index 64%
rename from Modules/Applications/AppFiltering/app/otbDespeckle.cxx
rename to Modules/Applications/AppSARUtils/app/otbDespeckle.cxx
index 2d3a2de8d2d280d82070dbffff49e44f0c18d4d4..f469402397ec95185ecdfb5ed8c99009b550b594 100644
--- a/Modules/Applications/AppFiltering/app/otbDespeckle.cxx
+++ b/Modules/Applications/AppSARUtils/app/otbDespeckle.cxx
@@ -61,13 +61,44 @@ private:
 
     // Documentation
     SetDocName("Despeckle");
-    SetDocLongDescription("This application reduce speckle noise. Four methods are available: Lee, Frost, GammaMAP and Kuan.");
-    SetDocLimitations("None");
+    SetDocLongDescription("SAR images are affected by speckle noise that inherently exists in and which"
+     " degrades the image quality. It is caused by the coherent nature of"
+     " back-scattered waves from multiple distributed targets. It is locally strong"
+     " and it increases the mean Grey level of a local area. \n\n"
+     "Reducing the speckle noise enhances radiometric resolution but tend to decrease the spatial resolution."
+     "Several different methods are used to eliminate speckle noise, based upon"
+     " different mathematical models of the phenomenon. The application includes four"
+     " methods: Lee [1], Frost [2], GammaMAP [3] and Kuan [4]. \n\n"
+     "We sum up below the basic principle of this four methods:\n"
+      "  * Lee : Estimate the signal by mean square error minimization (MMSE) on a sliding window.\n"
+      "  * Frost : Also derived from the MMSE criteria with a weighted sum of the values within the window. The weighting factors decrease with distance from the pixel of interest.\n"
+      "  * GammaMAP  : Derived under the assumption of the image follows a Gamma distribution.\n"
+      "  * Kuan : Also derived from the MMSE criteria under the assumption of non stationary mean and variance. It is quite similar to Lee filter in form."
+      );
+
+    SetDocLimitations("The application does not handle complex image as input.");
+
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+
+    SetDocSeeAlso("[1] J. Lee. Digital image enhancement and noise filtering by"
+                  "use of local statistics. IEEE Transactions on Pattern Analysis and Machine"
+                  "Intelligence, 2:165–168, 1980.\n"
+                  "[2] V. S. Frost, et al., A Model for Radar Images and Its"
+                  "Application to Adaptive Digital Filtering of Multiplicative"
+                  "Noise, IEEE Trans. Pattern Anal., Machine Intell., vol. 4,"
+                  "no. 2, pp. 157-166, Mar. 1982.\n"
+                  "[3] A. Lopes, E. Nezry, R. Touzi and H. Laur, Maximum A"
+                  "Posteriori Speckle Filtering And First Order Texture Models"
+                  "In Sar Images, 10th" "Annual International Symposium on"
+                  "Geoscience and Remote Sensing, 1990,pp. 2409-2412.  doi:"
+                  "10.1109/IGARSS.1990.689026\n"
+                  "[4] Kuan, D.  T., Sawchuk, A.  A., Strand, T.  C, and Chavel,"
+                  "P., 1987.  Adaptive restoration of image with speckle.  IEEE"
+                  "Trans on Acoustic Speech and Signal Processing, 35,"
+                  "pp. 373-383.");
 
     AddDocTag(Tags::Filter);
-	AddDocTag(Tags::SAR);
+	  AddDocTag(Tags::SAR);
 
     AddParameter(ParameterType_InputImage,  "in",   "Input Image");
     SetParameterDescription("in", "Input image.");
@@ -76,39 +107,47 @@ private:
 
     AddRAMParameter();
 
-    AddParameter(ParameterType_Choice,"filter","speckle filtering method");
+    AddParameter(ParameterType_Choice,"filter","Speckle filtering method");
+    
     AddChoice("filter.lee","Lee");
     SetParameterDescription("filter.lee","Lee filter");
+
     AddChoice("filter.frost","Frost");
     SetParameterDescription("filter.frost","Frost filter");
+
     AddChoice("filter.gammamap","GammaMap");
     SetParameterDescription("filter.gammamap","GammaMap filter");
+
     AddChoice("filter.kuan","Kuan");
     SetParameterDescription("filter.kuan","Kuan filter");
 
     AddParameter(ParameterType_Int,"filter.lee.rad","Radius");
-    SetParameterDescription("filter.lee.rad","Radius for lee filter");
+    SetParameterDescription("filter.lee.rad","Radius in pixel");
 
-    AddParameter(ParameterType_Float,"filter.lee.nblooks","nb looks");
-    SetParameterDescription("filter.lee.nblooks","Nb looks for lee filter");
+    AddParameter(ParameterType_Float,"filter.lee.nblooks","Number of looks");
+    SetParameterDescription("filter.lee.nblooks","Number of looks in the input image.");
 
     AddParameter(ParameterType_Int,"filter.frost.rad","Radius");
-    SetParameterDescription("filter.frost.rad","Radius for frost filter");
-
-    AddParameter(ParameterType_Float,"filter.frost.deramp","deramp");
-    SetParameterDescription("filter.frost.deramp","Decrease factor declaration");
+    SetParameterDescription("filter.frost.rad","Radius in pixel.");
+
+    AddParameter(ParameterType_Float,"filter.frost.deramp","Deramp factor");
+    SetParameterDescription("filter.frost.deramp","factor use to control the\n"
+       "exponential function used to weight effect of the distance between the\n"
+       "central pixel and its neighborhood. Increasing the deramp parameter will\n"
+       "lead to take more into account pixels farther from the center and\n"
+       "therefore increase the smoothing effects.");
     
     AddParameter(ParameterType_Int,"filter.gammamap.rad","Radius");
-    SetParameterDescription("filter.gammamap.rad","Radius for GammaMAP filter");
+    SetParameterDescription("filter.gammamap.rad","Radius in pixel.");
 
-    AddParameter(ParameterType_Float,"filter.gammamap.nblooks","nb looks");
-    SetParameterDescription("filter.gammamap.nblooks","Nb looks for GammaMAP filter");
+    AddParameter(ParameterType_Float,"filter.gammamap.nblooks","Number of looks");
+    SetParameterDescription("filter.gammamap.nblooks","Number of looks in the input image.");
     
     AddParameter(ParameterType_Int,"filter.kuan.rad","Radius");
-    SetParameterDescription("filter.kuan.rad","Radius for Kuan filter");
+    SetParameterDescription("filter.kuan.rad","Radius in pixel.");
 
-    AddParameter(ParameterType_Float,"filter.kuan.nblooks","nb looks");
-    SetParameterDescription("filter.kuan.nblooks","Nb looks for Kuan filter");
+    AddParameter(ParameterType_Float,"filter.kuan.nblooks","Number of looks");
+    SetParameterDescription("filter.kuan.nblooks","Number of looks in the input image.");
 
     // Default values
     SetDefaultParameterInt("filter.lee.rad", 1);
diff --git a/Modules/Applications/AppSARUtils/otb-module.cmake b/Modules/Applications/AppSARUtils/otb-module.cmake
index 41a1b43467aa97d35721a46dd6f4e4f4ad6b04be..964acb5a4f4f01fcfc86bd030df4e067da8af680 100644
--- a/Modules/Applications/AppSARUtils/otb-module.cmake
+++ b/Modules/Applications/AppSARUtils/otb-module.cmake
@@ -3,6 +3,10 @@ set(DOCUMENTATION "SAR Utils application.")
 otb_module(OTBAppSARUtils
   DEPENDS
     OTBApplicationEngine
+    OTBImageNoise
+    OTBImageBase
+    OTBITK
+    
   TEST_DEPENDS
     OTBTestKernel
     OTBCommandLine
diff --git a/Modules/Applications/AppSARUtils/test/CMakeLists.txt b/Modules/Applications/AppSARUtils/test/CMakeLists.txt
index 65dc6b75a9de038c360f9671a1a83c357a020bed..4c7a02ec56f895c2712aaa68237b8d643fe998d7 100644
--- a/Modules/Applications/AppSARUtils/test/CMakeLists.txt
+++ b/Modules/Applications/AppSARUtils/test/CMakeLists.txt
@@ -1,13 +1,79 @@
+#
+# Copyright (C) 2005-2017 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.
+#
+
 otb_module_test()
 #----------- ComputeModulusAndPhase TESTS ----------------
 otb_test_application(NAME apTvUtComputeModulusAndPhase_1inputComplex
-                     APP  ComputeModulusAndPhase
-                     OPTIONS -in ${INPUTDATA}/monobandComplexFloat.tif
-                             -modulus ${TEMP}/apTvUtMod1inputComplex.tif
-                             -phase ${TEMP}/apTvUtPha1inputComplex.tif
-                     VALID   --compare-n-images ${EPSILON_6} 2
-                             ${BASELINE}/Mod_monobandComplexFloat.tif
-                             ${TEMP}/apTvUtMod1inputComplex.tif
-                             ${BASELINE}/Pha_monobandComplexFloat.tif
-                             ${TEMP}/apTvUtPha1inputComplex.tif
-                     )
+  APP  ComputeModulusAndPhase
+  OPTIONS -in ${INPUTDATA}/monobandComplexFloat.tif
+  -modulus ${TEMP}/apTvUtMod1inputComplex.tif
+  -phase ${TEMP}/apTvUtPha1inputComplex.tif
+  VALID   --compare-n-images ${EPSILON_6} 2
+  ${BASELINE}/Mod_monobandComplexFloat.tif
+  ${TEMP}/apTvUtMod1inputComplex.tif
+  ${BASELINE}/Pha_monobandComplexFloat.tif
+  ${TEMP}/apTvUtPha1inputComplex.tif
+  )
+
+#----------- Despeckle TESTS ----------------
+
+otb_test_application(NAME  apTvDespeckleLee
+  APP  Despeckle
+  OPTIONS -in ${INPUTDATA}/GomaAvant.tif
+  -out ${TEMP}/bfFiltreLee_05_05_12_app.tif
+  -filter lee
+  -filter.lee.rad 5
+  -filter.lee.nblooks 12
+  VALID   --compare-image ${EPSILON_7}
+  ${BASELINE}/bfFiltreLee_05_05_12.tif
+  ${TEMP}/bfFiltreLee_05_05_12_app.tif)
+
+otb_test_application(NAME  apTvDespeckleFrost
+  APP  Despeckle
+  OPTIONS -in ${INPUTDATA}/GomaAvant.tif
+  -out ${TEMP}/bfFiltreFrost_05_05_12_app.tif
+  -filter frost
+  -filter.frost.rad 5
+  -filter.frost.deramp 0.1
+  VALID   --compare-image ${EPSILON_7}
+  ${BASELINE}/bfFiltreFrost_05_05_12_app.tif
+  ${TEMP}/bfFiltreFrost_05_05_12_app.tif)
+
+otb_test_application(NAME  apTvDespeckleGammaMAP
+  APP  Despeckle
+  OPTIONS -in ${INPUTDATA}/GomaAvant.tif
+  -out ${TEMP}/bfFiltreGammaMAP_05_05_12_app.tif
+  -filter gammamap
+  -filter.gammamap.rad 5
+  -filter.gammamap.nblooks 12
+  VALID   --compare-image ${EPSILON_7}
+  ${BASELINE}/bfFiltreGammaMAP_05_05_12.tif
+  ${TEMP}/bfFiltreGammaMAP_05_05_12_app.tif)                      
+
+otb_test_application(NAME  apTvDespeckleKuan
+  APP  Despeckle
+  OPTIONS -in ${INPUTDATA}/GomaAvant.tif
+  -out ${TEMP}/bfFiltreKuan_05_05_12_app.tif
+  -filter kuan
+  -filter.kuan.rad 5
+  -filter.kuan.nblooks 12
+  VALID   --compare-image ${EPSILON_7}
+  ${BASELINE}/bfFiltreKuan_05_05_12.tif
+  ${TEMP}/bfFiltreKuan_05_05_12_app.tif)
diff --git a/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx
index dd624673d0490e3d74402faba8a41f904868aa60..93694cc420dcc271c6dff0ac551d43d519acd2b4 100644
--- a/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbLSMSSegmentation.cxx
@@ -217,51 +217,83 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("LSMSSegmentation");
-    SetDescription("Second step of the exact Large-Scale Mean-Shift segmentation workflow.");
+    SetDescription("This application performs the second step of the exact Large-Scale Mean-Shift segmentation workflow (LSMS) [1].");
 
     SetDocName("Exact Large-Scale Mean-Shift segmentation, step 2");
-    SetDocLongDescription("This application performs the second step of the exact Large-Scale Mean-Shift segmentation workflow (LSMS). Filtered range image and spatial image should be created with the MeanShiftSmoothing application, with modesearch parameter disabled. If spatial image is not set, the application will only process the range image and spatial radius parameter will not be taken into account. This application will produce a labeled image where neighbor pixels whose range distance is below range radius (and optionally spatial distance below spatial radius) will be grouped together into the same cluster. For large images one can use the nbtilesx and nbtilesy parameters for tile-wise processing, with the guarantees of identical results. Please note that this application will generate a lot of temporary files (as many as the number of tiles), and will therefore require twice the size of the final result in term of disk space. The cleanup option (activated by default) allows removing all temporary file as soon as they are not needed anymore (if cleanup is activated, tmpdir set and tmpdir does not exists before running the application, it will be removed as well during cleanup). The tmpdir option allows defining a directory where to write the temporary files. Please also note that the output image type should be set to uint32 to ensure that there are enough labels available.");
-    SetDocLimitations("This application is part of the Large-Scale Mean-Shift segmentation workflow (LSMS) and may not be suited for any other purpose.");
+    SetDocLongDescription("This application will produce a labeled image where neighbor pixels"
+                          " whose range distance is below range radius (and optionally spatial"
+                          " distance below spatial radius) will be grouped together into the same"
+                          " cluster. For large images one can use the tilesizex and tilesizey"
+                          " parameters for tile-wise processing, with the guarantees of identical"
+                          " results.\n\n"
+                          "Filtered range image and spatial image should be created with the"
+                          " MeanShiftSmoothing application outputs (fout and foutpos) [2], with"
+                          " modesearch parameter disabled. If spatial image is not set, the"
+                          " application will only process the range image and spatial radius"
+                          " parameter will not be taken into account.\n\n"
+                          "Please note that this application will generate a lot of temporary"
+                          " files (as many as the number of tiles), and will therefore require"
+                          " twice the size of the final result in term of disk space. The cleanup"
+                          " option (activated by default) allows removing all temporary file as"
+                          " soon as they are not needed anymore (if cleanup is activated, tmpdir"
+                          " set and tmpdir does not exists before running the application, it will"
+                          " be removed as well during cleanup). The tmpdir option allows defining"
+                          " a directory where to write the temporary files.\n\n"
+                          "Please also note that the output image type should be set to uint32 to"
+                          " ensure that there are enough labels available.\n\n"
+                          "The output of this application can be passed to the"
+                          " LSMSSmallRegionMerging [3] or LSMSVectorization [4] applications to"
+                          " complete the LSMS workflow.");
+    SetDocLimitations("This application is part of the Large-Scale Mean-Shift segmentation"
+                      " workflow (LSMS) [1] and may not be suited for any other purpose. This"
+                      " application is not compatible with in-memory connection since it does"
+                      " its own internal streaming.");
     SetDocAuthors("David Youssefi");
-    SetDocSeeAlso("MeanShiftSmoothing, LSMSSmallRegionsMerging, LSMSVectorization");
+    SetDocSeeAlso( "[1] Michel, J., Youssefi, D., & Grizonnet, M. (2015). Stable"
+                   " mean-shift algorithm and its application to the segmentation of"
+                   " arbitrarily large remote sensing images. IEEE Transactions on"
+                   " Geoscience and Remote Sensing, 53(2), 952-964.\n"
+                   "[2] MeanShiftSmoothing\n"
+                   "[3] LSMSSmallRegionsMerging\n"
+                   "[4] LSMSVectorization");
     AddDocTag(Tags::Segmentation);
     AddDocTag("LSMS");
 
     AddParameter(ParameterType_InputImage,  "in",    "Filtered image");
-    SetParameterDescription( "in", "The filtered image (cf. Adaptive MeanShift Smoothing application)." );
-    AddParameter(ParameterType_InputImage,  "inpos",    "Spatial image");
-    SetParameterDescription( "inpos", " The spatial image. Spatial input is the displacement map (output of the Adaptive MeanShift Smoothing application)." );
+    SetParameterDescription( "in", "The filtered image, corresponding to the fout output parameter of the MeanShiftSmoothing application." );
+    AddParameter(ParameterType_InputImage,  "inpos",    "Filtered position image");
+    SetParameterDescription( "inpos", " The filtered position image, corresponding to the foutpos output parameter of the MeanShiftSmoothing application.");
     MandatoryOff("inpos");
 
-    AddParameter(ParameterType_OutputImage, "out", "Output Image");
-    SetParameterDescription( "out", "The output image. The output image is the segmentation of the filtered image. It is recommended to set the pixel type to uint32." );
+    AddParameter(ParameterType_OutputImage, "out", "Output labeled Image");
+    SetParameterDescription( "out", "This output contains the segmented image, where each pixel value is the unique integer label of the segment it belongs to. It is recommended to set the pixel type to uint32." );
     SetDefaultOutputPixelType("out",ImagePixelType_uint32);
 
     AddParameter(ParameterType_Float, "spatialr", "Spatial radius");
-    SetParameterDescription("spatialr", "Spatial radius of the neighborhood.");
+    SetParameterDescription("spatialr", "Threshold on Spatial distance to consider pixels in the same segment. A good value is half the spatial radius used in the MeanShiftSmoothing application (spatialr parameter).");
     SetDefaultParameterFloat("spatialr", 5);
     SetMinimumParameterFloatValue("spatialr", 0);
     MandatoryOff("spatialr");
     
     AddParameter(ParameterType_Float, "ranger", "Range radius");
-    SetParameterDescription("ranger", "Range radius defining the radius (expressed in radiometry unit) in the multi-spectral space.");
+    SetParameterDescription("ranger", "Threshold on spectral signature euclidean distance (expressed in radiometry unit) to consider pixels in the same segment. A good value is half the range radius used in the MeanShiftSmoothing application (ranger parameter).");
     SetDefaultParameterFloat("ranger", 15);
     SetMinimumParameterFloatValue("ranger", 0);
     MandatoryOff("ranger");
 
-    AddParameter(ParameterType_Int, "minsize", "Minimum Region Size");
-    SetParameterDescription("minsize", "Minimum Region Size. If, after the segmentation, a region is of size lower than this criterion, the region is deleted.");
+    AddParameter(ParameterType_Int, "minsize", "Minimum Segment Size");
+    SetParameterDescription("minsize", "Minimum Segment Size. If, after the segmentation, a segment is of size lower than this criterion, the segment is discarded.");
     SetDefaultParameterInt("minsize", 0);
     SetMinimumParameterIntValue("minsize", 0);
     MandatoryOff("minsize");
 
     AddParameter(ParameterType_Int, "tilesizex", "Size of tiles in pixel (X-axis)");
-    SetParameterDescription("tilesizex", "Size of tiles along the X-axis.");
+    SetParameterDescription("tilesizex", "Size of tiles along the X-axis for tile-wise processing.");
     SetDefaultParameterInt("tilesizex", 500);
     SetMinimumParameterIntValue("tilesizex", 1);
 
     AddParameter(ParameterType_Int, "tilesizey", "Size of tiles in pixel (Y-axis)");
-    SetParameterDescription("tilesizey", "Size of tiles along the Y-axis.");
+    SetParameterDescription("tilesizey", "Size of tiles along the Y-axis for tile-wise processing.");
     SetDefaultParameterInt("tilesizey", 500);
     SetMinimumParameterIntValue("tilesizey", 1);
 
@@ -272,7 +304,7 @@ private:
 
     AddParameter(ParameterType_Empty,"cleanup","Temporary files cleaning");
     EnableParameter("cleanup");
-    SetParameterDescription("cleanup","If activated, the application will try to clean all temporary files it created");
+    SetParameterDescription("cleanup","If activated, the application will try to remove all temporary files it created.");
     MandatoryOff("cleanup");
 
     // Doc example parameter settings
diff --git a/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx b/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
index dc04847b2c8e5c4137cb6dd695368786ca33835f..14c8354a143503d61ddbc3680512d5eb6ccb5143 100644
--- a/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
@@ -76,38 +76,58 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("LSMSSmallRegionsMerging");
-    SetDescription("Third (optional) step of the exact Large-Scale Mean-Shift segmentation workflow.");
+    SetDescription("This application performs the third (optional) step of the exact Large-Scale Mean-Shift segmentation workflow [1].");
 
     SetDocName("Exact Large-Scale Mean-Shift segmentation, step 3 (optional)");
-    SetDocLongDescription("This application performs the third step of the exact Large-Scale Mean-Shift segmentation workflow (LSMS). Given a segmentation result (label image) and the original image, it will merge regions whose size in pixels is lower than minsize parameter with the adjacent regions with the adjacent region with closest radiometry and acceptable size. Small regions will be processed by size: first all regions of area, which is equal to 1 pixel will be merged with adjacent region, then all regions of area equal to 2 pixels, until regions of area minsize. For large images one can use the nbtilesx and nbtilesy parameters for tile-wise processing, with the guarantees of identical results.");
-    SetDocLimitations("This application is part of the Large-Scale Mean-Shift segmentation workflow (LSMS) and may not be suited for any other purpose.");
+    SetDocLongDescription("Given a segmentation result (can be the out output parameter of the"
+                          " LSMSSegmentation application [2]) and the original image, it will"
+                          " merge segments whose size in pixels is lower than minsize parameter"
+                          " with the adjacent segments with the adjacent segment with closest"
+                          " radiometry and acceptable size.\n\n"
+                          "Small segments will be processed by increasing size: first all segments"
+                          " for which area is equal to 1 pixel will be merged with adjacent"
+                          " segments, then all segments of area equal to 2 pixels will be processed,"
+                          " until segments of area minsize. For large images one can use the"
+                          " tilesizex and tilesizey parameters for tile-wise processing, with the"
+                          " guarantees of identical results.\n\n"
+                          "The output of this application can be passed to the"
+                          " LSMSVectorization application [3] to complete the LSMS workflow.");
+    SetDocLimitations("This application is part of the Large-Scale Mean-Shift segmentation"
+                      " workflow (LSMS) and may not be suited for any other purpose. This"
+                      " application is not compatible with in-memory connection since it does"
+                      " its own internal streaming.");
     SetDocAuthors("David Youssefi");
-    SetDocSeeAlso("LSMSSegmentation, LSMSVectorization, MeanShiftSmoothing");
+    SetDocSeeAlso( "[1] Michel, J., Youssefi, D., & Grizonnet, M. (2015). Stable"
+                   " mean-shift algorithm and its application to the segmentation of"
+                   " arbitrarily large remote sensing images. IEEE Transactions on"
+                   " Geoscience and Remote Sensing, 53(2), 952-964.\n"
+                   "[2] LSMSegmentation\n"
+                   "[3] LSMSVectorization");
     AddDocTag(Tags::Segmentation);
     AddDocTag("LSMS");
 
     AddParameter(ParameterType_InputImage,  "in",    "Input image");
-    SetParameterDescription( "in", "The input image." );
+    SetParameterDescription( "in", "The input image, containing initial spectral signatures corresponding to the segmented image (inseg)." );
     AddParameter(ParameterType_InputImage,  "inseg",    "Segmented image");
-    SetParameterDescription( "inseg", " The segmented image input. Segmented image input is the segmentation of the input image." );
+    SetParameterDescription( "inseg", "Segmented image where each pixel value is the unique integer label of the segment it belongs to." );
 
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
-    SetParameterDescription( "out", "The output image. The output image is the input image where the minimal regions have been merged." );
+    SetParameterDescription( "out", "The output image. The output image is the segmented image where the minimal segments have been merged. An ecoding of uint32 is advised." );
     SetDefaultOutputPixelType("out",ImagePixelType_uint32);
 
-    AddParameter(ParameterType_Int, "minsize", "Minimum Region Size");
-    SetParameterDescription("minsize", "Minimum Region Size. If, after the segmentation, a region is of size lower than this criterion, the region is merged with the \"nearest\" region (radiometrically).");
+    AddParameter(ParameterType_Int, "minsize", "Minimum Segment Size");
+    SetParameterDescription("minsize", "Minimum Segment Size. If, after the segmentation, a segment is of size lower than this criterion, the segment is merged with the segment that has the closest sepctral signature.");
     SetDefaultParameterInt("minsize", 50);
     SetMinimumParameterIntValue("minsize", 0);
     MandatoryOff("minsize");
 
     AddParameter(ParameterType_Int, "tilesizex", "Size of tiles in pixel (X-axis)");
-    SetParameterDescription("tilesizex", "Size of tiles along the X-axis.");
+    SetParameterDescription("tilesizex", "Size of tiles along the X-axis for tile-wise processing.");
     SetDefaultParameterInt("tilesizex", 500);
     SetMinimumParameterIntValue("tilesizex", 1);
 
     AddParameter(ParameterType_Int, "tilesizey", "Size of tiles in pixel (Y-axis)");
-    SetParameterDescription("tilesizey", "Size of tiles along the Y-axis.");
+    SetParameterDescription("tilesizey", "Size of tiles along the Y-axis for tile-wise processing.");
     SetDefaultParameterInt("tilesizey", 500);
     SetMinimumParameterIntValue("tilesizey", 1);
 
diff --git a/Modules/Applications/AppSegmentation/app/otbLSMSVectorization.cxx b/Modules/Applications/AppSegmentation/app/otbLSMSVectorization.cxx
index aa3ea2a1be6bb89977ebe11083f27168bf92ecf3..166b87141dc47b313e1eb5b388f55cbfd2dccb01 100644
--- a/Modules/Applications/AppSegmentation/app/otbLSMSVectorization.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbLSMSVectorization.cxx
@@ -69,31 +69,46 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("LSMSVectorization");
-    SetDescription("Fourth step of the exact Large-Scale Mean-Shift segmentation workflow.");
+    SetDescription("This application performs the fourth step of the exact Large-Scale Mean-Shift segmentation workflow [1].");
 
     SetDocName("Exact Large-Scale Mean-Shift segmentation, step 4");
-    SetDocLongDescription("This application performs the fourth step of the exact Large-Scale Mean-Shift segmentation workflow (LSMS). Given a segmentation result (label image), that may have been processed for small regions merging or not, it will convert it to a GIS vector file containing one polygon per segment. Each polygon contains additional fields: mean and variance of each channels from input image (in parameter), segmentation image label, number of pixels in the polygon. For large images one can use the nbtilesx and nbtilesy parameters for tile-wise processing, with the guarantees of identical results.");
+    SetDocLongDescription("Given a segmentation result (label image), that may come from the"
+                          " LSMSSegmentation [2] application (out parameter) or have been"
+                          " processed for small regions merging [3] (out parameter), it will"
+                          " convert it to a GIS vector file containing one polygon per"
+                          " segment. Each polygon contains additional fields: mean and variance of"
+                          " each channels from input image (in parameter), segmentation image"
+                          " label, number of pixels in the polygon. For large images one can use"
+                          " the tilesizex and tilesizey parameters for tile-wise processing, with"
+                          " the guarantees of identical results.");
     SetDocLimitations("This application is part of the Large-Scale Mean-Shift segmentation workflow (LSMS) and may not be suited for any other purpose.");
     SetDocAuthors("David Youssefi");
-    SetDocSeeAlso("MeanShiftSmoothing, LSMSSegmentation, LSMSSmallRegionsMerging");
+
+    SetDocSeeAlso( "[1] Michel, J., Youssefi, D., & Grizonnet, M. (2015). Stable"
+                   " mean-shift algorithm and its application to the segmentation of"
+                   " arbitrarily large remote sensing images. IEEE Transactions on"
+                   " Geoscience and Remote Sensing, 53(2), 952-964.\n"
+                   "[2] LSMSegmentation\n"
+                   "[3] LSMSmallRegionMerging");
+
     AddDocTag(Tags::Segmentation);
     AddDocTag("LSMS");
 
     AddParameter(ParameterType_InputImage, "in", "Input Image");
-    SetParameterDescription( "in", "The input image." );
+    SetParameterDescription( "in", "The input image, containing initial spectral signatures corresponding to the segmented image (inseg)." );
     AddParameter(ParameterType_InputImage,  "inseg",    "Segmented image");
-    SetParameterDescription( "inseg", " The segmented image input. Segmented image input is the segmentation of the input image." );
+    SetParameterDescription( "inseg", "Segmented image where each pixel value is the unique integer label of the segment it belongs to.");
 
     AddParameter(ParameterType_OutputFilename, "out", "Output GIS vector file");
     SetParameterDescription( "out", "The output GIS vector file, representing the vectorized version of the segmented image where the features of the polygons are the radiometric means and variances." );
 
     AddParameter(ParameterType_Int, "tilesizex", "Size of tiles in pixel (X-axis)");
-    SetParameterDescription("tilesizex", "Size of tiles along the X-axis.");
+    SetParameterDescription("tilesizex", "Size of tiles along the X-axis for tile-wise processing.");
     SetDefaultParameterInt("tilesizex", 500);
     SetMinimumParameterIntValue("tilesizex", 1);
 
     AddParameter(ParameterType_Int, "tilesizey", "Size of tiles in pixel (Y-axis)");
-    SetParameterDescription("tilesizey", "Size of tiles along the Y-axis.");
+    SetParameterDescription("tilesizey", "Size of tiles along the Y-axis for tile-wise processing.");
     SetDefaultParameterInt("tilesizey", 500);
     SetMinimumParameterIntValue("tilesizey", 1);
 
diff --git a/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx b/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx
index 6f34edd86e8fee07d85cde3147e195f0436abd83..1219f24c1a9876a30ba77a55277442247a43e26b 100644
--- a/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbMeanShiftSmoothing.cxx
@@ -49,61 +49,118 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("MeanShiftSmoothing");
-    SetDescription("Perform mean shift filtering");
+    SetDescription("This application smooths an image using the MeanShift algorithm.");
 
     // Documentation
-    SetDocName("Exact Large-Scale Mean-Shift segmentation, step 1 (smoothing)");
-    SetDocLongDescription("This application performs mean shift fitlering (multi-threaded).");
-    SetDocLimitations("With mode search option, the result will slightly depend on thread number.");
+    SetDocName("MeanShift Smoothing");
+    SetDocLongDescription("MeanShift [1,2,3] is an iterative edge-preserving image smoothing"
+                          " algorithm often used in image processing and as a first step for"
+                          " image segmentation. The MeanShift algorithm can be applied to"
+                          " multispectral images.\n\n"
+                          "At first iteration, for any given pixel of the input image, the"
+                          " filtered value correspond to the average spectral signature of"
+                          " neighborhood pixels that are both spatially closer than the spatial"
+                          " radius parameter (spatialr) and with spectral signature that have an euclidean"
+                          " distance to the input pixel lower than the range radius (ranger), that is,"
+                          " pixels that are both close in space and in spectral signatures."
+                          " Subsequent iterations will repeat this process by considering that"
+                          " the pixel signature corresponds to the average spectral signature"
+                          " computed during previous iteration, and that the pixel position"
+                          " corresponds to the average position of pixels used to compute the"
+                          " average signature."
+                          "The algorithm stops when the maximum number of iterations (maxiter) is reached,"
+                          " or when the position and spectral signature does not change much"
+                          " between iterations, according to the convergence threshold (thres). If the"
+                          " modesearch option is used then convergence will also stops if the"
+                          " spatial position reaches a pixel that has already converged. This"
+                          " will speed-up convergence, at the expense of stability of the result.\n\n"
+
+                          "The application outputs the image of the final averaged spectral"
+                          " signatures (fout), and can also optionnaly output the 2D"
+                          " displacement field between input pixel position and final pixel"
+                          " position after convergence (foutpos).\n\n"
+
+                          "Note that computing an euclidean distance between spectral signatures"
+                          " may be innacurate and that techniques such as color space transform or image"
+                          " normalisation could be applied before using this application. Also"
+                          " note that most satellite images noise model is not gaussian, since"
+                          " noise variance linearly depends on luminance (the higher the"
+                          " luminance, the higher the noise variance). To account for such noise"
+                          " model, the application provides the range radius ramp option"
+                          " (rangeramp), which will vary the range radius linearly with the"
+                          " central pixel intensity. Default value is 1. (no ramp).\n\n"
+
+                          "This application is the first step of the large scale MeanShift method"
+                          " depicted in [4]. Both outputs (fout and foutpos) can be passed to the"
+                          " large scale MeanShift segmentation application [5]. If the"
+                          " application is used for large scale MeanShift, modesearch option should be off.");
+
+    SetDocLimitations("When modesearch is on, the application will yield slightly different"
+                      " results between executions, due to multi-threading. Results will also"
+                      " not be stable [4].");
+    
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+    SetDocSeeAlso("[1] Comaniciu, D., & Meer, P. (2002). Mean shift: A robust approach"
+                  " toward feature space analysis. IEEE Transactions on pattern analysis"
+                  " and machine intelligence, 24(5), 603-619.\n"
+                  "[2] Comaniciu, D., & Meer, P. (1997, June). Robust analysis of feature"
+                  " spaces: color image segmentation. In Computer Vision and Pattern"
+                  " Recognition, 1997. Proceedings., 1997 IEEE Computer Society Conference"
+                  " on (pp. 750-755). IEEE.\n"
+                  "[3] Comaniciu, D., & Meer, P. (1999). Mean shift analysis and"
+                  " applications. In Computer Vision, 1999. The Proceedings of the Seventh"
+                  " IEEE International Conference on (Vol. 2, pp. 1197-1203). IEEE.\n"
+                  "[4] Michel, J., Youssefi, D., & Grizonnet, M. (2015). Stable"
+                  " mean-shift algorithm and its application to the segmentation of"
+                  " arbitrarily large remote sensing images. IEEE Transactions on"
+                  " Geoscience and Remote Sensing, 53(2), 952-964.\n"
+                  "[5] LSMSSegmentation application");
 
     AddDocTag(Tags::Filter);
     AddDocTag("LSMS");
 
     AddParameter(ParameterType_InputImage,   "in",     "Input Image");
-    SetParameterDescription( "in", "The input image." );
+    SetParameterDescription( "in", "The input image can be any single or multiband image. Beware of pontential imbalance between bands ranges as it may alter euclidean distance." );
 
-    AddParameter(ParameterType_OutputImage,  "fout",    "Filtered output");
-    SetParameterDescription( "fout", "The filtered output image." );
+    AddParameter(ParameterType_OutputImage,  "fout",    "Spectral filtered output");
+    SetParameterDescription( "fout", "This output image contains the final average spectral signatures of each pixel. The output type should be at least as wide as the input image type. Floating point encoding is advised. This output can be used as input image (in) of the LSMSSegmentation application [4,5]."  );
 
-    AddParameter(ParameterType_OutputImage,  "foutpos",    "Spatial image");
-    SetParameterDescription( "foutpos", " The spatial image output. Spatial image output is a displacement map (pixel position after convergence).");
+    AddParameter(ParameterType_OutputImage,  "foutpos",    "Spatial filtered displacement output");
+    SetParameterDescription( "foutpos", " This output image contains the 2D displacement between the input pixel spatial position and the final position after convergence. Floating point encoding is mandatory. This output can be used as input image (in) of the LSMSSegmentation application [4,5].");
     MandatoryOff("foutpos");
 
     AddRAMParameter();
 
     AddParameter(ParameterType_Int, "spatialr", "Spatial radius");
-    SetParameterDescription("spatialr", "Spatial radius of the neighborhood.");
+    SetParameterDescription("spatialr", "Radius of the spatial neighborhood for averaging. Higher values will result in more smoothing and higher processing time.");
     SetDefaultParameterInt("spatialr", 5);
     MandatoryOff("spatialr");
 
     AddParameter(ParameterType_Float, "ranger", "Range radius");
-    SetParameterDescription("ranger", "Range radius defining the radius (expressed in radiometry unit) in the multi-spectral space.");
+    SetParameterDescription("ranger", "Threshold on spectral signature euclidean distance (expressed in radiometry unit) to consider neighborhood pixel for averaging. Higher values will be less edge-preserving (more similar to simple average in neighborhood), whereas lower values will result in less noise smoothing. Note that this parameter has no effect on processing time.");
     SetDefaultParameterFloat("ranger", 15.0);
     MandatoryOff("ranger");
 
     AddParameter(ParameterType_Float, "thres", "Mode convergence threshold");
-    SetParameterDescription("thres", "Algorithm iterative scheme will stop if mean-shift "
-                               "vector is below this threshold or if iteration number reached maximum number of iterations.");
+    SetParameterDescription("thres", "Algorithm will stop if update of average spectral signature and spatial position is below this threshold.");
     SetMinimumParameterFloatValue("thres", 0.0);
     SetDefaultParameterFloat("thres", 0.1);
     MandatoryOff("thres");
 
     AddParameter(ParameterType_Int, "maxiter", "Maximum number of iterations");
-    SetParameterDescription("maxiter", "Algorithm iterative scheme will stop if convergence hasn't been reached after the maximum number of iterations.");
+    SetParameterDescription("maxiter", "Algorithm will stop if convergence threshold is not met after the maximum number of iterations.");
     SetDefaultParameterInt("maxiter", 100);
     SetMinimumParameterIntValue("maxiter", 1);
     MandatoryOff("maxiter");
 
-    AddParameter(ParameterType_Float, "rangeramp", "Range radius coefficient");
-    SetParameterDescription("rangeramp", "This coefficient makes dependent the ranger of the colorimetry of the filtered pixel : y = rangeramp*x+ranger.");
+    AddParameter(ParameterType_Float, "rangeramp", "Range radius ramp coefficient");
+    SetParameterDescription("rangeramp", "Vary the range radius linearly with the central pixel intensity (experimental).");
     SetDefaultParameterFloat("rangeramp", 0.);
     SetMinimumParameterFloatValue("rangeramp", 0);
     MandatoryOff("rangeramp");
 
     AddParameter(ParameterType_Empty, "modesearch", "Mode search.");
-    SetParameterDescription("modesearch", "If activated pixel iterative convergence is stopped if the path crosses an already converged pixel. Be careful, with this option, the result will slightly depend on thread number");
+    SetParameterDescription("modesearch", "If activated pixel iterative convergence is stopped if the path crosses an already converged pixel. Be careful, with this option, the result will slightly depend on thread number and the results will not be stable (see [4] for more details).");
     DisableParameter("modesearch");
 
 
diff --git a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
index c8c975c57148fcd2ad4c2c7f5ed4d878dd9ffab8..5b3bfd2361f211e9dccf19b383542596fd1b994a 100644
--- a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
@@ -39,6 +39,7 @@
 #include "otbOGRLayerStreamStitchingFilter.h"
 
 #include "otbGeoInformationConversion.h"
+#include "otbClampImageFilter.h"
 
 //Utils
 #include "itksys/SystemTools.hxx"
@@ -129,6 +130,8 @@ public:
   <FloatImageType,
    WatershedSegmentationFilterType>      StreamingVectorizedWatershedFilterType;
 
+  typedef otb::ClampImageFilter<FloatImageType, UInt32ImageType> ClampFilterType;
+
   /** Standard macro */
   itkNewMacro(Self);
   itkTypeMacro(Segmentation, otb::Application);
@@ -352,8 +355,12 @@ private:
 
   template<class TInputImage, class TSegmentationFilter>
   FloatVectorImageType::SizeType
-  GenericApplySegmentation(otb::StreamingImageToOGRLayerSegmentationFilter<TInputImage,
-                           TSegmentationFilter> * streamingVectorizedFilter, TInputImage * inputImage, const otb::ogr::Layer& layer, const unsigned int outputNb)
+  GenericApplySegmentation(
+    otb::StreamingImageToOGRLayerSegmentationFilter<
+      TInputImage,TSegmentationFilter> * streamingVectorizedFilter,
+    TInputImage * inputImage,
+    const otb::ogr::Layer& layer,
+    const unsigned int outputNb)
   {
     // Retrieve tile size parameter
     const unsigned int tileSize = static_cast<unsigned int> (this->GetParameterInt("mode.vector.tilesize"));
@@ -369,7 +376,7 @@ private:
 
     if (segModeType == "vector" && HasValue("mode.vector.inmask"))
       {
-      streamingVectorizedFilter->SetInputMask(this->GetParameterUInt32Image("mode.vector.inmask"));
+      streamingVectorizedFilter->SetInputMask(m_ClampFilter->GetOutput());
       otbAppLogINFO(<<"Use a mask as input." << std::endl);
       }
     streamingVectorizedFilter->SetOGRLayer(layer);
@@ -422,7 +429,9 @@ private:
       DisableParameter("mode.raster.out");
       EnableParameter("mode.vector.out");
 
-      AddProcess(streamingVectorizedFilter->GetStreamer(), "Computing " + (dynamic_cast <ChoiceParameter *> (this->GetParameterByKey("filter")))->GetChoiceKey(GetParameterInt("filter")) + " segmentation");
+      AddProcess(streamingVectorizedFilter->GetStreamer(), "Computing "
+        + this->GetParameterString("filter")
+        + " segmentation");
 
       streamingVectorizedFilter->Initialize(); //must be called !
       streamingVectorizedFilter->Update(); //must be called !
@@ -435,7 +444,9 @@ private:
       EnableParameter("mode.raster.out");
 
       streamingVectorizedFilter->GetSegmentationFilter()->SetInput(inputImage);
-      SetParameterOutputImage<UInt32ImageType> ("mode.raster.out", dynamic_cast<UInt32ImageType *> (streamingVectorizedFilter->GetSegmentationFilter()->GetOutputs().at(outputNb).GetPointer()));
+      SetParameterOutputImage<UInt32ImageType> ("mode.raster.out",
+        dynamic_cast<UInt32ImageType*>(
+          streamingVectorizedFilter->GetSegmentationFilter()->GetOutputs().at(outputNb).GetPointer()));
       //TODO add progress reporting in raster mode
       // AddProcess(dynamic_cast <OutputImageParameter *> (GetParameterByKey("mode.raster.out"))->GetWriter(),
       //            "Computing " + (dynamic_cast <ChoiceParameter *>
@@ -468,7 +479,6 @@ private:
       //projection ref conversion to ESRI need to be tested in case of .shp
       if ((dataSourceName.find(".shp") != std::string::npos) && (!projRef.empty()))
         {
-
         if (!(otb::GeoInformationConversion::IsESRIValidWKT(projRef)))
           {
           otbAppLogFATAL(<<"Image projection reference "<<std::endl<< projRef);
@@ -494,57 +504,59 @@ private:
         OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger);
         layer.CreateField(field, true);
         }
-      else
-        if (outmode == "ulovw")
+      else if (outmode == "ulovw")
+        {
+        // Create the datasource
+        ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerOverwrite);
+
+        // and create the layer since we are in overwrite mode, the
+        // datasource is blank
+        layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options);
+        // And create the field
+        OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger);
+        layer.CreateField(field, true);
+        }
+      else if (outmode == "ulu")
+        {
+        // Create the datasource
+        ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerUpdate);
+        // and create the layer since we are in overwrite mode, the
+        // datasource is blank
+        layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options);
+
+        // And create the field if necessary
+        std::string fieldName = this->GetParameterString("mode.vector.fieldname");
+        OGRFeatureDefn & ogrFeatureDfn = layer.GetLayerDefn();
+
+        if (-1 == ogrFeatureDfn.GetFieldIndex(fieldName.c_str()))
           {
-          // Create the datasource
-          ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerOverwrite);
-
-          // and create the layer since we are in overwrite mode, the
-          // datasource is blank
-          layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options);
-          // And create the field
-          OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger);
+          OGRFieldDefn field(fieldName.c_str(), OFTInteger);
           layer.CreateField(field, true);
-
           }
-        else
-          if (outmode == "ulu")
-            {
-            // Create the datasource
-            ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerUpdate);
-            // and create the layer since we are in overwrite mode, the
-            // datasource is blank
-            layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options);
-
-            // And create the field if necessary
-            std::string fieldName = this->GetParameterString("mode.vector.fieldname");
-            OGRFeatureDefn & ogrFeatureDfn = layer.GetLayerDefn();
-
-            if (-1 == ogrFeatureDfn.GetFieldIndex(fieldName.c_str()))
-              {
-              OGRFieldDefn field(fieldName.c_str(), OFTInteger);
-              layer.CreateField(field, true);
-              }
-
-            }
-          else
-            if (outmode == "ulco")
-              {
-              // Create the datasource
-              ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerCreateOnly);
-
-              // and create the layer since we are in overwrite mode, the
-              // datasource is blank
-              layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options);
-              // And create the field
-              OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger);
-              layer.CreateField(field, true);
-              }
-            else
-              {
-              otbAppLogFATAL(<<"outmode not handled yet: "<< outmode);
-              }
+        }
+      else if (outmode == "ulco")
+        {
+        // Create the datasource
+        ogrDS = otb::ogr::DataSource::New(dataSourceName, otb::ogr::DataSource::Modes::Update_LayerCreateOnly);
+
+        // and create the layer since we are in overwrite mode, the
+        // datasource is blank
+        layer = ogrDS->CreateLayer(GetParameterString("mode.vector.layername"), &oSRS, wkbMultiPolygon, options);
+        // And create the field
+        OGRFieldDefn field(this->GetParameterString("mode.vector.fieldname").c_str(), OFTInteger);
+        layer.CreateField(field, true);
+        }
+      else
+        {
+        otbAppLogFATAL(<<"outmode not handled yet: "<< outmode);
+        }
+      }
+
+    // handle mask
+    if (HasValue("mode.vector.inmask"))
+      {
+      m_ClampFilter = ClampFilterType::New();
+      m_ClampFilter->SetInput( this->GetParameterFloatImage("mode.vector.inmask"));
       }
 
     // The actual stream size used
@@ -554,108 +566,105 @@ private:
       {
       otbAppLogINFO(<<"Use connected component segmentation."<<std::endl);
       ConnectedComponentStreamingVectorizedSegmentationOGRType::Pointer
-          ccVectorizationFilter = ConnectedComponentStreamingVectorizedSegmentationOGRType::New();
+        ccVectorizationFilter = ConnectedComponentStreamingVectorizedSegmentationOGRType::New();
 
       if (HasValue("mode.vector.inmask"))
         {
         ccVectorizationFilter->GetSegmentationFilter()->SetMaskImage(
-                                                                     this->GetParameterUInt32Image("mode.vector.inmask"));
+          m_ClampFilter->GetOutput());
         }
 
       ccVectorizationFilter->GetSegmentationFilter()->GetFunctor().SetExpression(GetParameterString("filter.cc.expr"));
-      streamSize = GenericApplySegmentation<FloatVectorImageType, ConnectedComponentSegmentationFilterType> (
-                                                                                                             ccVectorizationFilter,
-                                                                                                             this->GetParameterFloatVectorImage(
-                                                                                                                                                "in"),
-                                                                                                             layer, 0);
+      streamSize = GenericApplySegmentation<FloatVectorImageType,ConnectedComponentSegmentationFilterType>(
+        ccVectorizationFilter,
+        this->GetParameterFloatVectorImage("in"),
+        layer,
+        0);
       }
-      else
-        if (segType == "meanshift")
-          {
-          otbAppLogINFO(<<"Use threaded Mean-shift segmentation."<<std::endl);
-
-          MeanShiftVectorizedSegmentationOGRType::Pointer
-              meanShiftVectorizationFilter = MeanShiftVectorizedSegmentationOGRType::New();
-
-          //segmentation parameters
-          const unsigned int
-              spatialRadius = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.spatialr"));
-          const float rangeRadius = static_cast<float> (this->GetParameterFloat("filter.meanshift.ranger"));
-          const unsigned int
-              minimumObjectSize = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.minsize"));
-
-          const float threshold = this->GetParameterFloat("filter.meanshift.thres");
-          const unsigned int
-              maxIterNumber = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.maxiter"));
-
-          meanShiftVectorizationFilter->GetSegmentationFilter()->SetSpatialBandwidth(spatialRadius);
-          meanShiftVectorizationFilter->GetSegmentationFilter()->SetRangeBandwidth(rangeRadius);
-          meanShiftVectorizationFilter->GetSegmentationFilter()->SetMaxIterationNumber(maxIterNumber);
-          meanShiftVectorizationFilter->GetSegmentationFilter()->SetThreshold(threshold);
-          meanShiftVectorizationFilter->GetSegmentationFilter()->SetMinRegionSize(minimumObjectSize);
-
-          streamSize = this->GenericApplySegmentation<FloatVectorImageType, MeanShiftSegmentationFilterType> (
-                                                                                                              meanShiftVectorizationFilter,
-                                                                                                              this->GetParameterFloatVectorImage(
-                                                                                                                                                 "in"),
-                                                                                                              layer, 0);
-          }
-        else
-          if (segType == "watershed")
-            {
-            otbAppLogINFO(<<"Using watershed segmentation."<<std::endl);
-
-            AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New();
-
-            amplitudeFilter->SetInput(this->GetParameterFloatVectorImage("in"));
+    else if (segType == "meanshift")
+      {
+      otbAppLogINFO(<<"Use threaded Mean-shift segmentation."<<std::endl);
+
+      MeanShiftVectorizedSegmentationOGRType::Pointer
+          meanShiftVectorizationFilter = MeanShiftVectorizedSegmentationOGRType::New();
+
+      //segmentation parameters
+      const unsigned int
+          spatialRadius = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.spatialr"));
+      const float rangeRadius = static_cast<float> (this->GetParameterFloat("filter.meanshift.ranger"));
+      const unsigned int
+          minimumObjectSize = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.minsize"));
+
+      const float threshold = this->GetParameterFloat("filter.meanshift.thres");
+      const unsigned int
+          maxIterNumber = static_cast<unsigned int> (this->GetParameterInt("filter.meanshift.maxiter"));
+
+      meanShiftVectorizationFilter->GetSegmentationFilter()->SetSpatialBandwidth(spatialRadius);
+      meanShiftVectorizationFilter->GetSegmentationFilter()->SetRangeBandwidth(rangeRadius);
+      meanShiftVectorizationFilter->GetSegmentationFilter()->SetMaxIterationNumber(maxIterNumber);
+      meanShiftVectorizationFilter->GetSegmentationFilter()->SetThreshold(threshold);
+      meanShiftVectorizationFilter->GetSegmentationFilter()->SetMinRegionSize(minimumObjectSize);
+
+      streamSize = this->GenericApplySegmentation<FloatVectorImageType,MeanShiftSegmentationFilterType>(
+        meanShiftVectorizationFilter,
+        this->GetParameterFloatVectorImage("in"),
+        layer,
+        0);
+      }
+    else if (segType == "watershed")
+      {
+      otbAppLogINFO(<<"Using watershed segmentation."<<std::endl);
 
-            GradientMagnitudeFilterType::Pointer gradientMagnitudeFilter = GradientMagnitudeFilterType::New();
-            gradientMagnitudeFilter->SetInput(amplitudeFilter->GetOutput());
+      AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New();
 
-            StreamingVectorizedWatershedFilterType::Pointer
-                watershedVectorizedFilter = StreamingVectorizedWatershedFilterType::New();
+      amplitudeFilter->SetInput(this->GetParameterFloatVectorImage("in"));
 
-            watershedVectorizedFilter->GetSegmentationFilter()->SetThreshold(
-                                                                             GetParameterFloat(
-                                                                                               "filter.watershed.threshold"));
-            watershedVectorizedFilter->GetSegmentationFilter()->SetLevel(GetParameterFloat("filter.watershed.level"));
+      GradientMagnitudeFilterType::Pointer gradientMagnitudeFilter = GradientMagnitudeFilterType::New();
+      gradientMagnitudeFilter->SetInput(amplitudeFilter->GetOutput());
 
-            streamSize = this->GenericApplySegmentation<FloatImageType, WatershedSegmentationFilterType> (
-                                                                                                          watershedVectorizedFilter,
-                                                                                                          gradientMagnitudeFilter->GetOutput(),
-                                                                                                          layer, 0);
-            }
+      StreamingVectorizedWatershedFilterType::Pointer
+          watershedVectorizedFilter = StreamingVectorizedWatershedFilterType::New();
 
-        else
-          if (segType == "mprofiles")
-            {
-            otbAppLogINFO(<<"Using multiscale geodesic morphology segmentation."<<std::endl);
+      watershedVectorizedFilter->GetSegmentationFilter()->SetThreshold(
+        GetParameterFloat("filter.watershed.threshold"));
+      watershedVectorizedFilter->GetSegmentationFilter()->SetLevel(GetParameterFloat("filter.watershed.level"));
 
-            unsigned int profileSize = GetParameterInt("filter.mprofiles.size");
-            unsigned int initialValue = GetParameterInt("filter.mprofiles.start");
-            unsigned int step = GetParameterInt("filter.mprofiles.step");
-            double       sigma = GetParameterFloat("filter.mprofiles.sigma");
+      streamSize = this->GenericApplySegmentation<FloatImageType,WatershedSegmentationFilterType>(
+        watershedVectorizedFilter,
+        gradientMagnitudeFilter->GetOutput(),
+        layer,
+        0);
+      }
+    else if (segType == "mprofiles")
+      {
+      otbAppLogINFO(<<"Using multiscale geodesic morphology segmentation."<<std::endl);
 
+      unsigned int profileSize = GetParameterInt("filter.mprofiles.size");
+      unsigned int initialValue = GetParameterInt("filter.mprofiles.start");
+      unsigned int step = GetParameterInt("filter.mprofiles.step");
+      double       sigma = GetParameterFloat("filter.mprofiles.sigma");
 
-            AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New();
 
-            amplitudeFilter->SetInput(this->GetParameterFloatVectorImage("in"));
+      AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New();
 
-            MorphoVectorizedSegmentationOGRType::Pointer morphoVectorizedSegmentation = MorphoVectorizedSegmentationOGRType::New();
-            morphoVectorizedSegmentation->GetSegmentationFilter()->SetProfileStart(initialValue);
-            morphoVectorizedSegmentation->GetSegmentationFilter()->SetProfileSize(profileSize);
-            morphoVectorizedSegmentation->GetSegmentationFilter()->SetProfileStep(step);
-            morphoVectorizedSegmentation->GetSegmentationFilter()->SetSigma(sigma);
+      amplitudeFilter->SetInput(this->GetParameterFloatVectorImage("in"));
 
-            streamSize = GenericApplySegmentation<FloatImageType, MorphologicalProfilesSegmentationFilterType> (
-        morphoVectorizedSegmentation,                                                                     amplitudeFilter->GetOutput(),
-                                                                                                             layer, 0);
+      MorphoVectorizedSegmentationOGRType::Pointer morphoVectorizedSegmentation = MorphoVectorizedSegmentationOGRType::New();
+      morphoVectorizedSegmentation->GetSegmentationFilter()->SetProfileStart(initialValue);
+      morphoVectorizedSegmentation->GetSegmentationFilter()->SetProfileSize(profileSize);
+      morphoVectorizedSegmentation->GetSegmentationFilter()->SetProfileStep(step);
+      morphoVectorizedSegmentation->GetSegmentationFilter()->SetSigma(sigma);
 
-            }
-          else
-            {
-            otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl);
-            }
+      streamSize = GenericApplySegmentation<FloatImageType,MorphologicalProfilesSegmentationFilterType>(
+        morphoVectorizedSegmentation,
+        amplitudeFilter->GetOutput(),
+        layer,
+        0);
+      }
+    else
+      {
+      otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl);
+      }
 
     if (segModeType == "vector")
       {
@@ -676,26 +685,27 @@ private:
         AddProcess(fusionFilter, "Stitching polygons");
         fusionFilter->GenerateData();
 
-       //REPACK the Layer in case of Shapefile.
-       //This request will remove features marked as deleted in the .dbf filename,
-       //and recomputed FID for each features (without holes).
+        //REPACK the Layer in case of Shapefile.
+        //This request will remove features marked as deleted in the .dbf filename,
+        //and recomputed FID for each features (without holes).
         //Note : the GetDriver() Method has not been encapsulated in otb::ogr::DataSource,
         //so we must access the OGR pointer by using .ogr()
 
         std::string driverName(otb::ogr::version_proxy::GetDriverNameFromDataSource(&ogrDS->ogr()));
-       if ( driverName.find("ESRI Shapefile") != std::string::npos)
-         {
-           otbAppLogINFO(<<"REPACK the Shapefile ..."<<std::endl);
-           //In Shapefile format, the name of the DaaSource is also the name of the Layer.
-           std::string shpLayerName = itksys::SystemTools::GetFilenameWithoutExtension(GetParameterString("mode.vector.out"));
-
-           std::string repack("REPACK ");
-           repack = repack + shpLayerName;
-           ogrDS->ExecuteSQL(repack, ITK_NULLPTR, ITK_NULLPTR);
-         }
-       }
+        if ( driverName.find("ESRI Shapefile") != std::string::npos)
+          {
+          otbAppLogINFO(<<"REPACK the Shapefile ..."<<std::endl);
+          //In Shapefile format, the name of the DaaSource is also the name of the Layer.
+          std::string shpLayerName = itksys::SystemTools::GetFilenameWithoutExtension(GetParameterString("mode.vector.out"));
+          std::string repack("REPACK ");
+          repack = repack + shpLayerName;
+          ogrDS->ExecuteSQL(repack, ITK_NULLPTR, ITK_NULLPTR);
+          }
+        }
       }
   }
+
+  ClampFilterType::Pointer m_ClampFilter;
 };
 }
 }
diff --git a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
index 8b19cfabd052bd1abf2806821615347a4bfe67e2..eaf57ea79a2c47f194d73db7c8e2cdad7db717c2 100644
--- a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
+++ b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
@@ -127,82 +127,145 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("BlockMatching");
-    SetDescription("Performs block-matching to estimate pixel-wise disparities between two images");
+    SetDescription("Performs block-matching to estimate pixel-wise disparities"
+      " between two images.");
 
     SetDocName("Pixel-wise Block-Matching");
-    SetDocLongDescription("This application allows one to performs block-matching to estimate pixel-wise disparities "
-      "between two images. One must chose block-matching method and input"
-      " masks (related to the left and right input image) of pixels for which the disparity should be investigated. "
-      "Additionally, two criteria can be optionally used to disable disparity investigation for some pixel: a "
-      "no-data value, and a threshold on the local variance. This allows one to speed-up computation by avoiding to "
-      "investigate disparities that will not be reliable anyway. For efficiency reasons, if the optimal metric values"
-      " image is desired, it will be concatenated to the output image (which will then have three bands : horizontal "
-      "disparity, vertical disparity and metric value). One can split these images afterward.");
+    SetDocLongDescription("This application allows one to performs "
+      "block-matching to estimate pixel-wise disparities for a pair of images "
+      "in epipolar geometry.\n\n"
+      "This application is part of the stereovision pipeline. It can be used "
+      "after having computed epipolar grids (with StereoRectificationGridGenerator)"
+      " and resampled each input image into epipolar geometry (with "
+      "GridBasedImageResampling).\n\n"
+      "The application searches locally for the displacement between a reference"
+      " image and a secondary image. The correspondance is evaluated for each "
+      "pixel, based on a pair of local neighborhood windows. The displacement "
+      "evaluated can be 1D (along lines) or 2D. Parameters allows to set the "
+      "minimum and maximum disparities to search (both for horizontal and "
+      "vertical directions). A winner-take-all approach is used to select the "
+      "best match. There are different metrics implemented to evaluate the "
+      "match between two local windows:\n"
+      "  * SSD : Sum of Squared Distances\n"
+      "  * NCC : Normalized Cross-Correlation\n"
+      "  * Lp  : Lp pseudo norm\n"
+      "\n"                    
+      "Once the best integer disparity is found, an optional step of sub-pixel "
+      "disparity estimation can be performed, with various algorithms "
+      "(triangular interpolation, parabollic interpolation, dichotimic search)."
+      " As post-processing, there is an optional step of median filtering on "
+      "the disparities. One can chose input masks (related to the left and "
+      "right input image) of pixels for which the disparity should be "
+      "investigated. Additionally, two criteria can be optionally used to "
+      "disable disparity investigation for some pixel: a no-data value, and a "
+      "threshold on the local variance. This allows one to speed-up computation"
+      " by avoiding to investigate disparities that will not be reliable anyway"
+      ". For efficiency reasons, if the image of optimal metric values is "
+      "desired, it will be concatenated to the output image (which will then "
+      "have three bands : horizontal disparity, vertical disparity and metric "
+      "value). One can split these images afterward.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("otbStereoRectificationGridGenerator");
+    SetDocSeeAlso("[1] StereoRectificationGridGenerator\n"
+      "[2] GridBasedImageResampling");
 
     AddDocTag(Tags::Stereo);
 
     AddParameter(ParameterType_Group,"io","Input and output data");
-    SetParameterDescription("io","This group of parameters allows setting the input and output images.");
+    SetParameterDescription("io","This group of parameters allows setting the "
+      "input and output images.");
 
     AddParameter(ParameterType_InputImage,"io.inleft","Left input image");
-    SetParameterDescription("io.inleft","The left input image (reference)");
+    SetParameterDescription("io.inleft","The left input image (reference).\n"
+      "It should have the same size and same physical space as the right input."
+      " This image can be generated by GridBasedImageResampling");
 
     AddParameter(ParameterType_InputImage,"io.inright","Right input image");
-    SetParameterDescription("io.inright","The right input (secondary)");
+    SetParameterDescription("io.inright","The right input (secondary).\n"
+      "It should have the same size and same physical space as the left input."
+      " This image can be generated by GridBasedImageResampling");
 
     AddParameter(ParameterType_OutputImage, "io.out", "The output disparity map");
-    SetParameterDescription("io.out","An image containing the estimated disparities as well as the metric values if the option is used");
-
-    AddParameter(ParameterType_OutputImage, "io.outmask", "The output mask corresponding to all criterions");
-    SetParameterDescription("io.outmask","A mask image corresponding to all citerions (see masking parameters). Only required if variance threshold or nodata criterions are set.");
+    SetParameterDescription("io.out","An image containing the estimated "
+      "disparities as well as the metric values if the option is used. If no "
+      "metric is output and no sub-pixel interpolation is done, pixel type can"
+      "be a signed integer. In the other cases, floating point pixel is "
+      "advised.");
+
+    AddParameter(ParameterType_OutputImage, "io.outmask", "The output mask "
+      "corresponding to all criterions");
+    SetParameterDescription("io.outmask","An output mask image corresponding to"
+      " all citerions (see masking parameters). Only required if variance "
+      "threshold or nodata criterions are set. Output pixel type is unsigned "
+      "8bit by default.");
     SetDefaultOutputPixelType("io.outmask",ImagePixelType_uint8);
     DisableParameter("io.outmask");
     MandatoryOff("io.outmask");
 
-    AddParameter(ParameterType_Empty,"io.outmetric","Output optimal metric values as well");
-    SetParameterDescription("io.outmetric","If used, the output image will have a second component with metric optimal values");
+    AddParameter(ParameterType_Empty,"io.outmetric","Flag to output optimal "
+      "metric values as well");
+    SetParameterDescription("io.outmetric","If enabled, the output image will "
+      "have a third component with metric optimal values");
 
     AddParameter(ParameterType_Group,"mask","Image masking parameters");
-    SetParameterDescription("mask","This group of parameters allows determining the masking parameters to prevent disparities estimation for some pixels of the left image");
-
-    AddParameter(ParameterType_InputImage,"mask.inleft","Discard left pixels from mask image");
-    SetParameterDescription("mask.inleft","This parameter allows providing a custom mask for the left image.Block matching will be only perform on pixels inside the mask.");
+    SetParameterDescription("mask","This group of parameters allows determining"
+      " the masking parameters to prevent disparities estimation for some "
+      "pixels of the left image");
+
+    AddParameter(ParameterType_InputImage,"mask.inleft",
+      "Mask to discard left pixels");
+    SetParameterDescription("mask.inleft","This parameter allows providing a "
+      "custom mask for the left image. Block matching will be only perform on "
+      "pixels inside the mask (non-zero values).");
     MandatoryOff("mask.inleft");
 
-    AddParameter(ParameterType_InputImage,"mask.inright","Discard right pixels from mask image");
-    SetParameterDescription("mask.inright","This parameter allows providing a custom mask for the right image.Block matching will be perform only on pixels inside the mask.");
+    AddParameter(ParameterType_InputImage,"mask.inright",
+      "Mask to discard right pixels");
+    SetParameterDescription("mask.inright","This parameter allows providing a "
+      "custom mask for the right image. Block matching will be perform only on "
+      "pixels inside the mask (non-zero values).");
     MandatoryOff("mask.inright");
 
-    AddParameter(ParameterType_Float,"mask.nodata","Discard pixels with no-data value");
-    SetParameterDescription("mask.nodata","This parameter allows discarding pixels whose value is equal to the user-defined no-data value.");
+    AddParameter(ParameterType_Float,"mask.nodata",
+      "Discard pixels with no-data value");
+    SetParameterDescription("mask.nodata","This parameter allows discarding "
+      "pixels whose value is equal to the user-defined no-data value.");
     MandatoryOff("mask.nodata");
     SetDefaultParameterFloat("mask.nodata",0.);
     DisableParameter("mask.nodata");
 
-    AddParameter(ParameterType_Float,"mask.variancet","Discard pixels with low local variance");
-    SetParameterDescription("mask.variancet","This parameter allows discarding pixels whose local variance is too small (the size of the neighborhood is given by the radius parameter)");
+    AddParameter(ParameterType_Float,"mask.variancet",
+      "Discard pixels with low local variance");
+    SetParameterDescription("mask.variancet","This parameter allows discarding"
+      " pixels whose local variance is too small (the size of the neighborhood"
+      " is given by the radius parameter)");
     MandatoryOff("mask.variancet");
     SetDefaultParameterFloat("mask.variancet",100.);
     DisableParameter("mask.variancet");
 
     AddParameter(ParameterType_Group,"bm","Block matching parameters");
-    SetParameterDescription("bm","This group of parameters allow tuning the block-matching behaviour");
+    SetParameterDescription("bm","This group of parameters allow tuning the "
+      "block-matching behaviour");
 
     AddParameter(ParameterType_Choice,   "bm.metric", "Block-matching metric");
+    SetParameterDescription("bm.metric",
+      "Metric to evaluate matching between two local windows.");
+
     AddChoice("bm.metric.ssd","Sum of Squared Distances");
-    SetParameterDescription("bm.metric.ssd","Sum of squared distances between pixels value in the metric window");
+    SetParameterDescription("bm.metric.ssd","Sum of squared distances between"
+      " pixels value in the metric window");
 
     AddChoice("bm.metric.ncc","Normalized Cross-Correlation");
-    SetParameterDescription("bm.metric.ncc","Normalized Cross-Correlation between the left and right windows");
+    SetParameterDescription("bm.metric.ncc","Normalized Cross-Correlation "
+      "between the left and right windows");
 
     AddChoice("bm.metric.lp","Lp pseudo-norm");
-    SetParameterDescription("bm.metric.lp","Lp pseudo-norm between the left and right windows");
+    SetParameterDescription("bm.metric.lp","Lp pseudo-norm between the left and"
+      " right windows.");
 
     AddParameter(ParameterType_Float,"bm.metric.lp.p","p value" );
-    SetParameterDescription("bm.metric.lp.p", "Value of the p parameter in Lp pseudo-norm (must be positive)");
+    SetParameterDescription("bm.metric.lp.p", "Value of the p parameter in Lp"
+      " pseudo-norm (must be positive).");
     SetDefaultParameterFloat("bm.metric.lp.p", 1.0);
     SetMinimumParameterFloatValue("bm.metric.lp.p", 0.0);
 
@@ -227,43 +290,61 @@ private:
     SetParameterDescription("bm.subpixel", "Estimate disparities with sub-pixel precision");
 
     AddChoice("bm.subpixel.none", "None");
-    SetParameterDescription("bm.subpixel.none", "No sub-pixel ");
+    SetParameterDescription("bm.subpixel.none", "No sub-pixel search");
 
-    AddChoice("bm.subpixel.parabolic", "Parabolic");
-    SetParameterDescription("bm.subpixel.parabolic", "Parabolic fit");
+    AddChoice("bm.subpixel.parabolic", "Parabolic fit");
+    SetParameterDescription("bm.subpixel.parabolic", "The metric values closest"
+      " to the best match are used in order to fit a parabola to the local "
+      "extremum of the metric surface. The peak position of this parabola is "
+      "output.");
 
-    AddChoice("bm.subpixel.triangular", "Triangular");
-    SetParameterDescription("bm.subpixel.triangular", "Triangular fit");
+    AddChoice("bm.subpixel.triangular", "Triangular fit");
+    SetParameterDescription("bm.subpixel.triangular", "The metric values "
+      "closest to the best match are used in order to fit a triangular peak to "
+      "the local extremum of the metric surface. The peak position of this "
+      "triangle is output.");
 
-    AddChoice("bm.subpixel.dichotomy", "Dichotomy");
-    SetParameterDescription("bm.subpixel.dichotomy", "Dichotomic search");
+    AddChoice("bm.subpixel.dichotomy", "Dichotomy search");
+    SetParameterDescription("bm.subpixel.dichotomy", "An iterative dichotomic "
+      "search is performed to find the best sub-pixel position. The window in "
+      "the right image is resampled at sub-pixel positions to estimate the match.");
 
     AddParameter(ParameterType_Int,"bm.step", "Computation step");
-    SetParameterDescription("bm.step", "Location step between computed disparities");
+    SetParameterDescription("bm.step", "Location step between computed "
+      "disparities. Disparities will be computed every 'step' pixels in the "
+      "left image (step for both rows and columns). For instance, a value of 1 "
+      "corresponds to the classic dense disparity map.");
     SetDefaultParameterInt("bm.step",1);
     SetMinimumParameterIntValue("bm.step",1);
     MandatoryOff("bm.step");
 
     AddParameter(ParameterType_Int,"bm.startx","X start index");
-    SetParameterDescription("bm.startx","X start index of the subsampled grid (wrt the input image grid)");
+    SetParameterDescription("bm.startx","X start index of the subsampled grid "
+      "(wrt the input image grid). See parameter bm.step");
     SetDefaultParameterInt("bm.startx",0);
     MandatoryOff("bm.startx");
 
     AddParameter(ParameterType_Int,"bm.starty","Y start index");
-    SetParameterDescription("bm.starty","Y start index of the subsampled grid (wrt the input image grid)");
+    SetParameterDescription("bm.starty","Y start index of the subsampled grid "
+      "(wrt the input image grid). See parameter bm.step");
     SetDefaultParameterInt("bm.starty",0);
     MandatoryOff("bm.starty");
 
-    AddParameter(ParameterType_Group,"bm.medianfilter","Median filtering");
-    SetParameterDescription("bm.medianfilter","Use a median filter to get a smooth disparity map");
+    AddParameter(ParameterType_Group,"bm.medianfilter",
+      "Median filtering of disparity map");
+    SetParameterDescription("bm.medianfilter","Use a median filter to get a "
+      "smooth disparity map");
 
     AddParameter(ParameterType_Int,"bm.medianfilter.radius", "Radius");
-    SetParameterDescription("bm.medianfilter.radius", "Radius for median filter");
+    SetParameterDescription("bm.medianfilter.radius", "Radius (in pixels) for "
+      "median filter");
     MandatoryOff("bm.medianfilter.radius");
     DisableParameter("bm.medianfilter.radius");
 
-    AddParameter(ParameterType_Float,"bm.medianfilter.incoherence", "Incoherence threshold");
-    SetParameterDescription("bm.medianfilter.incoherence", "Incoherence threshold between original and filtered disparity");
+    AddParameter(ParameterType_Float,"bm.medianfilter.incoherence",
+      "Incoherence threshold");
+    SetParameterDescription("bm.medianfilter.incoherence", "Incoherence "
+      "threshold between original and filtered disparity");
     MandatoryOff("bm.medianfilter.incoherence");
     DisableParameter("bm.medianfilter.incoherence");
 
@@ -272,42 +353,60 @@ private:
     SetParameterDescription("bm.initdisp.none", "No initial disparity used");
 
     AddChoice("bm.initdisp.uniform", "Uniform initial disparity");
-    SetParameterDescription("bm.initdisp.uniform", "Use an uniform initial disparity estimate");
+    SetParameterDescription("bm.initdisp.uniform", "Use an uniform initial "
+      "disparity estimate");
 
-    AddParameter(ParameterType_Int, "bm.initdisp.uniform.hdisp", "Horizontal initial disparity");
-    SetParameterDescription("bm.initdisp.uniform.hdisp", "Value of the uniform horizontal disparity initial estimate (in pixels)");
+    AddParameter(ParameterType_Int, "bm.initdisp.uniform.hdisp",
+      "Horizontal initial disparity");
+    SetParameterDescription("bm.initdisp.uniform.hdisp", "Value of the uniform "
+      "horizontal disparity initial estimate (in pixels)");
     SetDefaultParameterInt("bm.initdisp.uniform.hdisp", 0);
 
-    AddParameter(ParameterType_Int, "bm.initdisp.uniform.vdisp", "Vertical initial disparity");
-    SetParameterDescription("bm.initdisp.uniform.vdisp", "Value of the uniform vertical disparity initial estimate (in pixels)");
+    AddParameter(ParameterType_Int, "bm.initdisp.uniform.vdisp",
+      "Vertical initial disparity");
+    SetParameterDescription("bm.initdisp.uniform.vdisp", "Value of the uniform "
+      "vertical disparity initial estimate (in pixels)");
     SetDefaultParameterInt("bm.initdisp.uniform.vdisp", 0);
 
-    AddParameter(ParameterType_Int, "bm.initdisp.uniform.hrad", "Horizontal exploration radius");
-    SetParameterDescription("bm.initdisp.uniform.hrad", "Horizontal exploration radius around the initial disparity estimate (in pixels)");
+    AddParameter(ParameterType_Int, "bm.initdisp.uniform.hrad",
+      "Horizontal exploration radius");
+    SetParameterDescription("bm.initdisp.uniform.hrad", "Horizontal exploration"
+      " radius around the initial disparity estimate (in pixels)");
     SetDefaultParameterInt("bm.initdisp.uniform.hrad", 0);
     DisableParameter("bm.initdisp.uniform.hrad");
 
-    AddParameter(ParameterType_Int, "bm.initdisp.uniform.vrad", "Vertical exploration radius");
-    SetParameterDescription("bm.initdisp.uniform.vrad", "Vertical exploration radius around the initial disparity estimate (in pixels)");
+    AddParameter(ParameterType_Int, "bm.initdisp.uniform.vrad",
+      "Vertical exploration radius");
+    SetParameterDescription("bm.initdisp.uniform.vrad", "Vertical exploration "
+      "radius around the initial disparity estimate (in pixels)");
     SetDefaultParameterInt("bm.initdisp.uniform.vrad", 0);
     DisableParameter("bm.initdisp.uniform.vrad");
 
     AddChoice("bm.initdisp.maps", "Initial disparity maps");
-    SetParameterDescription("bm.initdisp.maps", "Use initial disparity maps");
+    SetParameterDescription("bm.initdisp.maps", "Use initial disparity maps to "
+      "define the exploration area. This area in the right image is centered on"
+      " the current position shifted by the initial disparity estimate, and has"
+      " a given exploration radius in horizontal and vertical directions.");
 
-    AddParameter(ParameterType_InputImage, "bm.initdisp.maps.hmap", "Horizontal initial disparity map");
-    SetParameterDescription("bm.initdisp.maps.hmap", "Map of the initial horizontal disparities");
+    AddParameter(ParameterType_InputImage, "bm.initdisp.maps.hmap",
+      "Horizontal initial disparity map");
+    SetParameterDescription("bm.initdisp.maps.hmap", "Map of the initial "
+      "horizontal disparities");
 
-    AddParameter(ParameterType_InputImage, "bm.initdisp.maps.vmap", "Vertical initial disparity map");
-    SetParameterDescription("bm.initdisp.maps.vmap", "Map of the initial vertical disparities");
+    AddParameter(ParameterType_InputImage, "bm.initdisp.maps.vmap",
+      "Vertical initial disparity map");
+    SetParameterDescription("bm.initdisp.maps.vmap", "Map of the initial "
+      "vertical disparities");
 
     AddParameter(ParameterType_Int, "bm.initdisp.maps.hrad", "Horizontal exploration radius");
-    SetParameterDescription("bm.initdisp.maps.hrad", "Horizontal exploration radius around the initial disparity estimate (in pixels)");
+    SetParameterDescription("bm.initdisp.maps.hrad", "Horizontal exploration "
+      "radius around the initial disparity estimate (in pixels)");
     SetDefaultParameterInt("bm.initdisp.maps.hrad", 0);
     DisableParameter("bm.initdisp.maps.hrad");
 
     AddParameter(ParameterType_Int, "bm.initdisp.maps.vrad", "Vertical exploration radius");
-    SetParameterDescription("bm.initdisp.maps.vrad", "Vertical exploration radius around the initial disparity estimate (in pixels)");
+    SetParameterDescription("bm.initdisp.maps.vrad", "Vertical exploration "
+      "radius around the initial disparity estimate (in pixels)");
     SetDefaultParameterInt("bm.initdisp.maps.vrad", 0);
     DisableParameter("bm.initdisp.maps.vrad");
 
diff --git a/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx b/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx
index 6f626cf70ae661ec1fc534772fae3874703c71eb..6302a912f14fdaf910a80970825a70a384ef8807 100644
--- a/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx
+++ b/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx
@@ -65,39 +65,71 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("DisparityMapToElevationMap");
-    SetDescription("Projects a disparity map into a regular elevation map");
+    SetDescription("Projects a disparity map into a regular elevation map.");
 
     SetDocName("Disparity map to elevation map");
-    SetDocLongDescription("This application uses a disparity map computed from a stereo image pair to produce an "
-      "elevation map on the ground area covered by the stereo pair. The needed inputs are : the disparity map, "
-      "the stereo pair (in original geometry) and the epipolar deformation grids. These grids have to link the "
-      "original geometry (stereo pair) and the epipolar geometry (disparity map). ");
-    SetDocLimitations("None");
+    SetDocLongDescription("This application uses a disparity map computed from "
+      "a stereo image pair to produce an elevation map on the ground area "
+      "covered by the stereo pair.\n\n"
+      "This application is part of the stereo reconstruction pipeline. It can "
+      "be used after having computed the disparity map with BlockMatching.\n\n"
+      "The needed inputs are : the disparity map, the stereo pair (in original"
+      " geometry) and the epipolar deformation grids. These grids (computed by "
+      "StereoRectificationGridGenerator) have to contain the transform between "
+      "the original geometry (stereo pair) and the epipolar geometry (disparity"
+      " map). The algorithm for each disparity is the following :\n"
+      "  * skip if position is discarded by the disparity mask\n"
+      "  * compute left ray : transform the current position from epipolar "
+      "geometry to left sensor geometry (left rectification grid)\n"
+      "  * compute right ray : shift the current position with current "
+      "disparity and transform from epipolar geometry to right sensor (right "
+      "rectification grid)\n"
+      "  * estimate best 3D intersection between left and right rays\n"
+      "  * for the ground cell of the obtained 3D point, keep its elevation if "
+      "greater than current elevation (keeps the maximum of elevations of all "
+      "3D points in each cell)\n"
+      "\n"
+      "Minimum and maximum elevations settings are here to bound the "
+      "reconstructed DEM.");
+    SetDocLimitations("The epipolar deformation grid should be able to entirely"
+      " fit in memory.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("otbStereoRectificationGridGenerator otbBlockMatching");
+    SetDocSeeAlso("[1] StereoRectificationGridGenerator\n"
+      "[2] BlockMatching");
 
     AddDocTag(Tags::Stereo);
 
     AddParameter(ParameterType_Group,"io","Input and output data");
-    SetParameterDescription("io","This group of parameters allows one to set input images, output images and grids.");
+    SetParameterDescription("io","This group of parameters allows one to set "
+      "input images, output images and grids.");
 
     AddParameter(ParameterType_InputImage,"io.in","Input disparity map");
-    SetParameterDescription("io.in","The input disparity map (horizontal disparity in first band, vertical in second)");
+    SetParameterDescription("io.in","The input disparity map (horizontal "
+      "disparity in first band, vertical in second). This map can be computed "
+      "by BlockMatching application.");
 
     AddParameter(ParameterType_InputImage,"io.left","Left sensor image");
-    SetParameterDescription("io.left","Left image in original (sensor) geometry");
+    SetParameterDescription("io.left","Left image in original (sensor) geometry"
+      ". Only the geometric model of this image will be used, not the pixel "
+      "values.");
 
     AddParameter(ParameterType_InputImage,"io.right","Right sensor image");
-    SetParameterDescription("io.right","Right image in original (sensor) geometry");
+    SetParameterDescription("io.right","Right image in original (sensor) "
+      "geometry. Only the geometric model of this image will be used, not the "
+      "pixel values.");
 
     AddParameter(ParameterType_InputImage,"io.lgrid","Left Grid");
-    SetParameterDescription("io.lgrid","Left epipolar grid (deformation grid between sensor et disparity spaces)");
+    SetParameterDescription("io.lgrid","Left epipolar grid (deformation grid "
+      "between left sensor et disparity spaces)");
 
     AddParameter(ParameterType_InputImage,"io.rgrid","Right Grid");
-    SetParameterDescription("io.rgrid","Right epipolar grid (deformation grid between sensor et disparity spaces)");
+    SetParameterDescription("io.rgrid","Right epipolar grid (deformation grid "
+      "between rigth sensor et disparity spaces)");
 
     AddParameter(ParameterType_OutputImage,"io.out","Output elevation map");
-    SetParameterDescription("io.out", "Output elevation map in ground projection");
+    SetParameterDescription("io.out", "Output elevation map in ground "
+      "projection. Elevation values are in meters. Floating point pixel type "
+      "are expected.");
 
     AddParameter(ParameterType_Float,"step","DEM step");
     SetParameterDescription("step","Spacing of the output elevation map (in meters)");
@@ -112,7 +144,8 @@ private:
     SetDefaultParameterFloat("hmax",100.0);
 
     AddParameter(ParameterType_InputImage,"io.mask","Disparity mask");
-    SetParameterDescription("io.mask","Masked disparity cells won't be projected");
+    SetParameterDescription("io.mask","Masked disparity pixels won't be "
+      "projected (mask values equal to zero)");
     MandatoryOff("io.mask");
 
     ElevationParametersHandler::AddElevationParameters(this, "elev");
diff --git a/Modules/Applications/AppStereo/app/otbFineRegistration.cxx b/Modules/Applications/AppStereo/app/otbFineRegistration.cxx
index d24627f06f90b7f8bd8beaccb4b5ffe58ddc4ffe..a7fed89a0e400d60eeeae15067c35f10e9e76293 100644
--- a/Modules/Applications/AppStereo/app/otbFineRegistration.cxx
+++ b/Modules/Applications/AppStereo/app/otbFineRegistration.cxx
@@ -120,7 +120,16 @@ private:
     SetDescription("Estimate disparity map between two images.");
 
     SetDocName("Fine Registration");
-    SetDocLongDescription("Estimate disparity map between two images. Output image contain x offset, y offset and metric value.");
+    SetDocLongDescription("This application computes a disparity map between "
+      "two images that correspond to the same scene. It is intended for case "
+      "where small misregistration between images should be estimated and fixed"
+      ". The search is performed in 2D.\n\n"
+      "The algorithm uses an iterative approach to estimate a best match "
+      "between local patches. The typical use case is registration betwween "
+      "similar bands, or between two acquisitions. The output image contains "
+      "X and Y offsets, as well as the metric value. A sub-pixel accuracy can "
+      "be expected. The input images should have the same size and same "
+      "physical space.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
@@ -134,7 +143,9 @@ private:
     SetParameterDescription( "sec", "The secondary image." );
 
     AddParameter(ParameterType_OutputImage,  "out",   "Output Image");
-    SetParameterDescription( "out", "The output image." );
+    SetParameterDescription( "out", "The output image contains 3 bands, for X "
+      "offset, Y offset and the metric value. It may contain a 4th one with the"
+      " validity mask (if used)." );
 
     AddParameter(ParameterType_Int,  "erx",   "Exploration Radius X");
     SetParameterDescription( "erx", "The exploration radius along x (in pixels)" );
@@ -145,15 +156,18 @@ private:
     SetMinimumParameterIntValue("ery", 0);
 
     AddParameter(ParameterType_Int,  "mrx",   "Metric Radius X");
-    SetParameterDescription( "mrx", "Radius along x (in pixels) of the metric computation window" );
+    SetParameterDescription( "mrx", "Radius along x (in pixels) of the metric "
+      "computation window" );
     SetMinimumParameterIntValue("mrx", 0);
 
     AddParameter(ParameterType_Int,  "mry",   "Metric Radius Y");
-    SetParameterDescription( "mry", "Radius along y (in pixels) of the metric computation window" );
+    SetParameterDescription( "mry", "Radius along y (in pixels) of the metric "
+      "computation window" );
     SetMinimumParameterIntValue("mry", 0);
 
     AddParameter(ParameterType_InputImage,  "w",   "Image To Warp");
-    SetParameterDescription( "w", "The image to warp after disparity estimation is completed" );
+    SetParameterDescription( "w", "The image to warp after disparity estimation"
+    " is completed." );
     MandatoryOff("w");
 
     AddParameter(ParameterType_OutputImage,  "wo",   "Output Warped Image");
@@ -161,65 +175,81 @@ private:
     MandatoryOff("wo");
 
     AddParameter(ParameterType_Float,  "cox",   "Coarse Offset X");
-    SetParameterDescription( "cox", "Coarse offset along x (in physical space) between the two images" );
+    SetParameterDescription( "cox", "Coarse offset along x (in physical space)"
+      " between the two images, used as an initial offset for all pixels." );
     SetDefaultParameterFloat("cox", 0.0);
     MandatoryOff("cox");
 
     AddParameter(ParameterType_Float,  "coy",   "Coarse Offset Y");
-    SetParameterDescription( "coy", "Coarse offset along y (in physical space) between the two images" );
+    SetParameterDescription( "coy", "Coarse offset along y (in physical space)"
+      " between the two images, used as an initial offset for all pixels." );
     SetDefaultParameterFloat("coy", 0.0);
     MandatoryOff("coy");
 
     AddParameter(ParameterType_Float,  "ssrx",   "Sub-Sampling Rate X");
-    SetParameterDescription( "ssrx", "Generates a result at a coarser resolution with a given sub-sampling rate along X" );
+    SetParameterDescription( "ssrx", "Generates a result at a coarser "
+      "resolution with a given sub-sampling rate along X" );
     SetDefaultParameterFloat("ssrx", 1.0);
     SetMinimumParameterFloatValue("ssrx", 1.0);
     MandatoryOff("ssrx");
 
     AddParameter(ParameterType_Float,  "ssry",   "Sub-Sampling Rate Y");
-    SetParameterDescription( "ssry", "Generates a result at a coarser resolution with a given sub-sampling rate along Y" );
+    SetParameterDescription( "ssry", "Generates a result at a coarser "
+      "resolution with a given sub-sampling rate along Y" );
     SetDefaultParameterFloat("ssry", 1.0);
     SetMinimumParameterFloatValue("ssry", 1.0);
     MandatoryOff("ssry");
 
     AddParameter(ParameterType_Float,  "rgsx",   "Reference Gaussian Smoothing X");
-    SetParameterDescription( "rgsx", "Performs a gaussian smoothing of the reference image. Parameter is gaussian sigma (in pixels) in X direction." );
+    SetParameterDescription( "rgsx", "Performs a gaussian smoothing of the "
+      "reference image. Parameter is gaussian sigma (in pixels) in X direction." );
     MandatoryOff("rgsx");
 
     AddParameter(ParameterType_Float,  "rgsy",   "Reference Gaussian Smoothing Y");
-    SetParameterDescription( "rgsy", "Performs a gaussian smoothing of the reference image. Parameter is gaussian sigma (in pixels) in Y direction." );
+    SetParameterDescription( "rgsy", "Performs a gaussian smoothing of the "
+      "reference image. Parameter is gaussian sigma (in pixels) in Y direction." );
     MandatoryOff("rgsy");
 
     AddParameter(ParameterType_Float,  "sgsx",   "Secondary Gaussian Smoothing X");
-    SetParameterDescription( "sgsx", "Performs a gaussian smoothing of the secondary image. Parameter is gaussian sigma (in pixels) in X direction." );
+    SetParameterDescription( "sgsx", "Performs a gaussian smoothing of the "
+      "secondary image. Parameter is gaussian sigma (in pixels) in X direction." );
     MandatoryOff("sgsx");
 
     AddParameter(ParameterType_Float,  "sgsy",   "Secondary Gaussian Smoothing Y");
-    SetParameterDescription( "sgsy", "Performs a gaussian smoothing of the secondary image. Parameter is gaussian sigma (in pixels) in Y direction." );
+    SetParameterDescription( "sgsy", "Performs a gaussian smoothing of the "
+      "secondary image. Parameter is gaussian sigma (in pixels) in Y direction." );
     MandatoryOff("sgsy");
 
     AddParameter(ParameterType_String,  "m",   "Metric");
-    SetParameterDescription( "m", "Choose the metric used for block matching. Available metrics are cross-correlation (CC), cross-correlation with subtracted mean (CCSM), mean-square difference (MSD), mean reciprocal square difference (MRSD) and mutual information (MI). Default is cross-correlation" );
+    SetParameterDescription( "m", "Choose the metric used for block matching. "
+      "Available metrics are cross-correlation (CC), cross-correlation with "
+      "subtracted mean (CCSM), mean-square difference (MSD), mean reciprocal "
+      "square difference (MRSD) and mutual information (MI). Default is "
+      "cross-correlation" );
     MandatoryOff("m");
 
     AddParameter(ParameterType_Float,  "spa",   "SubPixelAccuracy");
-    SetParameterDescription( "spa", "Metric extrema location will be refined up to the given accuracy. Default is 0.01" );
+    SetParameterDescription( "spa", "Metric extrema location will be refined up"
+      " to the given accuracy. Default is 0.01" );
     SetDefaultParameterFloat("spa", 0.01);
     SetMinimumParameterFloatValue("spa", 0.0);
     MandatoryOff("spa");
 
     AddParameter(ParameterType_Float,  "cva",   "ConvergenceAccuracy");
-    SetParameterDescription( "cva", "Metric extrema will be refined up to the given accuracy. Default is 0.01" );
+    SetParameterDescription( "cva", "Metric extrema will be refined up to the"
+      " given accuracy. Default is 0.01" );
     SetDefaultParameterFloat("cva", 0.01);
     SetMinimumParameterFloatValue("cva", 0.0);
     MandatoryOff("cva");
 
     AddParameter(ParameterType_Float,  "vmlt",   "Validity Mask Lower Threshold");
-    SetParameterDescription( "vmlt", "Lower threshold to obtain a validity mask." );
+    SetParameterDescription( "vmlt", "Lower threshold to compute the validity "
+      "mask. This mask will be the 4th output band." );
     MandatoryOff("vmlt");
 
     AddParameter(ParameterType_Float,  "vmut",   "Validity Mask Upper Threshold");
-    SetParameterDescription( "vmut", "Upper threshold to obtain a validity mask." );
+    SetParameterDescription( "vmut", "Upper threshold to obtain a validity "
+      "mask. This mask will be the 4th output band." );
     MandatoryOff("vmut");
 
     AddRAMParameter();
diff --git a/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx b/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx
index fde86538aef54ca2e7bf7ff6b903325f4ed2665c..928b1da3e6f9303a2c72fb39ce97e335e063abd1 100644
--- a/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx
+++ b/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx
@@ -58,19 +58,38 @@ private:
     SetDescription("Generate a 3D Ply file from a DEM and a color image.");
 
     SetDocName("Ply 3D files generation");
-    SetDocLongDescription("Generate a 3D Ply file from a DEM and a color image.");
-    SetDocLimitations(" ");
+    SetDocLongDescription("The application converts an image containing "
+      "elevations into a PLY file, which is a file format to store 3D models. "
+      "This format is adpated for visualization on software such as MeshLab [2]"
+      " or CloudCompare [3]\n\n"
+      "This application is part of the stereo reconstruction framework. The "
+      "input data can be produced by the application DisparityMapToElevationMap.\n\n"
+      "There are two types of supported input images:\n"
+      "  * A DEM image, with a ground projection, containing elevation values. "
+      "Each elevation value can be considered as a 3D point.\n"
+      "  * A 3D grid image, containing 5 bands (the first 3 are the 3D "
+      "coordinates of each point, the 5th is a validity mask where valid values"
+      " are larger or equal to 1)\n"
+      "\n"
+      "The user shall also give a support image that contains color values for"
+      " each 3D point. The color values will be embedded in the PLY file.");
+    SetDocLimitations("The input DEM image has to entirely fit into memory.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+    SetDocSeeAlso("- [1] DisparityMapToElevationMap \n"
+      "- [2] http://www.meshlab.net/ \n"
+      "- [3] http://www.cloudcompare.org/");
 
     AddDocTag(Tags::Geometry);
 
-    AddParameter(ParameterType_InputImage,"indem","The input DEM");
-    SetParameterDescription("indem", "The input DEM");
+    AddParameter(ParameterType_InputImage,"indem","The input DEM image");
+    SetParameterDescription("indem", "The image should be either a projected "
+      "DEM or a 3D grid containing 3D point coordinates and a validity mask.");
 
     AddParameter(ParameterType_Choice,"mode", "Conversion Mode");
     AddChoice("mode.dem","DEM");
-    SetParameterDescription("mode.dem","DEM conversion mode");
+    SetParameterDescription("mode.dem","DEM conversion mode (the projection "
+      "information of the DEM is used to derive the X and Y coordinates of each"
+      " point)");
 
     AddChoice("mode.3dgrid","3D grid");
     SetParameterDescription("mode.3dgrid","3D grid conversion mode");
@@ -79,10 +98,14 @@ private:
     MapProjectionParametersHandler::AddMapProjectionParameters(this, "map");
 
     AddParameter(ParameterType_InputImage,"incolor","The input color image");
-    SetParameterDescription("incolor", "The input color image");
+    SetParameterDescription("incolor", "If the color image has 4 bands it will "
+      "be interpreted as Red, Green, Blue, NIR. In other cases, only the first "
+      "one is used (gray scale colors). The color values are expected in the "
+      "range 0 - 255, and will be embedded with each 3D ""point of the PLY file.");
 
     AddParameter(ParameterType_OutputFilename,"out","The output Ply file");
-    SetParameterDescription("out","The output Ply file");
+    SetParameterDescription("out","The output Ply file will contain as many 3D "
+      "points as pixels in the input DEM.");
 
     // Doc example
     SetDocExampleParameterValue("indem","image_dem.tif");
diff --git a/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx b/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
index b90ed3ec7225d5fe5c00ffb5983147dd87afd8a0..636b3808081b19a9c69c740b4f0f7954be5db90f 100644
--- a/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
+++ b/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
@@ -27,6 +27,68 @@
 using otb::Wrapper::Application;
 using otb::Wrapper::ApplicationRegistry;
 
+typedef std::pair<std::string,std::string> DocElement;
+
+bool CheckNonEmpty(const DocElement & elem)
+{
+  bool ret = true;
+  if (elem.second == "")
+    {
+    std::cout << "  /!\\ Missing "<< elem.first << std::endl;
+    ret = false;
+    }
+  return ret;
+}
+
+bool CheckMinimumSize(const DocElement & elem, unsigned int size)
+{
+  bool ret = true;
+  if (elem.second.size() < size)
+    {
+    std::cout<<"  /!\\ " << elem.first <<" too small..."<<std::endl;
+    ret = false;
+    }
+  return ret;
+}
+
+bool CheckNoNewline(const DocElement & elem)
+{
+  bool ret = true;
+  if (elem.second.find('\n') != std::string::npos)
+    {
+    std::cout << "  /!\\ "<< elem.first << " should not contain newlines"<<std::endl;
+    ret = false;
+    }
+  return ret;
+}
+
+bool CheckNoTrailingNewline(const DocElement & elem)
+{
+  bool ret = true;
+  std::string whitespace(" \t\f\v\r");
+  size_t pos = elem.second.find_last_not_of(whitespace);
+  if (pos != std::string::npos && elem.second.at(pos) == '\n')
+    {
+    std::cout << "  /!\\ "<< elem.first << " should not end with a newline" << std::endl;
+    ret = false;
+    }
+  return ret;
+}
+
+bool CheckMultiline(const DocElement & elem)
+{
+  bool ret = true;
+  std::string whitespace(" \t\f\v\r");
+  size_t pos = elem.second.find('\n');
+  size_t lastPos = elem.second.find_last_not_of(whitespace);
+  if (pos == std::string::npos || pos == lastPos)
+    {
+    std::cout << "  /!\\ "<< elem.first << " should not be a single line" << std::endl;
+    ret = false;
+    }
+  return ret;
+}
+
 int otbWrapperApplicationDocTest(int argc, char* argv[])
 {
   if (argc < 2)
@@ -69,46 +131,34 @@ int otbWrapperApplicationDocTest(int argc, char* argv[])
       }
 
     // Check doc element...
-    if( std::string(app->GetName()) == "" )
-      {
-      std::cout<<"Missing Name."<<std::endl;
-      isOK = false;
-      }
-    if( std::string(app->GetDocName()) == "" )
-      {
-      std::cout<<"Missing Doc Name."<<std::endl;
-      isOK = false;
-      }
-    if( std::string(app->GetDescription()) == "" )
-      {
-      std::cout<<"Missing Description."<<std::endl;
-      isOK = false;
-      }
-    if( std::string(app->GetDocLongDescription()) == "" )
-      {
-      std::cout<<"Missing DocLongDescription."<<std::endl;
-      isOK = false;
-      }
-    else if( std::string(app->GetDocLongDescription()).size() < 30 )
-      {
-      std::cout<<"DocLongDescription too small..."<<std::endl;
-      isOK = false;
-      }
-    if( std::string(app->GetDocAuthors()) == "" )
-      {
-      std::cout<<"Missing DocAuthors."<<std::endl;
-      isOK = false;
-      }
-    if( std::string(app->GetDocLimitations()) == "" )
-      {
-      std::cout<<"Missing DocLimitations."<<std::endl;
-      isOK = false;
-      }
-    if( std::string(app->GetDocSeeAlso()) == "" )
-      {
-      std::cout<<"Missing DocSeeAlso."<<std::endl;
-      isOK = false;
-      }
+    DocElement name("Name",app->GetName());
+    DocElement docName("Doc Name",app->GetDocName());
+    DocElement description("Description",app->GetDescription());
+    DocElement longDescription("Long description",app->GetDocLongDescription());
+    DocElement authors("DocAuthors",app->GetDocAuthors());
+    DocElement limitations("DocLimitations",app->GetDocLimitations());
+    DocElement seeAlso("DocSeeAlso",app->GetDocSeeAlso());
+
+    isOK = CheckNonEmpty(name) && isOK;
+    isOK = CheckNoNewline(name) && isOK;
+
+    isOK = CheckNonEmpty(docName) && isOK;
+    isOK = CheckNoNewline(docName) && isOK;
+
+    isOK = CheckNonEmpty(description) && isOK;
+
+    isOK = CheckNonEmpty(longDescription) && isOK;
+    isOK = CheckMinimumSize(longDescription,30) && isOK;
+    isOK = CheckNoTrailingNewline(longDescription) && isOK;
+    //isOK = CheckMultiline(longDescription) && isOK;
+
+    isOK = CheckNonEmpty(authors) && isOK;
+
+    isOK = CheckNonEmpty(limitations) && isOK;
+
+    isOK = CheckNonEmpty(seeAlso) && isOK;
+    // TODO : check format of SeeAlso section
+
     if( app->GetDocTags().size() == 0 )
       {
       std::cout<<"Missing DocTags."<<std::endl;
diff --git a/Modules/Core/Common/include/otbUnaryFunctorImageFilter.h b/Modules/Core/Common/include/otbUnaryFunctorImageFilter.h
index 798d8fe6c5aaa75994a24a3718ca84e529be51a4..2217de58baf54d756792382afc2c6080ccda5ddd 100644
--- a/Modules/Core/Common/include/otbUnaryFunctorImageFilter.h
+++ b/Modules/Core/Common/include/otbUnaryFunctorImageFilter.h
@@ -32,7 +32,7 @@ namespace otb
  * Add the capability to change the number of channel when operation on
  * VectorImage compared to the itk::UnaryFunctorImageFilter
  *
- * The number of channel is provided by the functor: TFunction::OutputSize. If
+ * The number of channel is provided by the functor: TFunction::GetOutputSize. If
  * this number is lower or equal to zero, the behavior of the itk::UnaryFunctorImageFilter
  * remains unchanged.
  *
diff --git a/Modules/Core/SpatialObjects/include/otbLineSpatialObject.h b/Modules/Core/SpatialObjects/include/otbLineSpatialObject.h
index cc04dacdd8526f661aa9209b94cdff9e3fb44aa9..a4adf2d0548ce1eb525d6b1804eb484455d12961 100644
--- a/Modules/Core/SpatialObjects/include/otbLineSpatialObject.h
+++ b/Modules/Core/SpatialObjects/include/otbLineSpatialObject.h
@@ -64,6 +64,8 @@ public:
   typedef std::vector<LinePointType>                     PointListType;
   typedef itk::VectorContainer<unsigned long, PointType> PointContainerType;
   typedef itk::SmartPointer<PointContainerType>          PointContainerPointer;
+  typedef itk::SizeValueType SizeValueType;
+  typedef itk::IdentifierType IdentifierType;
 
   /** Returns a reference to the list of the Line points.*/
   PointListType& GetPoints(void);
@@ -72,19 +74,19 @@ public:
   void SetPoints(PointListType& newPoints);
 
   /** Return a point in the list given the index */
-  const SpatialObjectPointType* GetPoint(unsigned long id) const ITK_OVERRIDE
+  const SpatialObjectPointType* GetPoint(IdentifierType id) const ITK_OVERRIDE
   {
     return &(m_Points[id]);
   }
 
   /** Return a point in the list given the index */
-  SpatialObjectPointType* GetPoint(unsigned long id) ITK_OVERRIDE
+  SpatialObjectPointType* GetPoint(IdentifierType id) ITK_OVERRIDE
   {
     return &(m_Points[id]);
   }
 
   /** Return the number of points in the list */
-  itk::SizeValueType GetNumberOfPoints(void) const ITK_OVERRIDE
+  SizeValueType GetNumberOfPoints(void) const ITK_OVERRIDE
   {
     return m_Points.size();
   }
diff --git a/Modules/Filtering/ImageManipulation/include/otbBinaryFunctorImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbBinaryFunctorImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0e246aee5f7e787c0d4b994874bd42f75c01d06
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbBinaryFunctorImageFilter.h
@@ -0,0 +1,84 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef otbBinaryFunctorImageFilter_h
+#define otbBinaryFunctorImageFilter_h
+
+#include "itkBinaryFunctorImageFilter.h"
+
+namespace otb
+{
+/**
+ * \class BinaryFunctorImageFilter
+ * \brief Implements pixel-wise generic operation on two images.
+ *
+ * Add the capability to change the number of channel when operation on
+ * VectorImage compared to the itk::BinaryFunctorImageFilter
+ *
+ * The number of channel is provided by the functor: TFunction::GetOutputSize. If
+ * this number is lower or equal to zero, the behavior of the itk::BinaryFunctorImageFilter
+ * remains unchanged.
+ *
+ * \sa itk::BinaryFunctorImageFilter
+ *
+ * \ingroup OTBImageManipulation
+ */
+template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
+class ITK_EXPORT BinaryFunctorImageFilter : public itk::BinaryFunctorImageFilter<TInputImage1, TInputImage2, TOutputImage, TFunction>
+{
+public:
+  /** Standard class typedefs. */
+  typedef BinaryFunctorImageFilter                                            Self;
+  typedef itk::BinaryFunctorImageFilter<TInputImage1, TInputImage2, TOutputImage, TFunction> Superclass;
+  typedef itk::SmartPointer<Self>                                            Pointer;
+  typedef itk::SmartPointer<const Self>                                      ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(BinaryFunctorImageFilter, itk::BinaryFunctorImageFilter);
+
+protected:
+  BinaryFunctorImageFilter() {};
+  ~BinaryFunctorImageFilter() ITK_OVERRIDE {}
+
+  /** BinaryFunctorImageFilter can produce an image which has a different number of bands
+   * than its input image.  As such, BinaryFunctorImageFilter
+   * needs to provide an implementation for
+   * GenerateOutputInformation() in order to inform the pipeline
+   * execution model.  The original documentation of this method is
+   * below.
+   *
+   * \sa ProcessObject::GenerateOutputInformaton()  */
+  void GenerateOutputInformation() ITK_OVERRIDE
+  {
+    Superclass::GenerateOutputInformation();
+    typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
+    outputPtr->SetNumberOfComponentsPerPixel( // propagate vector length info
+      this->GetFunctor().GetOutputSize());
+  }
+
+private:
+  BinaryFunctorImageFilter(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+};
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbTernaryFunctorImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbTernaryFunctorImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..3e6d3f540505708893faa290c511633e55d4b462
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbTernaryFunctorImageFilter.h
@@ -0,0 +1,84 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef otbTernaryFunctorImageFilter_h
+#define otbTernaryFunctorImageFilter_h
+
+#include "itkTernaryFunctorImageFilter.h"
+
+namespace otb
+{
+/**
+ * \class TernaryFunctorImageFilter
+ * \brief Implements pixel-wise generic operation on three images.
+ *
+ * Add the capability to change the number of channel when operation on
+ * VectorImage compared to the itk::TernaryFunctorImageFilter
+ *
+ * The number of channel is provided by the functor: TFunction::GetOutputSize. If
+ * this number is lower or equal to zero, the behavior of the itk::TernaryFunctorImageFilter
+ * remains unchanged.
+ *
+ * \sa itk::TernaryFunctorImageFilter
+ *
+ * \ingroup OTBImageManipulation
+ */
+template <class TInputImage1, class TInputImage2, class TInputImage3, class TOutputImage, class TFunction>
+class ITK_EXPORT TernaryFunctorImageFilter : public itk::TernaryFunctorImageFilter<TInputImage1, TInputImage2, TInputImage3, TOutputImage, TFunction>
+{
+public:
+  /** Standard class typedefs. */
+  typedef TernaryFunctorImageFilter                                            Self;
+  typedef itk::TernaryFunctorImageFilter<TInputImage1, TInputImage2, TInputImage3, TOutputImage, TFunction> Superclass;
+  typedef itk::SmartPointer<Self>                                            Pointer;
+  typedef itk::SmartPointer<const Self>                                      ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(TernaryFunctorImageFilter, itk::TernaryFunctorImageFilter);
+
+protected:
+  TernaryFunctorImageFilter() {};
+  ~TernaryFunctorImageFilter() ITK_OVERRIDE {}
+
+  /** TernaryFunctorImageFilter can produce an image which has a different number of bands
+   * than its input image.  As such, TernaryFunctorImageFilter
+   * needs to provide an implementation for
+   * GenerateOutputInformation() in order to inform the pipeline
+   * execution model.  The original documentation of this method is
+   * below.
+   *
+   * \sa ProcessObject::GenerateOutputInformaton()  */
+  void GenerateOutputInformation() ITK_OVERRIDE
+  {
+    Superclass::GenerateOutputInformation();
+    typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
+    outputPtr->SetNumberOfComponentsPerPixel( // propagate vector length info
+      this->GetFunctor().GetOutputSize());
+  }
+
+private:
+  TernaryFunctorImageFilter(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+};
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/Polarimetry/test/CMakeLists.txt b/Modules/Filtering/Polarimetry/test/CMakeLists.txt
index 73045f5cd8b40c0395a34604f11abb85dceeaa24..d1c77627cf5316b3353b3eab49f760faca17a690 100644
--- a/Modules/Filtering/Polarimetry/test/CMakeLists.txt
+++ b/Modules/Filtering/Polarimetry/test/CMakeLists.txt
@@ -74,7 +74,7 @@ otb_add_test(NAME saTvVectorMultiChannelsPolarimetricSynthesisFilter COMMAND otb
   --compare-image ${EPSILON_7}   ${BASELINE}/saTvMultiPolarimetricSynthesis1.tif
   ${TEMP}/resMultiPolarimetricSynthesis1.tif
   otbVectorMultiChannelsPolarimetricSynthesisFilter
-  ${INPUTDATA}/RSAT2_AltonaExtract_1000_1000_100_100.hdr
+  ${INPUTDATA}/RSAT2_AltonaExtract_1000_1000_100_100.tif
   ${TEMP}/resMultiPolarimetricSynthesis1.tif
   10.0     # PsiI
   0.0     # KhiI
diff --git a/Modules/Hyperspectral/EndmembersExtraction/include/otbVcaImageFilter.txx b/Modules/Hyperspectral/EndmembersExtraction/include/otbVcaImageFilter.txx
index 919e3a6d322dc4d5d9cc2e2cf88d16fc457f8629..014ff8e7eef8cc32e52e8154eb583dbab4142020 100644
--- a/Modules/Hyperspectral/EndmembersExtraction/include/otbVcaImageFilter.txx
+++ b/Modules/Hyperspectral/EndmembersExtraction/include/otbVcaImageFilter.txx
@@ -233,7 +233,7 @@ void VCAImageFilter<TImage>::GenerateData()
   vnl_matrix<PrecisionType> A(m_NumberOfEndmembers, m_NumberOfEndmembers);
   A.fill(0);
   A(m_NumberOfEndmembers - 1, 0) = 1;
-  typename RandomVariateGeneratorType::Pointer randomGen = RandomVariateGeneratorType::New();
+  typename RandomVariateGeneratorType::Pointer randomGen = RandomVariateGeneratorType::GetInstance();
 
   for (unsigned int i = 0; i < m_NumberOfEndmembers; ++i)
     {
diff --git a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
index 4e3b75a54835bd4fdd132f431fecc2336806d0fe..812c938e6b86b6dd5005abc9939e5275b639f8e5 100644
--- a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
+++ b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
@@ -1766,19 +1766,26 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
   /* -------------------------------------------------------------------- */
   /*  Set the six coefficients of affine geoTransform                     */
   /* -------------------------------------------------------------------- */
-  itk::VariableLengthVector<double> geoTransform(6);
-  /// Reporting origin and spacing
-  // Beware : GDAL origin is at the corner of the top-left pixel
-  // whereas OTB/ITK origin is at the centre of the top-left pixel
-  geoTransform[0] = m_Origin[0] - 0.5*m_Spacing[0];
-  geoTransform[3] = m_Origin[1] - 0.5*m_Spacing[1];
-  geoTransform[1] = m_Spacing[0];
-  geoTransform[5] = m_Spacing[1];
-
-  // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
-  geoTransform[2] = 0.;
-  geoTransform[4] = 0.;
-  dataset->SetGeoTransform(const_cast<double*>(geoTransform.GetDataPointer()));
+  if ( vcl_abs(m_Origin[0] - 0.5) > Epsilon
+    || vcl_abs(m_Origin[1] - 0.5) > Epsilon
+    || vcl_abs(m_Spacing[0] - 1.0) > Epsilon
+    || vcl_abs(m_Spacing[1] - 1.0) > Epsilon )
+    {
+    // Only set the geotransform if it is not identity (it may erase GCP)
+    itk::VariableLengthVector<double> geoTransform(6);
+    /// Reporting origin and spacing
+    // Beware : GDAL origin is at the corner of the top-left pixel
+    // whereas OTB/ITK origin is at the centre of the top-left pixel
+    geoTransform[0] = m_Origin[0] - 0.5*m_Spacing[0];
+    geoTransform[3] = m_Origin[1] - 0.5*m_Spacing[1];
+    geoTransform[1] = m_Spacing[0];
+    geoTransform[5] = m_Spacing[1];
+
+    // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
+    geoTransform[2] = 0.;
+    geoTransform[4] = 0.;
+    dataset->SetGeoTransform(const_cast<double*>(geoTransform.GetDataPointer()));
+    }
 
   /* -------------------------------------------------------------------- */
   /*      Report metadata.                                                */
diff --git a/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx b/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
index 8248ef8a1df7019224761445e628f1f59e3d573a..53b61999699415cf18f36e1f182cf698560fbe4a 100644
--- a/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
+++ b/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
@@ -211,7 +211,7 @@ void OGRIOHelper
     otb::VectorDataKeywordlist kwl;
     for (int fieldNum = 0; fieldNum < feature->GetFieldCount(); ++fieldNum)
       {
-      if (feature->IsFieldSet(fieldNum))
+      if (ogr::version_proxy::IsFieldSetAndNotNull(feature, fieldNum))
         {
         kwl.AddField(feature->GetFieldDefnRef(fieldNum), feature->GetRawFieldRef(fieldNum));
         }
diff --git a/Modules/IO/TestKernel/src/otbTestHelper.cxx b/Modules/IO/TestKernel/src/otbTestHelper.cxx
index dfdd2345b95d7649b02cf56091b80d7a309f7769..9c1559a7138dbd3da2f5917ee6d2fe66d4dae441 100644
--- a/Modules/IO/TestKernel/src/otbTestHelper.cxx
+++ b/Modules/IO/TestKernel/src/otbTestHelper.cxx
@@ -1941,7 +1941,7 @@ void TestHelper::DumpOGRFeature(FILE* fpOut, OGRFeature* feature, char** papszOp
               poFDefn->GetNameRef(),
               OGRFieldDefn::GetFieldTypeName(poFDefn->GetType()));
 
-      if (feature->IsFieldSet(iField)) fprintf(fpOut, "%s\n", feature->GetFieldAsString(iField));
+      if (ogr::version_proxy::IsFieldSetAndNotNull(feature, iField)) fprintf(fpOut, "%s\n", feature->GetFieldAsString(iField));
       else fprintf(fpOut, "(null)\n");
 
       }
diff --git a/Modules/Learning/LearningBase/include/otbMachineLearningModel.h b/Modules/Learning/LearningBase/include/otbMachineLearningModel.h
index c5fb59f28c9fa5931351921309b5ac35cbf46b48..552880cb9a83a4e43b7e29ae75689613633e5ef0 100644
--- a/Modules/Learning/LearningBase/include/otbMachineLearningModel.h
+++ b/Modules/Learning/LearningBase/include/otbMachineLearningModel.h
@@ -22,8 +22,8 @@
 #define otbMachineLearningModel_h
 
 #include "itkObject.h"
-#include "itkVariableLengthVector.h"
 #include "itkListSample.h"
+#include "otbMachineLearningModelTraits.h"
 
 namespace otb
 {
@@ -66,6 +66,7 @@ namespace otb
  *
  * \ingroup OTBLearningBase
  */
+
 template <class TInputValue, class TTargetValue, class TConfidenceValue = double >
 class ITK_EXPORT MachineLearningModel
   : public itk::Object
@@ -81,22 +82,22 @@ public:
 
   /**\name Input related typedefs */
   //@{
-  typedef TInputValue                                   InputValueType;
-  typedef itk::VariableLengthVector<InputValueType>     InputSampleType;
-  typedef itk::Statistics::ListSample<InputSampleType>  InputListSampleType;
+  typedef typename MLMSampleTraits<TInputValue>::ValueType  InputValueType;
+  typedef typename MLMSampleTraits<TInputValue>::SampleType InputSampleType;
+  typedef itk::Statistics::ListSample<InputSampleType>      InputListSampleType;
   //@}
 
   /**\name Target related typedefs */
   //@{
-  typedef TTargetValue                                  TargetValueType;
-  typedef itk::FixedArray<TargetValueType,1>            TargetSampleType;
-  typedef itk::Statistics::ListSample<TargetSampleType> TargetListSampleType;
+  typedef typename MLMTargetTraits<TTargetValue>::ValueType  TargetValueType;
+  typedef typename MLMTargetTraits<TTargetValue>::SampleType TargetSampleType;
+  typedef itk::Statistics::ListSample<TargetSampleType>      TargetListSampleType;
   //@}
 
   /**\name Confidence value typedef */
-  typedef TConfidenceValue                                  ConfidenceValueType;
-  typedef itk::FixedArray<ConfidenceValueType,1>            ConfidenceSampleType;
-  typedef itk::Statistics::ListSample<ConfidenceSampleType> ConfidenceListSampleType;
+  typedef typename MLMTargetTraits<TConfidenceValue>::ValueType  ConfidenceValueType;
+  typedef typename MLMTargetTraits<TConfidenceValue>::SampleType ConfidenceSampleType;
+  typedef itk::Statistics::ListSample<ConfidenceSampleType>      ConfidenceListSampleType;
 
   /**\name Standard macros */
   //@{
diff --git a/Modules/Learning/LearningBase/include/otbMachineLearningModelTraits.h b/Modules/Learning/LearningBase/include/otbMachineLearningModelTraits.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9bc4cec29b9b3b45891e0265d63009bff34b76e
--- /dev/null
+++ b/Modules/Learning/LearningBase/include/otbMachineLearningModelTraits.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2005-2017 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.
+ */
+
+
+#ifndef otbMachineLearningModelTraits_h
+#define otbMachineLearningModelTraits_h
+
+
+#include "itkVariableLengthVector.h"
+#include "itkFixedArray.h"
+#include "itkIsNumber.h"
+#include "itkMetaProgrammingLibrary.h"
+
+namespace otb
+{
+
+/**
+ * This is the struct defining the sample implementation for
+ * MachineLearningModel. It offers two type definitions: SampleType
+ * and ValueType.
+ *
+ * \tparam TInput : input sample type (can be either a scalar type or
+ * a VariableLenghtVector
+ * \tparam isNumber either TrueType or FalseType for partial
+ * specialization
+  
+ */
+template <typename TInput, typename isNumber> struct MLMSampleTraitsImpl;
+
+
+/// \cond SPECIALIZATION_IMPLEMENTATION
+// For Numbers
+template <typename TInput> struct MLMSampleTraitsImpl<TInput, itk::mpl::TrueType> {
+  typedef TInput                             ValueType;
+   typedef itk::VariableLengthVector<TInput> SampleType;
+};
+
+// For Vectors
+template <typename TInput> struct MLMSampleTraitsImpl<TInput, itk::mpl::FalseType> {
+  typedef typename TInput::ValueType        ValueType;
+  typedef TInput                            SampleType;
+};
+/// \endcond
+
+/**
+ * Simplified implementation of SampleTraits using MLMSampleTraitsImpl
+ */
+template <typename TInput> using MLMSampleTraits = MLMSampleTraitsImpl< TInput, typename itk::mpl::IsNumber<TInput>::Type >;
+
+
+/**
+ * This is the struct defining the sample implementation for
+ * MachineLearningModel. It offers two type definitions: TargetType
+ * and ValueType.
+ *
+ * \tparam TInput : input sample type (can be either a scalar type or
+ * a VariableLenghtVector or a FixedArray
+ * \tparam isNumber either TrueType or FalseType for partial
+ * specialization
+  
+ */
+template <typename TInput, typename isNumber> struct MLMTargetTraitsImpl;
+
+
+/// \cond SPECIALIZATION_IMPLEMENTATION
+// For Numbers
+template <typename TInput> struct MLMTargetTraitsImpl<TInput, itk::mpl::TrueType> {
+  typedef TInput                             ValueType;
+  typedef itk::FixedArray<TInput,1>          SampleType;
+};
+
+// For Vectors
+template <typename TInput> struct MLMTargetTraitsImpl<TInput, itk::mpl::FalseType> {
+  typedef typename TInput::ValueType        ValueType;
+  typedef TInput                            SampleType;
+};
+/// \endcond
+
+/**
+ * Simplified implementation of TargetTraits using MLMTargetTraitsImpl
+ */
+template <typename TInput> using MLMTargetTraits = MLMTargetTraitsImpl< TInput, typename itk::mpl::IsNumber<TInput>::Type >;
+
+
+} // End namespace otb
+
+#endif
diff --git a/Modules/Learning/LearningBase/test/CMakeLists.txt b/Modules/Learning/LearningBase/test/CMakeLists.txt
index 74a67d44dddd939201c134f28be152281b85a7a2..d1d16c3e65801e606c6e6903538b65264a4483a6 100644
--- a/Modules/Learning/LearningBase/test/CMakeLists.txt
+++ b/Modules/Learning/LearningBase/test/CMakeLists.txt
@@ -29,6 +29,7 @@ otbDecisionTreeWithRealValues.cxx
 otbSEMClassifierNew.cxx
 otbDecisionTreeNew.cxx
 otbKMeansImageClassificationFilterNew.cxx
+otbMachineLearningModelTemplates.cxx
 )
 
 add_executable(otbLearningBaseTestDriver ${OTBLearningBaseTests})
diff --git a/Modules/Learning/LearningBase/test/otbMachineLearningModelTemplates.cxx b/Modules/Learning/LearningBase/test/otbMachineLearningModelTemplates.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..96d35e014394d6b0d6836a90ddcbf3a2303db4bf
--- /dev/null
+++ b/Modules/Learning/LearningBase/test/otbMachineLearningModelTemplates.cxx
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005-2017 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 <otbMachineLearningModel.h>
+
+typedef otb::MachineLearningModel<float,short>          MachineLearningModelType1;
+typedef MachineLearningModelType1::InputValueType       InputValueType1;
+typedef MachineLearningModelType1::InputSampleType      InputSampleType1;
+typedef MachineLearningModelType1::InputListSampleType  InputListSampleType1;
+typedef MachineLearningModelType1::TargetValueType      TargetValueType1;
+typedef MachineLearningModelType1::TargetSampleType     TargetSampleType1;
+typedef MachineLearningModelType1::TargetListSampleType TargetListSampleType1;
+
+typedef otb::MachineLearningModel<float,itk::VariableLengthVector<double> > MachineLearningModelType2;
+typedef MachineLearningModelType2::InputValueType       InputValueType2;
+typedef MachineLearningModelType2::InputSampleType      InputSampleType2;
+typedef MachineLearningModelType2::InputListSampleType  InputListSampleType2;
+typedef MachineLearningModelType2::TargetValueType      TargetValueType2;
+typedef MachineLearningModelType2::TargetSampleType     TargetSampleType2;
+typedef MachineLearningModelType2::TargetListSampleType TargetListSampleType2;
+
+
+
diff --git a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx
index 8e3850392e50d3cf6ca64eae74d49d4e1dd0133c..d5faa1064cb5c5a589dba2d64f5909d07007ff24 100644
--- a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx
+++ b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.txx
@@ -175,6 +175,7 @@ PersistentImageSampleExtractorFilter<TInputImage>
   IndexType imgIndex;
   PixelType imgPixel;
   double imgComp;
+
   ogr::Layer::const_iterator featIt = layerForThread.begin();
   for(; featIt!=layerForThread.end(); ++featIt)
     {
diff --git a/Modules/Remote/Mosaic.remote.cmake b/Modules/Remote/Mosaic.remote.cmake
index adfa72d32c7efb2f6171a63b2110352a0f141774..c6f4a068dfbc4a348c9ca7bd1370a02682353100 100644
--- a/Modules/Remote/Mosaic.remote.cmake
+++ b/Modules/Remote/Mosaic.remote.cmake
@@ -5,5 +5,5 @@ A more detailed description can be found on the project website:
 https://github.com/remicres/otb-mosaic
 "
   GIT_REPOSITORY https://github.com/remicres/otb-mosaic.git
-  GIT_TAG 516dfa7e7b91aa0263e495ee6b3878a03ced9173
+  GIT_TAG master
 )
diff --git a/SuperBuild/CMake/External_boost.cmake b/SuperBuild/CMake/External_boost.cmake
index 8dc75b7a2d4a8e1943dfb19b78a3df7d22bd0851..baff81fc2a466ddd4d98c2d2c7af842de5d76bce 100644
--- a/SuperBuild/CMake/External_boost.cmake
+++ b/SuperBuild/CMake/External_boost.cmake
@@ -71,7 +71,7 @@ set(BOOST_BUILD_COMMAND ${CMAKE_COMMAND}
 #NOTE: update _SB_Boost_INCLUDE_DIR below when you change version number
 ExternalProject_Add(BOOST
   PREFIX BOOST
-  URL "http://download.sourceforge.net/project/boost/boost/1.60.0/boost_1_60_0.tar.bz2"
+  URL "http://downloads.sourceforge.net/project/boost/boost/1.60.0/boost_1_60_0.tar.bz2"
   URL_MD5 65a840e1a0b13a558ff19eeb2c4f0cbe
   BINARY_DIR ${BOOST_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -79,6 +79,7 @@ ExternalProject_Add(BOOST
   CONFIGURE_COMMAND ${BOOST_CONFIGURE_COMMAND}
   BUILD_COMMAND ${BOOST_BUILD_COMMAND}
   INSTALL_COMMAND ""
+  LOG_DOWNLOAD 1
   LOG_CONFIGURE 1
   LOG_BUILD 1
   LOG_INSTALL 1  
diff --git a/SuperBuild/CMake/External_curl.cmake b/SuperBuild/CMake/External_curl.cmake
index fc6fe75d08b1005ea14b66e9e34df5f5398c4c0d..8728bdeb7e8a02c4af70125d157e3cd492862015 100644
--- a/SuperBuild/CMake/External_curl.cmake
+++ b/SuperBuild/CMake/External_curl.cmake
@@ -24,64 +24,41 @@ SETUP_SUPERBUILD(CURL)
 
 # declare dependencies
 ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(CURL ZLIB)
-
 if(NOT APPLE)
-  ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(OPENSSL)
+  ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(CURL OPENSSL)
 endif()
 
-if(MSVC)
-  if(NOT BUILD_SHARED_LIBS)
-    message(FATAL_ERROR "static build or curl not supported")
-    return()
-  endif()
-
-  if(OTB_TARGET_SYSTEM_ARCH_IS_X64)
-    set(CURL_INSTALL_DIR_PREFIX "libcurl-vc-x64")
-  else()
-    set(CURL_INSTALL_DIR_PREFIX "libcurl-vc-x86")
-  endif()
-
-  set(CURL_INSTALL_DIR_PREFIX "${CURL_INSTALL_DIR_PREFIX}-release-dll-zlib-dll-ipv6-sspi-winssl")
-
-  ExternalProject_Add(CURL
+ExternalProject_Add(CURL
   PREFIX CURL
   URL "http://curl.haxx.se/download/curl-7.40.0.tar.gz"
   URL_MD5 58943642ea0ed050ab0431ea1caf3a6f
-  SOURCE_DIR ${CURL_SB_SRC}
-  BINARY_DIR ${CURL_SB_SRC}/winbuild
+  BINARY_DIR ${CURL_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
   DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
+  CMAKE_CACHE_ARGS
+  ${SB_CMAKE_CACHE_ARGS}
+  -DBUILD_CURL_TESTS:BOOL=OFF
+  -DBUILD_CURL_EXE:BOOL=ON
+  -DCMAKE_USE_OPENSSL:BOOL=OFF
+  -DCMAKE_USE_LIBSSH2:BOOL=OFF
+  -DCURL_DISABLE_LDAP:BOOL=ON
+  -DCMAKE_USE_OPENLDAP:BOOL=OFF
+  -DENABLE_MANUAL:BOOL=OFF
+  -DENABLE_IPV6:BOOL=OFF
+  ${CURL_SB_CONFIG}
   DEPENDS ${CURL_DEPENDENCIES}
-  CONFIGURE_COMMAND ""
-  BUILD_COMMAND nmake /f ${CURL_SB_SRC}/winbuild/Makefile.vc mode=dll WITH_ZLIB=dll WITH_DEVEL=${SB_INSTALL_PREFIX}
-  INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory
-  ${CURL_SB_SRC}/builds/${CURL_INSTALL_DIR_PREFIX}/ ${SB_INSTALL_PREFIX}
+  CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
-else(UNIX)
+SUPERBUILD_PATCH_SOURCE(CURL)
 
-  ExternalProject_Add(CURL
-    PREFIX CURL
-    URL "http://curl.haxx.se/download/curl-7.40.0.tar.gz"
-    URL_MD5 58943642ea0ed050ab0431ea1caf3a6f
-    BINARY_DIR ${CURL_SB_BUILD_DIR}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    CMAKE_CACHE_ARGS
-    ${SB_CMAKE_CACHE_ARGS}
-    -DBUILD_CURL_TESTS:BOOL=OFF
-    -DBUILD_CURL_EXE:BOOL=ON
-    -DCMAKE_USE_OPENSSL:BOOL=${SB_ENABLE_OPENSSL_CURL}
-    -DCMAKE_USE_LIBSSH2:BOOL=OFF
-    -DCURL_DISABLE_LDAP:BOOL=ON
-    -DCMAKE_USE_OPENLDAP:BOOL=OFF
-    ${CURL_SB_CONFIG}
-    DEPENDS ${CURL_DEPENDENCIES}
-    CMAKE_COMMAND ${SB_CMAKE_COMMAND}
-    LOG_CONFIGURE 1
-    LOG_BUILD 1
-    LOG_INSTALL 1
-    )
+set(_SB_CURL_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
+if(WIN32)
+  set(_SB_CURL_LIBRARY "${SB_INSTALL_PREFIX}/lib/libcurl_imp.lib")
+elseif(UNIX)
+  set(_SB_CURL_LIBRARY ${SB_INSTALL_PREFIX}/lib/libcurl${CMAKE_SHARED_LIBRARY_SUFFIX})
 endif()
-
-SUPERBUILD_UPDATE_CMAKE_VARIABLES(CURL TRUE)
diff --git a/SuperBuild/CMake/External_expat.cmake b/SuperBuild/CMake/External_expat.cmake
index 2991992a9875afa5735d9a4478288065691c6e14..d59f4391faf8a06f7d8b84d786afef692244a44e 100644
--- a/SuperBuild/CMake/External_expat.cmake
+++ b/SuperBuild/CMake/External_expat.cmake
@@ -24,7 +24,7 @@ SETUP_SUPERBUILD(EXPAT)
 
 ExternalProject_Add(EXPAT
   PREFIX EXPAT
-  URL "http://sourceforge.net/projects/expat/files/expat/2.1.0/expat-2.1.0.tar.gz/download"
+  URL "http://downloads.sourceforge.net/project/expat/expat/2.1.0/expat-2.1.0.tar.gz"
   URL_MD5 dd7dab7a5fea97d2a6a43f511449b7cd
   BINARY_DIR ${EXPAT_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -35,6 +35,10 @@ ExternalProject_Add(EXPAT
   -DBUILD_tests:BOOL=OFF
   -DBUILD_tools:BOOL=OFF
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 SUPERBUILD_UPDATE_CMAKE_VARIABLES(EXPAT FALSE)
diff --git a/SuperBuild/CMake/External_fftw.cmake b/SuperBuild/CMake/External_fftw.cmake
index a6969ab7b225836c475f196d01de19c51383522c..ce1bdbea7f377f3402465e0d31867f46bb05922f 100644
--- a/SuperBuild/CMake/External_fftw.cmake
+++ b/SuperBuild/CMake/External_fftw.cmake
@@ -54,6 +54,7 @@ ExternalProject_Add(FFTWF
   --disable-fortran
   --disable-dependency-tracking
   DEPENDS ${FFTW_DEPENDENCIES}
+  LOG_CONFIGURE 1
   LOG_BUILD 1
   LOG_INSTALL 1
   )
@@ -80,6 +81,8 @@ ExternalProject_Add(FFTWD
   --disable-fortran
   --disable-dependency-tracking
   DEPENDS FFTWF
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
   LOG_BUILD 1
   LOG_INSTALL 1  
   )
diff --git a/SuperBuild/CMake/External_freetype.cmake b/SuperBuild/CMake/External_freetype.cmake
index 014e35f0ccbc44730f248d9d3f26e9c4a8cb0c48..1af53391eb1546030311305916d1e902696222fa 100644
--- a/SuperBuild/CMake/External_freetype.cmake
+++ b/SuperBuild/CMake/External_freetype.cmake
@@ -39,6 +39,10 @@ ExternalProject_Add(FREETYPE
   ${SB_CMAKE_CACHE_ARGS}
   ${FREETYPE_SB_CONFIG}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 set(_SB_FREETYPE_INCLUDE_DIRS ${SB_INSTALL_PREFIX}/include/freetype2)
diff --git a/SuperBuild/CMake/External_gdal.cmake b/SuperBuild/CMake/External_gdal.cmake
index aa87dc9f44e755b5e1824c90f9a2b01f682c4e45..fd7ed1836132c30fe132e67c14c3add1ca92f11e 100644
--- a/SuperBuild/CMake/External_gdal.cmake
+++ b/SuperBuild/CMake/External_gdal.cmake
@@ -65,7 +65,6 @@ if(UNIX)
     ${SB_CONFIGURE_ARGS}
     --with-cfitsio=no
     --with-dods-root=no
-    --with-dwgdirect=no
     --with-ecw=no
     --with-epsilon=no
     --with-fme=no
@@ -100,6 +99,8 @@ if(UNIX)
     --with-xerces=no
     --with-xml2=no
     --with-pg=no
+    --with-webp=no
+    --with-threads=yes
     ${GDAL_SB_CONFIG}
     ${GDAL_SB_EXTRA_OPTIONS}
     )
@@ -107,8 +108,6 @@ if(UNIX)
   #set(GDAL_INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install)
 
 else(MSVC)
-  STRING(REGEX REPLACE "/$" "" CMAKE_WIN_INSTALL_PREFIX ${SB_INSTALL_PREFIX})
-  STRING(REGEX REPLACE "/" "\\\\" CMAKE_WIN_INSTALL_PREFIX ${CMAKE_WIN_INSTALL_PREFIX})
   configure_file(
     ${CMAKE_SOURCE_DIR}/patches/GDAL/nmake_gdal_extra.opt.in
     ${CMAKE_BINARY_DIR}/nmake_gdal_extra.opt)
@@ -133,8 +132,8 @@ endif()
 
 ExternalProject_Add(GDAL
   PREFIX GDAL
-  URL "http://download.osgeo.org/gdal/2.1.0/gdal-2.1.0.tar.gz"
-  URL_MD5 0fc165cd947c54b132204233dfb243f1
+  URL "http://download.osgeo.org/gdal/2.2.1/gdal-2.2.1.tar.gz"
+  URL_MD5 785acf2b0cbf9d56d37c9044d0ee2505
   SOURCE_DIR ${GDAL_SB_SRC}
   BINARY_DIR ${GDAL_SB_SRC}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -143,6 +142,7 @@ ExternalProject_Add(GDAL
   CONFIGURE_COMMAND ${GDAL_CONFIGURE_COMMAND}
   BUILD_COMMAND ${GDAL_BUILD_COMMAND}
   INSTALL_COMMAND ${GDAL_INSTALL_COMMAND}
+  LOG_DOWNLOAD 1
   LOG_CONFIGURE 1
   LOG_BUILD 1
   LOG_INSTALL 1
diff --git a/SuperBuild/CMake/External_geos.cmake b/SuperBuild/CMake/External_geos.cmake
index f129a04379cd304f097e5425df52b29a0c73e913..921aa4d667cf4ba7f621cb8965ca47af08742c61 100644
--- a/SuperBuild/CMake/External_geos.cmake
+++ b/SuperBuild/CMake/External_geos.cmake
@@ -22,23 +22,10 @@ INCLUDE_ONCE_MACRO(GEOS)
 
 SETUP_SUPERBUILD(GEOS)
 
-if(MSVC)
-  set(GEOS_PATCH_COMMAND ${CMAKE_COMMAND} -E copy
-	  ${CMAKE_SOURCE_DIR}/patches/GEOS/CMakeLists.txt
-	  ${CMAKE_SOURCE_DIR}/patches/GEOS/nmake.opt
-	  ${GEOS_SB_SRC})
-  set(GEOS_CMAKE_COMMAND ${SB_CMAKE_COMMAND} -DGEOS_SB_SRC=${GEOS_SB_SRC})
-
-else()
-  set(GEOS_PATCH_COMMAND)
-  set(GEOS_CMAKE_COMMAND ${SB_CMAKE_COMMAND})
-
-endif()
-
 ExternalProject_Add(GEOS
    PREFIX GEOS
-   URL "http://download.osgeo.org/geos/geos-3.5.0.tar.bz2"
-   URL_MD5 136842690be7f504fba46b3c539438dd
+   URL "http://download.osgeo.org/geos/geos-3.6.1.tar.bz2"
+   URL_MD5 c97e338b3bc81f9848656e9d693ca6cc
    SOURCE_DIR ${GEOS_SB_SRC}
    BINARY_DIR ${GEOS_SB_SRC}
    INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -46,17 +33,23 @@ ExternalProject_Add(GEOS
    CMAKE_CACHE_ARGS
    ${SB_CMAKE_CACHE_ARGS}
    -DGEOS_ENABLE_TESTS:BOOL=OFF
-   PATCH_COMMAND ${GEOS_PATCH_COMMAND}
+   -DGEOS_ENABLE_MACOSX_FRAMEWORK:BOOL=OFF
+   -DGEOS_BUILD_STATIC:BOOL=${BUILD_STATIC_LIBS}
+   -DGEOS_BUILD_SHARED:BOOL=${BUILD_SHARED_LIBS}
    CMAKE_COMMAND ${GEOS_CMAKE_COMMAND}
+   LOG_DOWNLOAD 1
+   LOG_CONFIGURE 1
+   LOG_BUILD 1
+   LOG_INSTALL 1
    )
 
-if(NOT MSVC)
-  SUPERBUILD_PATCH_SOURCE(GEOS)
-endif()
+# Patch still needed with version 3.6.1 to avoid error during CMake configuration
+# See https://trac.osgeo.org/geos/ticket/753
+SUPERBUILD_PATCH_SOURCE(GEOS)
 
 set(_SB_GEOS_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
 if(WIN32)
-  set(_SB_GEOS_LIBRARY ${SB_INSTALL_PREFIX}/lib/geos_i.lib )
+  set(_SB_GEOS_LIBRARY ${SB_INSTALL_PREFIX}/lib/geos.lib )
 elseif(UNIX)
   set(_SB_GEOS_LIBRARY ${SB_INSTALL_PREFIX}/lib/libgeos${CMAKE_SHARED_LIBRARY_SUFFIX})
-endif()
\ No newline at end of file
+endif()
diff --git a/SuperBuild/CMake/External_geotiff.cmake b/SuperBuild/CMake/External_geotiff.cmake
index 99babdd855a58186668364bbea4be881fb3ff479..3bb24a3202b39db9724a8261da78bf7fdfdf86fc 100644
--- a/SuperBuild/CMake/External_geotiff.cmake
+++ b/SuperBuild/CMake/External_geotiff.cmake
@@ -35,59 +35,28 @@ ADD_SUPERBUILD_CMAKE_VAR(GEOTIFF ZLIB_LIBRARY)
 ADD_SUPERBUILD_CMAKE_VAR(GEOTIFF JPEG_INCLUDE_DIR)
 ADD_SUPERBUILD_CMAKE_VAR(GEOTIFF JPEG_LIBRARY)
 
-#RK: we are forced to use autoconf on osx due to cmake's find_* functions
-#Do we need to use the same of Linux ?
-if(UNIX)
-  set(GEOTIFF_SB_CONFIG)
-  ADD_SUPERBUILD_CONFIGURE_VAR(GEOTIFF PROJ_ROOT     --with-proj)
-  ADD_SUPERBUILD_CONFIGURE_VAR(GEOTIFF TIFF_ROOT     --with-libtiff)
-  ADD_SUPERBUILD_CONFIGURE_VAR(GEOTIFF JPEG_ROOT     --with-jpeg)
-  ADD_SUPERBUILD_CONFIGURE_VAR(GEOTIFF ZLIB_ROOT     --with-libz)
+ExternalProject_Add(GEOTIFF
+  PREFIX GEOTIFF
+  URL "http://download.osgeo.org/geotiff/libgeotiff/libgeotiff-1.4.2.tar.gz"
+  URL_MD5 96ab80e0d4eff7820579957245d844f8
+  SOURCE_DIR ${GEOTIFF_SB_SRC}
+  BINARY_DIR ${GEOTIFF_SB_BUILD_DIR}
+  INSTALL_DIR ${SB_INSTALL_PREFIX}
+  DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
+  DEPENDS ${GEOTIFF_DEPENDENCIES}
+  CMAKE_CACHE_ARGS
+  ${SB_CMAKE_CACHE_ARGS}
+  -DBUILD_TESTING:BOOL=OFF
+  -DPROJ4_OSGEO4W_HOME:PATH=${SB_INSTALL_PREFIX}
+  ${GEOTIFF_SB_CONFIG}
+  CMAKE_COMMAND ${SB_CMAE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
+  )
 
-  ExternalProject_Add(GEOTIFF
-    PREFIX GEOTIFF
-    URL "http://download.osgeo.org/geotiff/libgeotiff/libgeotiff-1.4.1.tar.gz"
-    URL_MD5 48bdf817e6e7a37671cc1f41b01e10fc
-    SOURCE_DIR ${GEOTIFF_SB_SRC}
-    BINARY_DIR ${GEOTIFF_SB_SRC}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    DEPENDS ${GEOTIFF_DEPENDENCIES}
-    CONFIGURE_COMMAND
-    ${SB_ENV_CONFIGURE_CMD}
-    ${GEOTIFF_SB_SRC}/configure
-    ${SB_CONFIGURE_ARGS}
-    ${GEOTIFF_SB_CONFIG}
-    LOG_BUILD 1
-    LOG_INSTALL 1
-    )
-
-  # [LOG_CONFIGURE 1]           # Wrap configure in script to log output
-  # [LOG_BUILD 1]               # Wrap build in script to log output
-  # [LOG_TEST 1]                # Wrap test in script to log output
-  # [LOG_INSTALL 1]             # Wrap install in script to log output
-  SUPERBUILD_PATCH_SOURCE(GEOTIFF)
-
-else()
-
-  ExternalProject_Add(GEOTIFF
-    PREFIX GEOTIFF
-    URL "http://download.osgeo.org/geotiff/libgeotiff/libgeotiff-1.4.1.tar.gz"
-    URL_MD5 48bdf817e6e7a37671cc1f41b01e10fc
-    SOURCE_DIR ${GEOTIFF_SB_SRC}
-    BINARY_DIR ${GEOTIFF_SB_BUILD_DIR}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    DEPENDS ${GEOTIFF_DEPENDENCIES}
-    CMAKE_CACHE_ARGS
-    ${SB_CMAKE_CACHE_ARGS}
-    -DBUILD_TESTING:BOOL=OFF
-    -DPROJ4_OSGEO4W_HOME:PATH=${SB_INSTALL_PREFIX}
-    ${GEOTIFF_SB_CONFIG}
-    CMAKE_COMMAND ${SB_CMAKE_COMMAND}
-    )
-
-endif()
+SUPERBUILD_PATCH_SOURCE(GEOTIFF)
 
 set(_SB_GEOTIFF_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
 if(WIN32)
diff --git a/SuperBuild/CMake/External_glew.cmake b/SuperBuild/CMake/External_glew.cmake
index 769ba0b808c3b8e83539e3dce0c3bb90501aad56..3f370e28e0642d584cfbdecfb881fa28d71a07e4 100644
--- a/SuperBuild/CMake/External_glew.cmake
+++ b/SuperBuild/CMake/External_glew.cmake
@@ -24,13 +24,17 @@ SETUP_SUPERBUILD(GLEW)
 
 ExternalProject_Add(GLEW
   PREFIX GLEW
-  URL "https://sourceforge.net/projects/glew/files/glew/1.13.0/glew-1.13.0.tgz/download"
+  URL "https://downloads.sourceforge.net/project/glew/glew/1.13.0/glew-1.13.0.tgz"
   URL_MD5 7cbada3166d2aadfc4169c4283701066
   SOURCE_DIR ${GLEW_SB_SRC}
   BINARY_DIR ${GLEW_SB_BUILD_DIR}
   DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
   CONFIGURE_COMMAND ${SB_CMAKE_COMMAND} ${SB_CMAKE_CACHE_ARGS} -DBUILD_UTILS:BOOL=OFF ${GLEW_SB_SRC}/build/cmake/
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 SUPERBUILD_PATCH_SOURCE(GLEW)
diff --git a/SuperBuild/CMake/External_glfw.cmake b/SuperBuild/CMake/External_glfw.cmake
index ed7285bd7cfff094d8754c1feb65e8bf09e0b29b..62e2ee046d0dbd1f1b83c6adb2ef13a834d4a9e0 100644
--- a/SuperBuild/CMake/External_glfw.cmake
+++ b/SuperBuild/CMake/External_glfw.cmake
@@ -35,4 +35,10 @@ ExternalProject_Add(GLFW
   -DGLFW_BUILD_DOCS:BOOL=OFF
   -DGLFW_BUILD_TESTS:BOOL=OFF
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
+
+SUPERBUILD_PATCH_SOURCE(GLFW)
diff --git a/SuperBuild/CMake/External_glut.cmake b/SuperBuild/CMake/External_glut.cmake
index 3299afd9b35d353890c6775ffffe88ccf198757a..8894a4931c3619b58bb01125b85494ecf2fbb37c 100644
--- a/SuperBuild/CMake/External_glut.cmake
+++ b/SuperBuild/CMake/External_glut.cmake
@@ -53,6 +53,10 @@ ExternalProject_Add(GLUT
   DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
   PATCH_COMMAND ${GLUT_PATCH_COMMAND}
   CONFIGURE_COMMAND ${GLUT_CONFIGURE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 set(_SB_GLUT_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
diff --git a/SuperBuild/CMake/External_itk.cmake b/SuperBuild/CMake/External_itk.cmake
index d46abbc7f9e55233b27047cca25a64244af3daa5..a96dc75196ce61766cb5e8ad9f491e83a163cb63 100644
--- a/SuperBuild/CMake/External_itk.cmake
+++ b/SuperBuild/CMake/External_itk.cmake
@@ -152,14 +152,14 @@ set(ITK_SB_COMPILATION_FLAGS
 
 #variables are later used in packaging
 set(SB_ITK_VERSION_MAJOR "4")
-set(SB_ITK_VERSION_MINOR "10")
+set(SB_ITK_VERSION_MINOR "12")
 
 set(_SB_ITK_DIR ${SB_INSTALL_PREFIX}/lib/cmake/ITK-${SB_ITK_VERSION_MAJOR}.${SB_ITK_VERSION_MINOR})
 
 ExternalProject_Add(ITK
   PREFIX ITK
-  URL "http://downloads.sourceforge.net/project/itk/itk/4.10/InsightToolkit-4.10.0.tar.gz"
-  URL_MD5 8c67ba296da3835fb67bb29d98dcff3e
+  URL "https://sourceforge.net/projects/itk/files/itk/4.12/InsightToolkit-4.12.0.tar.gz"
+  URL_MD5 561a403f93c88c64085b5623e8e61f79
   SOURCE_DIR ${ITK_SB_SRC}
   BINARY_DIR ${ITK_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -180,6 +180,10 @@ ExternalProject_Add(ITK
   ${ITK_SB_CONFIG}
   DEPENDS ${ITK_DEPENDENCIES}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 SUPERBUILD_PATCH_SOURCE(ITK)
diff --git a/SuperBuild/CMake/External_jpeg.cmake b/SuperBuild/CMake/External_jpeg.cmake
index 0a4fca1b69d3debed537887ce4d71ecf7da60679..38e1460e508505e880d72656f47142ce118d3ee2 100644
--- a/SuperBuild/CMake/External_jpeg.cmake
+++ b/SuperBuild/CMake/External_jpeg.cmake
@@ -45,13 +45,17 @@ endif()
 
 ExternalProject_Add(JPEG
   PREFIX JPEG
-  URL "http://sourceforge.net/projects/libjpeg-turbo/files/1.4.1/libjpeg-turbo-1.4.1.tar.gz"
+  URL "http://downloads.sourceforge.net/project/libjpeg-turbo/1.4.1/libjpeg-turbo-1.4.1.tar.gz"
   URL_MD5 b1f6b84859a16b8ebdcda951fa07c3f2
   SOURCE_DIR ${JPEG_SB_SRC}
   BINARY_DIR ${JPEG_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
   DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
   CONFIGURE_COMMAND ${JPEG_CONFIGURE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 SUPERBUILD_PATCH_SOURCE(JPEG)
diff --git a/SuperBuild/CMake/External_libkml.cmake b/SuperBuild/CMake/External_libkml.cmake
index 4d412687de14f6a74ef470cc02d0431713f6773b..e330ab05f7f5809a07ebf78dd7f0a980dde81522 100644
--- a/SuperBuild/CMake/External_libkml.cmake
+++ b/SuperBuild/CMake/External_libkml.cmake
@@ -44,7 +44,10 @@ ExternalProject_Add(LIBKML
   CMAKE_CACHE_ARGS ${SB_CMAKE_CACHE_ARGS}
   ${LIBKML_SB_CONFIG}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
-  LOG_BUILD 1  
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 set(_SB_LIBKML_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
diff --git a/SuperBuild/CMake/External_libsvm.cmake b/SuperBuild/CMake/External_libsvm.cmake
index 4a903c3e59c2d3bfe2ef7adc802051f34d19f33e..435c6d280c5faeb2bf5d2152cc3381c16a9f783b 100644
--- a/SuperBuild/CMake/External_libsvm.cmake
+++ b/SuperBuild/CMake/External_libsvm.cmake
@@ -35,6 +35,10 @@ ExternalProject_Add(LIBSVM
   PATCH_COMMAND ${CMAKE_COMMAND} -E copy
   ${CMAKE_SOURCE_DIR}/patches/LIBSVM/CMakeLists.txt
   ${LIBSVM_SB_SRC}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 set(_SB_LIBSVM_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
diff --git a/SuperBuild/CMake/External_muparser.cmake b/SuperBuild/CMake/External_muparser.cmake
index 20bb3ca23b068de7b6fb6ca0af2b4f991a9ac19f..669cd29da28b2979529ca4b5da69608c66ac2aae 100644
--- a/SuperBuild/CMake/External_muparser.cmake
+++ b/SuperBuild/CMake/External_muparser.cmake
@@ -35,6 +35,10 @@ ExternalProject_Add(MUPARSER
   PATCH_COMMAND ${CMAKE_COMMAND} -E copy
   ${CMAKE_SOURCE_DIR}/patches/MUPARSER/CMakeLists.txt
   ${MUPARSER_SB_SRC}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
-SUPERBUILD_UPDATE_CMAKE_VARIABLES(MUPARSER FALSE)
\ No newline at end of file
+SUPERBUILD_UPDATE_CMAKE_VARIABLES(MUPARSER FALSE)
diff --git a/SuperBuild/CMake/External_muparserx.cmake b/SuperBuild/CMake/External_muparserx.cmake
index a946a0da64a7e44fcc6f45e329015fa9272bf91d..e67b3974ad51cb504eb75cd31aa8f64153acde72 100644
--- a/SuperBuild/CMake/External_muparserx.cmake
+++ b/SuperBuild/CMake/External_muparserx.cmake
@@ -42,6 +42,10 @@ ExternalProject_Add(MUPARSERX
   ${MUPARSERX_FLAGS}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
   DEPENDS ${MUPARSERX_DEPENDENCIES}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 #Patch mpParserMessageProvider.cpp. This patch is integrated upstream but not yet released (last release is 4.0.7)
diff --git a/SuperBuild/CMake/External_mvd.cmake b/SuperBuild/CMake/External_mvd.cmake
deleted file mode 100644
index b3bf91b18f2b96a49e94fc8d1186f6fe75ab3abe..0000000000000000000000000000000000000000
--- a/SuperBuild/CMake/External_mvd.cmake
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright (C) 2005-2017 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.
-#
-
-if( __EXTERNAL_MVD__)
-  return()
-else()
-  set(__EXTERNAL_MVD__ 1)
-endif()
-
-SETUP_SUPERBUILD(MVD)
-
-set(MONTEVERDI_GIT_TAG "develop" CACHE STRING "branch name of monteverdi to build. Default is 'develop'")
-
-# declare dependencies
-ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(MVD OTB QWT QT4)
-
-set(MVD_SB_CONFIG)
-ADD_SUPERBUILD_CMAKE_VAR(MVD OTB_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(MVD QWT_INCLUDE_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(MVD QWT_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(MVD QT_QMAKE_EXECUTABLE)
-
-#TODO: control build testing via cmake variable properly
-
-ExternalProject_Add(MVD
-  PREFIX MVD
-  GIT_REPOSITORY "https://git@git.orfeo-toolbox.org/git/monteverdi2.git"
-  GIT_TAG "${MONTEVERDI_GIT_TAG}"
-  SOURCE_DIR ${MVD_SB_SRC}
-  BINARY_DIR ${MVD_SB_BUILD_DIR}
-  INSTALL_DIR ${CMAKE_INSTALL_PREFIX}
-  DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-  DEPENDS ${MVD_DEPENDENCIES}
-  CMAKE_CACHE_ARGS ${SB_CMAKE_CACHE_ARGS}
-  -DMonteverdi_INSTALL_LIB_DIR:STRING=lib
-  -DOTB_DATA_ROOT:STRING=${OTB_DATA_ROOT}
-  ${MVD_SB_CONFIG}
-  CMAKE_COMMAND ${SB_CMAKE_COMMAND}
-)
diff --git a/SuperBuild/CMake/External_opencv.cmake b/SuperBuild/CMake/External_opencv.cmake
index 854d09de427b0a9c86456694c46f98b3ca55e8f4..675777f3e8ef080192d0bfdd6741b40ed8332237 100644
--- a/SuperBuild/CMake/External_opencv.cmake
+++ b/SuperBuild/CMake/External_opencv.cmake
@@ -100,6 +100,10 @@ ExternalProject_Add(OPENCV
   ${OPENCV_SB_CONFIG}
   DEPENDS ${OPENCV_DEPENDENCIES}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 
diff --git a/SuperBuild/CMake/External_openjpeg.cmake b/SuperBuild/CMake/External_openjpeg.cmake
index cabb84509f4821470b7c09da4b8ce7cd52057ca4..09de9cb472905cfb0473061051b6447d217ec556 100644
--- a/SuperBuild/CMake/External_openjpeg.cmake
+++ b/SuperBuild/CMake/External_openjpeg.cmake
@@ -56,9 +56,13 @@ ExternalProject_Add(OPENJPEG
   ${OPENJPEG_SB_CONFIG}
   DEPENDS ${OPENJPEG_DEPENDENCIES}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 SUPERBUILD_UPDATE_CMAKE_VARIABLES(OPENJPEG FALSE)
 
-#Apply patches to openjpeg (for now Even Roualt optim)
+#Apply patches to openjpeg (for now Even Rouault optimizations)
 SUPERBUILD_PATCH_SOURCE(OPENJPEG "-ut")
diff --git a/SuperBuild/CMake/External_openssl.cmake b/SuperBuild/CMake/External_openssl.cmake
index e398c44a89274d9ba61ea0adcdb424608f0d1cd3..7e20c05fb4fd4698ca683c638914d840de68ff64 100644
--- a/SuperBuild/CMake/External_openssl.cmake
+++ b/SuperBuild/CMake/External_openssl.cmake
@@ -25,32 +25,47 @@ SETUP_SUPERBUILD(OPENSSL)
 ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(OPENSSL ZLIB)
 
 if(WIN32)
+  find_program(PERL_COMMAND NAMES perl perl.exe)
+  if(NOT PERL_COMMAND)
+    message(FATAL_ERROR "PERL_COMMAND not set. it is needed to configure openssl!")
+    return()
+  endif()
+
   set(OPENSSL_BUILD_ARCH "linux-x32")
   set(OPENSSL_BUILD_ARCH "VC-WIN32")
+  set(OPENSSL_CONFIGURE_CMD "${OPENSSL_SB_SRC}/ms/do_ms.bat")
   if(CMAKE_SIZEOF_VOID_P EQUAL 8)
     set(OPENSSL_BUILD_ARCH "linux-x86_64")
     set(OPENSSL_BUILD_ARCH "VC-WIN64A")
+    set(OPENSSL_CONFIGURE_CMD "${OPENSSL_SB_SRC}/ms/do_win64a.bat")
   endif()
 endif()
 
 if(MSVC)
-  STRING(REGEX REPLACE "/$" "" CMAKE_WIN_INSTALL_PREFIX ${SB_INSTALL_PREFIX})
-  STRING(REGEX REPLACE "/" "\\\\" CMAKE_WIN_INSTALL_PREFIX ${CMAKE_WIN_INSTALL_PREFIX})
   ExternalProject_Add(OPENSSL
     PREFIX OPENSSL
     URL "https://github.com/openssl/openssl/archive/OpenSSL_1_0_1p.tar.gz"
     URL_MD5 6bc1f9a9d9d474aceceb377e758e48ec
     DEPENDS ${OPENSSL_DEPENDENCIES}
-    BINARY_DIR ${OPENSSL_SB_BUILD_DIR}
+    BINARY_DIR ${OPENSSL_SB_SRC}
     INSTALL_DIR ${SB_INSTALL_PREFIX}
     DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    PATCH_COMMAND  ${CMAKE_COMMAND} -E copy_directory ${OPENSSL_SB_SRC} ${OPENSSL_SB_BUILD_DIR}
-    CONFIGURE_COMMAND
+    PATCH_COMMAND
     ${SB_ENV_CONFIGURE_CMD}
-    ${CMAKE_COMMAND} -E chdir ${OPENSSL_SB_BUILD_DIR}
-    perl Configure ${OPENSSL_BUILD_ARCH} no-asm  --prefix=${CMAKE_WIN_INSTALL_PREFIX} --openssldir=${CMAKE_WIN_INSTALL_PREFIX}
-    BUILD_COMMAND ms/do_ms.bat
-    INSTALL_COMMAND nmake -f ms/ntdll.mak install
+    ${PERL_COMMAND} ${OPENSSL_SB_SRC}/Configure
+    ${OPENSSL_BUILD_ARCH}
+    no-asm
+    "--prefix=${SB_INSTALL_PREFIX_NATIVE}"
+    "--openssldir=${SB_INSTALL_PREFIX_NATIVE}"
+    CONFIGURE_COMMAND
+      ${SB_ENV_CONFIGURE_CMD}
+      ${OPENSSL_CONFIGURE_CMD}
+    BUILD_COMMAND nmake -f "${OPENSSL_SB_SRC}/ms/ntdll.mak"
+    INSTALL_COMMAND nmake -f "${OPENSSL_SB_SRC}/ms/ntdll.mak" install
+    LOG_DOWNLOAD 1
+    LOG_CONFIGURE 1
+    LOG_BUILD 1
+    LOG_INSTALL 1
     )
 
 else(UNIX)
@@ -59,16 +74,25 @@ else(UNIX)
     DEPENDS ${OPENSSL_DEPENDENCIES}
     URL "https://github.com/openssl/openssl/archive/OpenSSL_1_0_1p.tar.gz"
     URL_MD5 6bc1f9a9d9d474aceceb377e758e48ec
-    BINARY_DIR ${OPENSSL_SB_BUILD_DIR}
+    BINARY_DIR ${OPENSSL_SB_SRC}
     INSTALL_DIR ${SB_INSTALL_PREFIX}
     DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    PATCH_COMMAND  ${CMAKE_COMMAND} -E copy_directory ${OPENSSL_SB_SRC} ${OPENSSL_SB_BUILD_DIR}
     CONFIGURE_COMMAND
     ${SB_ENV_CONFIGURE_CMD}
-    ${CMAKE_COMMAND} -E chdir ${OPENSSL_SB_BUILD_DIR} ./config ${OPENSSL_BUILD_ARCH}
-    --prefix=${SB_INSTALL_PREFIX} shared zlib zlib-dynamic -I${SB_INSTALL_PREFIX}/include -L${SB_INSTALL_PREFIX}/lib
+    ${OPENSSL_SB_SRC}/config ${OPENSSL_BUILD_ARCH}
+    "--prefix=${SB_INSTALL_PREFIX}"
+    shared
+    zlib
+    zlib-dynamic
+    "-I${SB_INSTALL_PREFIX}/include"
+    "-L${SB_INSTALL_PREFIX}/lib"
     BUILD_COMMAND $(MAKE)
-    INSTALL_COMMAND $(MAKE) install)
+    INSTALL_COMMAND $(MAKE) install
+    LOG_DOWNLOAD 1
+    LOG_CONFIGURE 1
+    LOG_BUILD 1
+    LOG_INSTALL 1
+    )
 
   ExternalProject_Add_Step(OPENSSL remove_static
     COMMAND ${CMAKE_COMMAND} -E remove
@@ -82,7 +106,7 @@ endif()
 
 set(_SB_OPENSSL_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
 if(WIN32)
-  set(_SB_OPENSSL_LIBRARY ${SB_INSTALL_PREFIX}/lib/libcurl.lib)
+  set(_SB_OPENSSL_LIBRARY "${SB_INSTALL_PREFIX}/lib/ssleay32.lib;${SB_INSTALL_PREFIX}/lib/libeay32.lib")
 elseif(UNIX)
   set(_SB_OPENSSL_LIBRARY ${SB_INSTALL_PREFIX}/lib/libssl${CMAKE_SHARED_LIBRARY_SUFFIX})
 endif()
diff --git a/SuperBuild/CMake/External_openthreads.cmake b/SuperBuild/CMake/External_openthreads.cmake
index bf783fd625a753991e6311078a2c392ad5328ff4..43661aa81cbdc81d382f5cec078dca61c860f691 100644
--- a/SuperBuild/CMake/External_openthreads.cmake
+++ b/SuperBuild/CMake/External_openthreads.cmake
@@ -37,6 +37,10 @@ ExternalProject_Add(OPENTHREADS
   PATCH_COMMAND ${CMAKE_COMMAND} -E copy
   ${CMAKE_SOURCE_DIR}/patches/OPENTHREADS/CMakeLists.txt
   ${OPENTHREADS_SB_SRC}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 set(_SB_OPENTHREADS_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
diff --git a/SuperBuild/CMake/External_ossim.cmake b/SuperBuild/CMake/External_ossim.cmake
index 8347a3cb854486d43b833a8105138e557f2c360d..04d89d5f3ba6c207b726d4c9cfc4351d06b275b3 100644
--- a/SuperBuild/CMake/External_ossim.cmake
+++ b/SuperBuild/CMake/External_ossim.cmake
@@ -67,6 +67,10 @@ ExternalProject_Add(OSSIM
   ${OSSIM_SB_CONFIG}
   DEPENDS ${OSSIM_DEPENDENCIES}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 ExternalProject_Add_Step(OSSIM patch_no_cmakelists
diff --git a/SuperBuild/CMake/External_otb.cmake b/SuperBuild/CMake/External_otb.cmake
index b4a7107a176fd1222f949d61632e5a1d38aab8a7..7960b53e44e89d7537ec3ee2e7991f7202e6e356 100644
--- a/SuperBuild/CMake/External_otb.cmake
+++ b/SuperBuild/CMake/External_otb.cmake
@@ -35,15 +35,15 @@ if(OTB_USE_CURL)
 endif()
 
 if(OTB_USE_LIBKML)
-    ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(OTB LIBKML)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_INCLUDE_DIR)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_BASE_LIBRARY)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_CONVENIENCE_LIBRARY)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_DOM_LIBRARY)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_ENGINE_LIBRARY)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_REGIONATOR_LIBRARY)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_XSD_LIBRARY)
-    ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_MINIZIP_LIBRARY)
+  ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(OTB LIBKML)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_INCLUDE_DIR)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_BASE_LIBRARY)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_CONVENIENCE_LIBRARY)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_DOM_LIBRARY)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_ENGINE_LIBRARY)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_REGIONATOR_LIBRARY)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_XSD_LIBRARY)
+  ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_MINIZIP_LIBRARY)
 endif()
 
 if(OTB_USE_OPENCV)
@@ -128,30 +128,7 @@ ADD_SUPERBUILD_CMAKE_VAR(OTB TINYXML_LIBRARY)
 ADD_SUPERBUILD_CMAKE_VAR(OTB Boost_INCLUDE_DIR)
 ADD_SUPERBUILD_CMAKE_VAR(OTB Boost_LIBRARY_DIR)
 
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_INCLUDE_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_BASE_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_CONVENIENCE_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_DOM_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_ENGINE_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_REGIONATOR_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_XSD_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBKML_MINIZIP_LIBRARY)
-
-ADD_SUPERBUILD_CMAKE_VAR(OTB OpenCV_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(OTB Shark_DIR)
-
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBSVM_INCLUDE_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(OTB LIBSVM_LIBRARY)
-
-if(OTB_USE_CURL)
-ADD_SUPERBUILD_CMAKE_VAR(OTB CURL_INCLUDE_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(OTB CURL_LIBRARY)
-endif()
-
-if(MSVC)
-  ADD_SUPERBUILD_CMAKE_VAR(OTB JPEG_LIBRARY)
-endif()
-  
+ 
 # forward compilation flags
 set(OTB_SB_C_FLAGS "${SB_PRIOR_INCLUDE_FLAGS} ${CMAKE_C_FLAGS} ")
 set(OTB_SB_CXX_FLAGS "${SB_PRIOR_INCLUDE_FLAGS} ${CMAKE_CXX_FLAGS}")
diff --git a/SuperBuild/CMake/External_pcre.cmake b/SuperBuild/CMake/External_pcre.cmake
index 717f09f576d2fe2f638a154c33019bc8c300fdd8..aefa89e5b535315fef74cee9bff3ed2d0bbb18ba 100644
--- a/SuperBuild/CMake/External_pcre.cmake
+++ b/SuperBuild/CMake/External_pcre.cmake
@@ -25,7 +25,7 @@ if(MSVC)
 else()
   ExternalProject_Add(PCRE
     PREFIX PCRE
-    URL "http://sourceforge.net/projects/pcre/files/pcre/8.36/pcre-8.36.tar.gz/download"
+    URL "http://downloads.sourceforge.net/project/pcre/pcre/8.36/pcre-8.36.tar.gz"
     URL_MD5 ff7b4bb14e355f04885cf18ff4125c98
     BINARY_DIR ${PCRE_SB_BUILD_DIR}
     INSTALL_DIR ${SB_INSTALL_PREFIX}
diff --git a/SuperBuild/CMake/External_png.cmake b/SuperBuild/CMake/External_png.cmake
index 1d2d16148dddfef8363f12a002785ca364d96b57..cd149a67b88e1741c912623d7f8f28957a228850 100644
--- a/SuperBuild/CMake/External_png.cmake
+++ b/SuperBuild/CMake/External_png.cmake
@@ -30,7 +30,7 @@ ADD_SUPERBUILD_CMAKE_VAR(PNG ZLIB_LIBRARY)
 
 ExternalProject_Add(PNG
   PREFIX PNG
-  URL "http://sourceforge.net/projects/libpng/files/libpng16/older-releases/1.6.16/lpng1616.zip/download"
+  URL "http://downloads.sourceforge.net/project/libpng/libpng16/older-releases/1.6.16/lpng1616.zip"
   URL_MD5 c90c9587c9a5c735327fb3f6900f6b03
   BINARY_DIR ${PNG_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -48,6 +48,10 @@ ExternalProject_Add(PNG
   -DSKIP_INSTALL_EXECUTABLES:BOOL=OFF
   ${PNG_SB_CONFIG}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 set(_SB_PNG_PNG_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
 
diff --git a/SuperBuild/CMake/External_proj.cmake b/SuperBuild/CMake/External_proj.cmake
index 2949915c9fc42904d863752944473f78c3393494..a4fc838c7e44757776948edbda6dbeb2358fe40a 100644
--- a/SuperBuild/CMake/External_proj.cmake
+++ b/SuperBuild/CMake/External_proj.cmake
@@ -22,51 +22,32 @@ INCLUDE_ONCE_MACRO(PROJ)
 
 SETUP_SUPERBUILD(PROJ)
 
-if(MSVC)
-  ExternalProject_Add(PROJ
-    PREFIX PROJ
-    URL "http://download.osgeo.org/proj/proj-4.8.0.tar.gz"
-    URL_MD5 d815838c92a29179298c126effbb1537
-    SOURCE_DIR ${PROJ_SB_SRC}
-    BINARY_DIR ${PROJ_SB_SRC}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    CONFIGURE_COMMAND ""
-    BUILD_COMMAND nmake /f ${PROJ_SB_SRC}/makefile.vc
-    INSTALL_COMMAND nmake /f ${PROJ_SB_SRC}/makefile.vc install-all INSTDIR=${SB_INSTALL_PREFIX_NATIVE}
-    )
-
-else()
-
-  if(APPLE)
-    set(PROJ_SB_ENV_CONFIGURE_CMD ${SB_ENV_CONFIGURE_CMD} LDFLAGS=-headerpad_max_install_names)
-  else()
-    set(PROJ_SB_ENV_CONFIGURE_CMD ${SB_ENV_CONFIGURE_CMD})
-  endif()
-
-  ExternalProject_Add(PROJ
-    PREFIX PROJ
-    URL "http://download.osgeo.org/proj/proj-4.8.0.tar.gz"
-    URL_MD5 d815838c92a29179298c126effbb1537
-    BINARY_DIR ${PROJ_SB_SRC}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    CONFIGURE_COMMAND
-    ${SB_ENV_CONFIGURE_CMD}
-    ${PROJ_SB_SRC}/configure
-    --prefix=${SB_INSTALL_PREFIX}
-    --enable-static=no
-    BUILD_COMMAND $(MAKE)
-    INSTALL_COMMAND $(MAKE) install
-    )
-
-endif()
+ExternalProject_Add(PROJ
+  PREFIX PROJ
+  URL "http://download.osgeo.org/proj/proj-4.9.3.tar.gz"
+  URL_MD5 d598336ca834742735137c5674b214a1
+  BINARY_DIR ${PROJ_SB_SRC}
+  INSTALL_DIR ${SB_INSTALL_PREFIX}
+  DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
+  CMAKE_CACHE_ARGS
+  ${SB_CMAKE_CACHE_ARGS}
+  -DBUILD_LIBPROJ_SHARED:BOOL=TRUE
+  -DVERSIONED_OUTPUT:BOOL=FALSE
+  -DBUILD_FRAMEWORKS_AND_BUNDLE:BOOL=FALSE
+  -DPROJ_LIB_SUBDIR:STRING=lib
+  -DPROJ_INCLUDE_SUBDIR:STRING=include
+  CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
+  )
 
 SUPERBUILD_PATCH_SOURCE(PROJ)
 
 set(_SB_PROJ_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
 if(WIN32)
-  set(_SB_PROJ_LIBRARY ${SB_INSTALL_PREFIX}/lib/proj_i.lib)
+  set(_SB_PROJ_LIBRARY ${SB_INSTALL_PREFIX}/lib/proj.lib)
 elseif(UNIX)
   set(_SB_PROJ_LIBRARY ${SB_INSTALL_PREFIX}/lib/libproj${CMAKE_SHARED_LIBRARY_SUFFIX})
 endif()
diff --git a/SuperBuild/CMake/External_qt4.cmake b/SuperBuild/CMake/External_qt4.cmake
index 8866464eba0bcdb6de152c762c2ae2a327cd247e..6d7c12cd52c00e83b0117ef97fd9814c7d20e193 100644
--- a/SuperBuild/CMake/External_qt4.cmake
+++ b/SuperBuild/CMake/External_qt4.cmake
@@ -40,7 +40,7 @@ endif()
 #NOTE: make sure your superbuild install directory does not contain any
 #Qt files from previous install of superbuild QT.
 # declare dependencies
-ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(QT4 ZLIB PNG JPEG SQLITE FREETYPE)
+ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(QT4 ZLIB PNG JPEG FREETYPE)
 
 #use system libs always for Qt4 as we build them from source or have already in system
 set(QT4_SB_CONFIG)
@@ -55,10 +55,9 @@ if(UNIX)
   else() #Linux
     if(QT4_SB_ENABLE_GTK)
       message(WARNING "QT4_SB_ENABLE_GTK support is experimental")
-
       set(QT4_SB_CONFIG "${QT4_SB_CONFIG} -sm -xrender -xrandr -gtkstyle")
     else()
-      set(QT4_SB_CONFIG "${QT4_SB_CONFIG} -no-gtkstyle")
+      set(QT4_SB_CONFIG "${QT4_SB_CONFIG} -no-gtkstyle -no-glib -no-fontconfig")
     endif()
   endif()
   #common for all unix
@@ -105,10 +104,12 @@ add_custom_target(QT4-uninstall
   COMMAND ${CMAKE_COMMAND} -E remove_directory "${SB_INSTALL_PREFIX}/include/QtSvg"
   COMMAND ${CMAKE_COMMAND} -E remove_directory "${SB_INSTALL_PREFIX}/include/QtTest"
   COMMAND ${CMAKE_COMMAND} -E remove_directory "${SB_INSTALL_PREFIX}/include/QtXml"
+  COMMAND ${CMAKE_COMMAND} -E remove_directory "${SB_INSTALL_PREFIX}/include/Qt"
   COMMAND ${CMAKE_COMMAND} -E remove_directory "${SB_INSTALL_PREFIX}/mkspecs"
   COMMAND ${CMAKE_COMMAND} -E remove_directory "${SB_INSTALL_PREFIX}/plugins"
   COMMAND ${CMAKE_COMMAND} -E remove_directory "${SB_INSTALL_PREFIX}/translations"
   COMMAND ${CMAKE_COMMAND} -E remove -f "${SB_INSTALL_PREFIX}/lib/libQt*"
+  COMMAND ${CMAKE_COMMAND} -E remove -f "${SB_INSTALL_PREFIX}/lib/pkgconfig/Qt*"
   COMMAND ${CMAKE_COMMAND} -E remove -f "${SB_INSTALL_PREFIX}/bin/qmake${QT4_BIN_EXT}"
   COMMAND ${CMAKE_COMMAND} -E remove -f "${SB_INSTALL_PREFIX}/bin/lrelease${QT4_BIN_EXT}"
   COMMAND ${CMAKE_COMMAND} -E remove -f "${SB_INSTALL_PREFIX}/bin/moc${QT4_BIN_EXT}"
@@ -130,6 +131,7 @@ add_custom_target(QT4-uninstall
     DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
     CONFIGURE_COMMAND ${QT4_CONFIGURE_COMMAND}
     DEPENDS ${QT4_DEPENDENCIES}
+    LOG_DOWNLOAD 1
     LOG_CONFIGURE 1    
     LOG_BUILD 1
     LOG_INSTALL 1    
diff --git a/SuperBuild/CMake/External_qwt.cmake b/SuperBuild/CMake/External_qwt.cmake
index b7c49bb46e25518ae261a006da3905c9a8746368..847d001b80bdc98c5a842e72acdaa0d7742c727f 100644
--- a/SuperBuild/CMake/External_qwt.cmake
+++ b/SuperBuild/CMake/External_qwt.cmake
@@ -45,7 +45,7 @@ endif()
 
 ExternalProject_Add(QWT
   PREFIX QWT
-  URL "http://sourceforge.net/projects/qwt/files/qwt/5.2.3/qwt-5.2.3.zip/download"
+  URL "http://downloads.sourceforge.net/project/qwt/qwt/5.2.3/qwt-5.2.3.zip"
   URL_MD5 310a1c8ab831f4b2219505dcb7691cf1
   SOURCE_DIR ${QWT_SB_SRC}
   BINARY_DIR ${QWT_SB_BUILD_DIR}
@@ -67,4 +67,4 @@ if(WIN32)
   set(_SB_QWT_LIBRARY ${SB_INSTALL_PREFIX}/lib/qwt5.lib)
 elseif(UNIX)
   set(_SB_QWT_LIBRARY ${SB_INSTALL_PREFIX}/lib/libqwt${CMAKE_SHARED_LIBRARY_SUFFIX})
-endif()
\ No newline at end of file
+endif()
diff --git a/SuperBuild/CMake/External_shark.cmake b/SuperBuild/CMake/External_shark.cmake
index f6a41acb569536fff64b9a3cedd68b18e37979dc..4fa164d29259d33037ad8c85ee6327ba6e8a0f85 100644
--- a/SuperBuild/CMake/External_shark.cmake
+++ b/SuperBuild/CMake/External_shark.cmake
@@ -46,6 +46,12 @@ ExternalProject_Add(SHARK
   -DENABLE_CBLAS:BOOL=OFF
   ${SHARK_SB_CONFIG}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
+SUPERBUILD_PATCH_SOURCE(SHARK)
+
 set(_SB_Shark_DIR ${SB_INSTALL_PREFIX}/lib/cmake/Shark)
diff --git a/SuperBuild/CMake/External_sqlite.cmake b/SuperBuild/CMake/External_sqlite.cmake
index 8a87e03d0e28bc4e89af98a3d21d9a50ce7bb80b..32d845fc3d434ae9b90b459500e55d854333a1d3 100644
--- a/SuperBuild/CMake/External_sqlite.cmake
+++ b/SuperBuild/CMake/External_sqlite.cmake
@@ -33,6 +33,10 @@ ExternalProject_Add(SQLITE
   PATCH_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/patches/SQLITE ${SQLITE_SB_SRC}
   CMAKE_CACHE_ARGS ${SB_CMAKE_CACHE_ARGS}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 set(_SB_SQLITE_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
diff --git a/SuperBuild/CMake/External_swig.cmake b/SuperBuild/CMake/External_swig.cmake
index 84c28823c7a64cc2ef82d2618ddfc5a153fe76d4..a21bac8410d123d711560da0ebffc5f0f50a58f8 100644
--- a/SuperBuild/CMake/External_swig.cmake
+++ b/SuperBuild/CMake/External_swig.cmake
@@ -43,7 +43,7 @@ if(MSVC)
   # Use pre-built swig executable (no linking is required, no install done)
   ExternalProject_Add(SWIG
     PREFIX SWIG
-    URL "http://sourceforge.net/projects/swig/files/swigwin/swigwin-3.0.7/swigwin-3.0.7.zip/download"
+    URL "http://downloads.sourceforge.net/project/swig/swigwin/swigwin-3.0.7/swigwin-3.0.7.zip"
     URL_MD5 d8b5a9ce49c819cc1bfc1e797b85ba7a
     INSTALL_DIR ${SB_INSTALL_PREFIX}
     DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
@@ -62,7 +62,7 @@ else()
 
   ExternalProject_Add(SWIG
     PREFIX SWIG
-    URL "http://sourceforge.net/projects/swig/files/swig/swig-3.0.7/swig-3.0.7.tar.gz/download"
+    URL "http://downloads.sourceforge.net/project/swig/swig/swig-3.0.7/swig-3.0.7.tar.gz"
     URL_MD5 7fff46c84b8c630ede5b0f0827e3d90a
     BINARY_DIR ${SWIG_SB_BUILD_DIR}
     INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -76,6 +76,10 @@ else()
     BUILD_COMMAND $(MAKE)
     INSTALL_COMMAND $(MAKE) install
     DEPENDS ${SWIG_DEPENDENCIES}
+    LOG_DOWNLOAD 1
+    LOG_CONFIGURE 1
+    LOG_BUILD 1
+    LOG_INSTALL 1
     )
 
   ExternalProject_Add_Step(SWIG copy_source
diff --git a/SuperBuild/CMake/External_tiff.cmake b/SuperBuild/CMake/External_tiff.cmake
index 296312b853baa1f2c8b98abff11e4a6e3c940d7f..d1d48880f29a7333d72e993f9abadf2c1e00d51c 100644
--- a/SuperBuild/CMake/External_tiff.cmake
+++ b/SuperBuild/CMake/External_tiff.cmake
@@ -25,77 +25,52 @@ SETUP_SUPERBUILD(TIFF)
 # declare dependencies
 ADDTO_DEPENDENCIES_IF_NOT_SYSTEM(TIFF ZLIB JPEG)
 
-ADD_SUPERBUILD_CMAKE_VAR(TIFF ZLIB_INCLUDE_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(TIFF ZLIB_LIBRARY)
-ADD_SUPERBUILD_CMAKE_VAR(TIFF JPEG_INCLUDE_DIR)
-ADD_SUPERBUILD_CMAKE_VAR(TIFF JPEG_LIBRARY)
-
 if(MSVC)
-  STRING(REGEX REPLACE "/$" "" CMAKE_WIN_INSTALL_PREFIX ${SB_INSTALL_PREFIX})
-  STRING(REGEX REPLACE "/" "\\\\" CMAKE_WIN_INSTALL_PREFIX ${CMAKE_WIN_INSTALL_PREFIX})
-  configure_file(${CMAKE_SOURCE_DIR}/patches/TIFF/nmake.opt ${CMAKE_BINARY_DIR}/nmake_libtiff_extra.opt)
-  ExternalProject_Add(TIFF_build
-    PREFIX TIFF
-    URL "http://download.osgeo.org/libtiff/tiff-4.0.6.tar.gz"
-    URL_MD5 d1d2e940dea0b5ad435f21f03d96dd72
-    SOURCE_DIR ${TIFF_SB_SRC}
-    BINARY_DIR ${TIFF_SB_SRC}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    DEPENDS ${TIFF_DEPENDENCIES}
-    PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/nmake_libtiff_extra.opt ${TIFF_SB_SRC}/nmake.opt
-    CONFIGURE_COMMAND ""
-    BUILD_COMMAND nmake /f ${TIFF_SB_SRC}/Makefile.vc
-    INSTALL_COMMAND ${CMAKE_COMMAND} -E copy  ${CMAKE_SOURCE_DIR}/patches/TIFF/CMakeLists.txt
-    ${CMAKE_BINARY_DIR}/TIFF/_install
-    )
-
-  ExternalProject_Add(TIFF
-    PREFIX TIFF/_install
-    DOWNLOAD_COMMAND ""
-    SOURCE_DIR TIFF/_install
-    BINARY_DIR ${TIFF_SB_BUILD_DIR}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    CMAKE_CACHE_ARGS
-    -DCMAKE_INSTALL_PREFIX:STRING=${SB_INSTALL_PREFIX}
-    -DCMAKE_BUILD_TYPE:STRING=Release
-    -DTIFF_BUILD_DIR:STRING=${TIFF_SB_SRC}/libtiff
-    DEPENDS TIFF_build
-    CMAKE_COMMAND
-    )
-
-else()
-  ExternalProject_Add(TIFF
-    PREFIX TIFF
-    URL "http://download.osgeo.org/libtiff/tiff-4.0.6.tar.gz"
-    URL_MD5 d1d2e940dea0b5ad435f21f03d96dd72
-    SOURCE_DIR ${TIFF_SB_SRC}
-    BINARY_DIR ${TIFF_SB_BUILD_DIR}
-    INSTALL_DIR ${SB_INSTALL_PREFIX}
-    DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
-    DEPENDS ${TIFF_DEPENDENCIES}
-    CMAKE_CACHE_ARGS
-    ${SB_CMAKE_CACHE_ARGS}
-    -DCMAKE_INSTALL_LIBDIR:PATH=lib
-    -DCMAKE_INSTALL_BINDIR:PATH=bin
-    -DBUILD_TESTING:BOOL=OFF
-    -Djpeg:BOOL=TRUE
-    -Dlzma:BOOL=FALSE
-    -Djbig:BOOL=FALSE
-    -Dzlib:BOOL=TRUE
-    -DWITH_OPENGL:BOOL=FALSE
-    -Dpixarlog:BOOL=TRUE
-    ${TIFF_SB_CONFIG}
-    CMAKE_COMMAND ${SB_CMAKE_COMMAND}
-    )
+  set(TIFF_C_FLAGS "/D_CRT_SECURE_NO_WARNINGS /DWIN32")
 endif()
 
+ExternalProject_Add(TIFF
+  PREFIX TIFF
+  URL "http://download.osgeo.org/libtiff/tiff-4.0.8.tar.gz"
+  URL_MD5 2a7d1c1318416ddf36d5f6fa4600069b
+  SOURCE_DIR ${TIFF_SB_SRC}
+  BINARY_DIR ${TIFF_SB_BUILD_DIR}
+  INSTALL_DIR ${SB_INSTALL_PREFIX}
+  DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
+  DEPENDS ${TIFF_DEPENDENCIES}
+  CMAKE_CACHE_ARGS
+  ${SB_CMAKE_CACHE_ARGS}
+  -DCMAKE_C_FLAGS:STRING=${TIFF_C_FLAGS}
+  -DCMAKE_INSTALL_LIBDIR:PATH=lib
+  -DCMAKE_INSTALL_BINDIR:PATH=bin
+  -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS:BOOL=TRUE
+  -DBUILD_TESTING:BOOL=FALSE
+  -Djpeg:BOOL=TRUE
+  -Dlzma:BOOL=FALSE
+  -Djbig:BOOL=FALSE
+  -Dzlib:BOOL=TRUE
+  -DWITH_OPENGL:BOOL=FALSE
+  -Dpixarlog:BOOL=TRUE
+  -Dcxx:BOOL=FALSE
+  -Dwith_opengl:BOOL=FALSE
+  -Dwith_tools:BOOL=FALSE
+  -Dwith_test:BOOL=FALSE
+  -Dwith_contrib:BOOL=FALSE
+  -Dwith_docs:BOOL=FALSE
+  ${TIFF_SB_CONFIG}
+  CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
+  )
+    
 SUPERBUILD_PATCH_SOURCE(TIFF)
 
+#do we really need these variables? 
 set(_SB_TIFF_INCLUDE_DIR ${SB_INSTALL_PREFIX}/include)
 if(WIN32)
-  set(_SB_TIFF_LIBRARY ${SB_INSTALL_PREFIX}/lib/libtiff_i.lib)
+  set(_SB_TIFF_LIBRARY ${SB_INSTALL_PREFIX}/lib/tiff.lib)
 elseif(UNIX)
   set(_SB_TIFF_LIBRARY ${SB_INSTALL_PREFIX}/lib/libtiff${CMAKE_SHARED_LIBRARY_SUFFIX})
 endif()
diff --git a/SuperBuild/CMake/External_tinyxml.cmake b/SuperBuild/CMake/External_tinyxml.cmake
index d79b14ea6646d7c178dbcb20bf21c34e22a79f96..8952e1ea83147829c4cd3a1a491111ff9ccb0941 100644
--- a/SuperBuild/CMake/External_tinyxml.cmake
+++ b/SuperBuild/CMake/External_tinyxml.cmake
@@ -24,7 +24,7 @@ SETUP_SUPERBUILD(TINYXML)
 
 ExternalProject_Add(TINYXML
   PREFIX TINYXML
-  URL "http://sourceforge.net/projects/tinyxml/files/tinyxml/2.6.2/tinyxml_2_6_2.tar.gz/download"
+  URL "http://downloads.sourceforge.net/project/tinyxml/tinyxml/2.6.2/tinyxml_2_6_2.tar.gz"
   URL_MD5 c1b864c96804a10526540c664ade67f0
   BINARY_DIR ${TINYXML_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
@@ -35,6 +35,10 @@ ExternalProject_Add(TINYXML
   ${TINYXML_SB_SRC}
   CMAKE_CACHE_ARGS ${SB_CMAKE_CACHE_ARGS}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
 SUPERBUILD_UPDATE_CMAKE_VARIABLES(TINYXML FALSE)
diff --git a/SuperBuild/CMake/External_zlib.cmake b/SuperBuild/CMake/External_zlib.cmake
index d19fe414172a5d15b5c9dcdacf12c7cfe708092c..6948e1f54244176e582864c1f958a139ea559402 100644
--- a/SuperBuild/CMake/External_zlib.cmake
+++ b/SuperBuild/CMake/External_zlib.cmake
@@ -26,21 +26,27 @@ SETUP_SUPERBUILD(ZLIB)
 # Try official release 1.2.8
 ExternalProject_Add(ZLIB
   PREFIX ZLIB
-  URL "http://sourceforge.net/projects/libpng/files/zlib/1.2.8/zlib-1.2.8.tar.gz/download"
+  URL "http://downloads.sourceforge.net/project/libpng/zlib/1.2.8/zlib-1.2.8.tar.gz"
   URL_MD5 44d667c142d7cda120332623eab69f40
   BINARY_DIR ${ZLIB_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
   DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
   CMAKE_CACHE_ARGS ${SB_CMAKE_CACHE_ARGS}
   CMAKE_COMMAND ${SB_CMAKE_COMMAND}
+  LOG_DOWNLOAD 1
+  LOG_CONFIGURE 1
+  LOG_BUILD 1
+  LOG_INSTALL 1
   )
 
+#patch zlib cmake to disable static build on request
 if(UNIX)
   ExternalProject_Add_Step(ZLIB remove_static
     COMMAND ${CMAKE_COMMAND} -E remove ${SB_INSTALL_PREFIX}/lib/libz.a
     DEPENDEES install)
 endif()
 
+#check who uses zdll.lib and remove this hack
 if(MSVC)
   ExternalProject_Add_Step(ZLIB msvc_copy_hell
     COMMAND ${CMAKE_COMMAND} -E copy ${ZLIB_SB_BUILD_DIR}/zlib.lib ${SB_INSTALL_PREFIX}/lib/zdll.lib
diff --git a/SuperBuild/CMake/patch.cmake b/SuperBuild/CMake/patch.cmake
index 651aec69583dd741b3130e5cfcae04df6bd5c1b4..db91ef224f2324afcde0c8f070644ae34ccd18f6 100644
--- a/SuperBuild/CMake/patch.cmake
+++ b/SuperBuild/CMake/patch.cmake
@@ -54,7 +54,8 @@ foreach(dot_diff_file ${DOT_DIFF_FILES})
   endif()
 
   if(PATCHING_FAILED)
-    message(FATAL_ERROR "${PATCH_PROGRAM} returned non-zero exit status \n ${patch_ov} \n")
+    message(FATAL_ERROR
+      "${PATCH_PROGRAM} ${PATCH_ARGS} -p1 -i ${dot_diff_file} failed\n error: ${patch_ov} \n")
   else()
     message("${patch_ov}")
   endif()
diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt
index 15024aae21f834f33b5954de928b496b7bde8aa9..6d47c1185ec61de953820d854367b956dfb3a960 100644
--- a/SuperBuild/CMakeLists.txt
+++ b/SuperBuild/CMakeLists.txt
@@ -18,7 +18,7 @@
 # limitations under the License.
 #
 
-cmake_minimum_required(VERSION 3.1.0)
+cmake_minimum_required(VERSION 3.3.0)
 
 project(OTB-SuperBuild)
 
@@ -42,6 +42,7 @@ include(ExternalProject)
 include(OTBCheckTargetSystemArch)
 
 option(BUILD_SHARED_LIBS "Build OTB with shared libraries." ON)
+option(BUILD_STATIC_LIBS "Build with static libraries." OFF)
 
 set(OTB_ADDITIONAL_CACHE "" CACHE STRING "Additional cmake option for OTB -DVAR:TYPE=VALUE ...")
 
@@ -73,11 +74,11 @@ option(BUILD_TESTING "Build the testing tree." OFF)
 include(CTest)
 include(SuperBuild_Macro)
 
-# Setup location where source tar-balls are downloaded
-#set (install_location "${CMAKE_CURRENT_BINARY_DIR}/install")
-set (DOWNLOAD_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/Downloads"
-     CACHE PATH "Location where source tar-balls are (to be) downloaded.")
-mark_as_advanced(DOWNLOAD_LOCATION)
+# Configure location where source tar-balls are downloaded
+find_path(DOWNLOAD_LOCATION
+  NAMES OTBSuperBuild.readme
+  HINTS $ENV{DOWNLOAD_LOCATION} "${CMAKE_CURRENT_BINARY_DIR}/Downloads"
+  )
 
 # General options
 option(OTB_DATA_USE_LARGEINPUT "Use Large inputs images test." OFF)
@@ -145,15 +146,6 @@ if(NOT CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE Release)
 endif()
 
-if(MSVC)
-  set(BUILD_SHARED_LIBS OFF)
-  if(CMAKE_MAJOR_VERSION GREATER 2 AND CMAKE_MINOR_VERSION GREATER 2)
-    set(BUILD_SHARED_LIBS ON)
-  else()
-    message(WARNING "BUILD_SHARED_LIBS is set to OFF with CMake < 3.3")
-  endif()
-endif()
-
 if(MSVC)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /Ox /FC /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE")
   if(MSVC_VERSION GREATER 1310)
@@ -249,6 +241,7 @@ option(USE_SYSTEM_GDAL "Use a system build of GDAL" OFF)
 option(USE_SYSTEM_FFTW "Use a system build of FFTW" OFF)
 option(USE_SYSTEM_ITK "Use a system build of ITK" OFF)
 option(USE_SYSTEM_OPENTHREADS  "Use a system build of OpenThreads" OFF)
+option(USE_SYSTEM_OSSIM  "Use a system build of OSSIM" OFF)
 option(USE_SYSTEM_MUPARSER  "Use a system build of muParser" OFF)
 option(USE_SYSTEM_MUPARSERX "Use a system build of  muParserX" OFF)
 option(USE_SYSTEM_TINYXML  "Use a system build of TinyXML" OFF)
@@ -281,18 +274,19 @@ option(OTB_USE_MUPARSERX "Enable module muparserX in OTB" ON)
 option(OTB_USE_OPENCV "Enable module OpenCV in OTB" ON)
 option(OTB_USE_QT4 "Enable module QT4 in OTB" ON)
 option(OTB_USE_SIFTFAST "Enable module Siftfast in OTB" ON)
-option(OTB_USE_OPENGL "Enable module OpenGL in OTB" OFF)
-option(OTB_USE_GLEW "Enable module GLEW in OTB" OFF)
-option(OTB_USE_GLFW "Enable module GLFW in OTB" OFF)
-option(OTB_USE_GLUT "Enable module GLUT in OTB" OFF)
-option(OTB_USE_SHARK "Enable module Shark in OTB" OFF)
-option(OTB_USE_QWT "Enable module QWT in OTB" OFF)
+option(OTB_USE_OPENGL "Enable module OpenGL in OTB" ON)
+option(OTB_USE_GLEW "Enable module GLEW in OTB" ON)
+option(OTB_USE_GLFW "Enable module GLFW in OTB" ON)
 
-#Problem: below cmake setting will fail!
-#-DOTB_USE_OPENGL=ON -DOTB_USE_GLEW=ON -DOTB_USE_QWT=ON
-#This is because ENABLE_MONTEVERDI is OFF by default
-# This brings a lot of twisted logic. so taking out this option
+#Cannot activate GLUT on OSX. See manits issue #1194")
+if(APPLE)
+  option(OTB_USE_GLUT "Enable module GLUT in OTB" OFF)
+else()
+  option(OTB_USE_GLUT "Enable module GLUT in OTB" ON)
+endif()
 
+option(OTB_USE_SHARK "Enable module Shark in OTB" ON)
+option(OTB_USE_QWT "Enable module QWT in OTB" ON)
 
 # set OTB_DATA_ROOT to run test
 find_path(OTB_DATA_ROOT README-OTB-Data PATHS $ENV{OTB_DATA_ROOT} ${OTB-SuperBuild_SOURCE_DIR}/../../OTB-Data)
@@ -352,6 +346,7 @@ endif()
 message(STATUS "OTB_TARGET_SYSTEM_ARCH=${OTB_TARGET_SYSTEM_ARCH}")
 message(STATUS "OTB_TARGET_SYSTEM_ARCH_IS_X64=${OTB_TARGET_SYSTEM_ARCH_IS_X64}")
 if(DOWNLOAD_LOCATION)
+  message(STATUS "DOWNLOAD_LOCATION=${DOWNLOAD_LOCATION}")
   message(STATUS "Source archives for dependencies will be taken from '${DOWNLOAD_LOCATION}'")
 else()
   message(STATUS "DOWNLOAD_LOCATION is not set. We will download all source archives during build!")
diff --git a/SuperBuild/Packaging/PackageGlobals.cmake b/SuperBuild/Packaging/PackageGlobals.cmake
index 9b94a74c1bade4cca2bbe6f69ea0e64a038e81dd..fdcfb3da3709c78e0b703ae99f296acced1aece7 100644
--- a/SuperBuild/Packaging/PackageGlobals.cmake
+++ b/SuperBuild/Packaging/PackageGlobals.cmake
@@ -91,6 +91,7 @@ set(LINUX_SYSTEM_DLLS
   libexpat.so.*
   libfontconfig.so*
   libfreetype.so*
+  libwebp.so*
   )
 
 # libgcc_s.*dylib and other *.framework are dragged by QT
diff --git a/SuperBuild/patches/CURL/curl-1-cmake-all.diff b/SuperBuild/patches/CURL/curl-1-cmake-all.diff
new file mode 100755
index 0000000000000000000000000000000000000000..e2e0807143542ebb4a73c4fa5d6821cedaa6a4df
--- /dev/null
+++ b/SuperBuild/patches/CURL/curl-1-cmake-all.diff
@@ -0,0 +1,67 @@
+diff -burN curl-7.40.0/CMake/CurlTests.c curl-7.40.0.orig/CMake/CurlTests.c
+--- curl-7.40.0/CMake/CurlTests.c	2017-07-26 15:24:27.473903048 +0200
++++ curl-7.40.0.orig/CMake/CurlTests.c	2017-07-26 15:22:05.268949035 +0200
+@@ -139,7 +139,7 @@
+   rc = gethostbyname_r(address, &h, &hdata);
+ #elif defined(HAVE_GETHOSTBYNAME_R_5) || \
+       defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
+-  rc = gethostbyname_r(address, &h, buffer, 8192, 0, &h_errnop);
++  rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
+   (void)hp; /* not used for test */
+ #elif defined(HAVE_GETHOSTBYNAME_R_6) || \
+       defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
+diff -burN curl-7.40.0.orig/CMake/OtherTests.cmake curl-7.40.0/CMake/OtherTests.cmake
+--- curl-7.40.0.orig/CMake/OtherTests.cmake	2014-11-20 18:42:16.000000000 +0100
++++ curl-7.40.0/CMake/OtherTests.cmake	2017-07-21 16:37:37.414343678 +0200
+@@ -10,6 +10,7 @@
+ 
+ set(signature_call_conv)
+ if(HAVE_WINDOWS_H)
++   set(_source_epilogue "${_source_epilogue}\n#define _WINSOCKAPI_")
+   add_header_include(HAVE_WINDOWS_H "windows.h")
+   add_header_include(HAVE_WINSOCK2_H "winsock2.h")
+   add_header_include(HAVE_WINSOCK_H "winsock.h")
+@@ -163,7 +164,9 @@
+     return 0;
+   }" HAVE_MSG_NOSIGNAL)
+ 
+-if(NOT HAVE_WINDOWS_H)
++if(HAVE_WINDOWS_H)
++add_header_include(HAVE_WINSOCK2_H "winsock2.h")
++else()
+   add_header_include(HAVE_SYS_TIME_H "sys/time.h")
+   add_header_include(TIME_WITH_SYS_TIME "time.h")
+   add_header_include(HAVE_TIME_H "time.h")
+diff -burN curl-7.40.0.orig/src/CMakeLists.txt curl-7.40.0/src/CMakeLists.txt
+--- curl-7.40.0.orig/src/CMakeLists.txt	2014-11-20 18:42:17.000000000 +0100
++++ curl-7.40.0/src/CMakeLists.txt	2017-07-21 16:37:41.082367733 +0200
+@@ -25,14 +25,21 @@
+       "${CMAKE_CURRENT_SOURCE_DIR}/tool_hugehelp.h"
+     VERBATIM)
+ else()
+-  add_custom_command(
+-    OUTPUT tool_hugehelp.c
+-    COMMAND echo "/* built-in manual is disabled, blank function */" > tool_hugehelp.c
+-    COMMAND echo "#include \"tool_hugehelp.h\"" >> tool_hugehelp.c
+-    COMMAND echo "void hugehelp(void) {}" >> tool_hugehelp.c
+-    DEPENDS
+-      "${CMAKE_CURRENT_SOURCE_DIR}/tool_hugehelp.h"
+-    VERBATIM)
++file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tool_hugehelp.c
++"/*built-in manual is disabled, blank function */\n"
++)
++file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/tool_hugehelp.c
++"#include \"tool_hugehelp.h\"\nvoid hugehelp(void) {}\n"
++)
++
++  # add_custom_command(
++    # OUTPUT tool_hugehelp.c
++    # COMMAND echo "/* built-in manual is disabled, blank function */" > tool_hugehelp.c
++    # COMMAND echo "#include \"tool_hugehelp.h\"" >> tool_hugehelp.c
++    # COMMAND echo "void hugehelp(void) {}" >> tool_hugehelp.c
++    # DEPENDS
++      # "${CMAKE_CURRENT_SOURCE_DIR}/tool_hugehelp.h"
++    # VERBATIM)
+ endif()
+ 
+ transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
diff --git a/SuperBuild/patches/GDAL/gdal-2-enviRotation-all.diff b/SuperBuild/patches/GDAL/gdal-2-enviRotation-all.diff
new file mode 100644
index 0000000000000000000000000000000000000000..8c7f7acdce6b34c908a9a10580f2697157534658
--- /dev/null
+++ b/SuperBuild/patches/GDAL/gdal-2-enviRotation-all.diff
@@ -0,0 +1,32 @@
+diff -burN gdal-2.2.1-orig/frmts/raw/envidataset.cpp gdal-2.2.1/frmts/raw/envidataset.cpp
+--- gdal-2.2.1-orig/frmts/raw/envidataset.cpp	2017-06-23 14:18:43.000000000 +0200
++++ gdal-2.2.1/frmts/raw/envidataset.cpp	2017-07-20 18:25:05.373655046 +0200
+@@ -620,10 +620,13 @@
+         adfGeoTransform[4] != 0.0 || adfGeoTransform[5] != 1.0;
+     if( bHasNonDefaultGT )
+     {
++        const double dfDet = adfGeoTransform[1] * adfGeoTransform[5] -
++                             adfGeoTransform[2] * adfGeoTransform[4];
++        const double dfSign = (dfDet>0.0 ? 1.0 : -1.0);
+         const double dfRotation1 =
+-            -atan2(-adfGeoTransform[2], adfGeoTransform[1]) * kdfRadToDeg;
++            -atan2(dfSign * adfGeoTransform[2], adfGeoTransform[1]) * kdfRadToDeg;
+         const double dfRotation2 =
+-            -atan2(-adfGeoTransform[4], -adfGeoTransform[5]) * kdfRadToDeg;
++            -atan2(-adfGeoTransform[4], dfSign * adfGeoTransform[5]) * kdfRadToDeg;
+         const double dfRotation = (dfRotation1 + dfRotation2) / 2.0;
+ 
+         if( fabs(dfRotation1 - dfRotation2) > 1e-5 )
+@@ -1534,7 +1537,12 @@
+ 
+     // Fallback to localcs if we don't recognise things.
+     if( oSRS.GetRoot() == NULL )
++        {
+         oSRS.SetLocalCS(papszFields[0]);
++        // assume that the Y axis isn't flipped
++        adfGeoTransform[2] *= -1.0;
++        adfGeoTransform[5] *= -1.0;
++        }
+ 
+     // Try to set datum from projection info line if we have a
+     // projected coordinate system without a GEOGCS.
diff --git a/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in b/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in
index 87f6bcd7b43280ad18f51db294000b68bcb1cbb8..72824d4104ed4ef7ae04e073ea4e264a9945be2d 100644
--- a/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in
+++ b/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in
@@ -11,60 +11,60 @@ JPEG_SUPPORTED = 1
 # This will enable 12bit libjpeg - use only with internal jpeg builds.
 #JPEG12_SUPPORTED = 1
 
-GDAL_HOME="@CMAKE_WIN_INSTALL_PREFIX@"
+GDAL_HOME="@SB_INSTALL_PREFIX_NATIVE@"
 
 #if using an external jpeg library uncomment the follwing lines
 JPEG_EXTERNAL_LIB = 1
-JPEGDIR = @CMAKE_WIN_INSTALL_PREFIX@\include
-JPEG_LIB = @CMAKE_WIN_INSTALL_PREFIX@\lib\jpeg.lib
+JPEGDIR = @SB_INSTALL_PREFIX_NATIVE@\include
+JPEG_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\jpeg.lib
 
 #if using an external png library uncomment the follwing lines
 PNG_EXTERNAL_LIB = 1
-PNGDIR = @CMAKE_WIN_INSTALL_PREFIX@\include
-PNG_LIB = @CMAKE_WIN_INSTALL_PREFIX@\lib\libpng.lib
+PNGDIR = @SB_INSTALL_PREFIX_NATIVE@\include
+PNG_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\libpng.lib
 
 # if using an external libtiff library
-TIFF_INC = -I@CMAKE_WIN_INSTALL_PREFIX@\include
-TIFF_LIB = @CMAKE_WIN_INSTALL_PREFIX@\lib\libtiff_i.lib
+TIFF_INC = -I@SB_INSTALL_PREFIX_NATIVE@\include
+TIFF_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\tiff.lib
 # uncomment following line, if you have libtiff version >= 4.0 to enable BigTIFF support
 TIFF_OPTS= -DBIGTIFF_SUPPORT
 
 # if using an external libgeotiff library
-GEOTIFF_INC = -I@CMAKE_WIN_INSTALL_PREFIX@\include
-GEOTIFF_LIB = @CMAKE_WIN_INSTALL_PREFIX@\lib\geotiff_i.lib
+GEOTIFF_INC = -I@SB_INSTALL_PREFIX_NATIVE@\include
+GEOTIFF_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\geotiff_i.lib
 
-EXPAT_DIR = @CMAKE_WIN_INSTALL_PREFIX@
+EXPAT_DIR = @SB_INSTALL_PREFIX_NATIVE@
 EXPAT_INCLUDE = -I$(EXPAT_DIR)\include
 EXPAT_LIB = $(EXPAT_DIR)\lib\expat.lib
 
 # SQLite Libraries
-SQLITE_INC=-I@CMAKE_WIN_INSTALL_PREFIX@\include
-SQLITE_LIB=@CMAKE_WIN_INSTALL_PREFIX@\lib\sqlite3.lib
+SQLITE_INC=-I@SB_INSTALL_PREFIX_NATIVE@\include
+SQLITE_LIB=@SB_INSTALL_PREFIX_NATIVE@\lib\sqlite3.lib
 # Uncomment following line if libsqlite3 has been compiled with SQLITE_HAS_COLUMN_METADATA=yes
 SQLITE_HAS_COLUMN_METADATA=yes
 
 # PROJ.4 stuff
-PROJ_INCLUDE = -I@CMAKE_WIN_INSTALL_PREFIX@\include
-PROJ_LIBRARY = @CMAKE_WIN_INSTALL_PREFIX@\lib\proj_i.lib
+PROJ_INCLUDE = -I@SB_INSTALL_PREFIX_NATIVE@\include
+PROJ_LIBRARY = @SB_INSTALL_PREFIX_NATIVE@\lib\proj.lib
 
 # Uncomment to use libcurl (DLL by default)
 # The cURL library is used for WCS, WMS, GeoJSON, SRS call importFromUrl(), WFS, GFT, CouchDB, /vsicurl/ etc.
-CURL_DIR=@CMAKE_WIN_INSTALL_PREFIX@
+CURL_DIR=@SB_INSTALL_PREFIX_NATIVE@
 CURL_INC = -I$(CURL_DIR)\include
 # Uncoment following line to use libcurl as dynamic library
-CURL_LIB = $(CURL_DIR)\lib\libcurl.lib wsock32.lib wldap32.lib winmm.lib
+CURL_LIB = $(CURL_DIR)\lib\libcurl_imp.lib wsock32.lib wldap32.lib winmm.lib
 
 # Uncomment for GEOS support (GEOS >= 3.1.0 required)
-GEOS_DIR=@CMAKE_WIN_INSTALL_PREFIX@
+GEOS_DIR=@SB_INSTALL_PREFIX_NATIVE@
 GEOS_CFLAGS = -I$(GEOS_DIR)\include -I$(GEOS_DIR)\include\geos -DHAVE_GEOS
-GEOS_LIB     = $(GEOS_DIR)\lib\geos_i.lib $(GEOS_DIR)\lib\geos_c_i.lib
+GEOS_LIB     = $(GEOS_DIR)\lib\geos.lib $(GEOS_DIR)\lib\geos_c.lib
 
 # Uncomment for OpenJpeg support
 HAVE_OPENJPEG = YES
 OPENJPEG_ENABLED = YES
 OPENJPEG_VERSION = 20100
-OPENJPEG_CFLAGS = -I@CMAKE_WIN_INSTALL_PREFIX@\include
-OPENJPEG_LIB = @CMAKE_WIN_INSTALL_PREFIX@\lib\openjp2.lib
+OPENJPEG_CFLAGS = -I@SB_INSTALL_PREFIX_NATIVE@\include
+OPENJPEG_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\openjp2.lib
 
 
 ##################################################################
@@ -86,6 +86,10 @@ OPENJPEG_LIB = @CMAKE_WIN_INSTALL_PREFIX@\lib\openjp2.lib
 #		$(LIBKML_DIR)/third_party\zlib-1.2.3.win32/lib/minizip.lib \
 #		$(LIBKML_DIR)/third_party\zlib-1.2.3.win32/lib/zlib.lib
 
+#we use external zlib on windows
+ZLIB_EXTERNAL_LIB = 1
+ZLIB_INC = -I@SB_INSTALL_PREFIX_NATIVE@\include
+ZLIB_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\zlib.lib
 
 # Uncomment the following and update to enable NCSA HDF Release 4 support.
 #HDF4_PLUGIN = NO
diff --git a/SuperBuild/patches/GEOS/CMakeLists.txt b/SuperBuild/patches/GEOS/CMakeLists.txt
deleted file mode 100644
index a89103afaecae9441d1095ccab4d97bb094148eb..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/GEOS/CMakeLists.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (C) 2005-2017 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.
-#
-
-cmake_minimum_required(VERSION 2.8)
-
-project(GEOS_SUPERBUILD)
-
-add_custom_target(build_with_nmake 
-ALL DEPENDS 
-COMMAND
-nmake /f ${GEOS_SB_SRC}/makefile.vc
-WORKING_DIRECTORY ${GEOS_SB_SRC}
-)
-
-install(FILES  ${GEOS_SB_SRC}/capi/geos_c.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
-install(FILES  ${GEOS_SB_SRC}/include/geos.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
-install(DIRECTORY ${GEOS_SB_SRC}/include/geos DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
-install(FILES  ${GEOS_SB_SRC}/src/geos.dll DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
-install(FILES  ${GEOS_SB_SRC}/src/geos_c.dll DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
-install(FILES  ${GEOS_SB_SRC}/src/geos.lib DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
-install(FILES  ${GEOS_SB_SRC}/src/geos_i.lib DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
-install(FILES  ${GEOS_SB_SRC}/src/geos_c_i.lib DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
diff --git a/SuperBuild/patches/GEOS/geos-1-fixes-all.diff b/SuperBuild/patches/GEOS/geos-1-fixes-all.diff
index 4a516fe4697128ff5f81bbecc25568e62a46bceb..ca7663fffbf52a566124f57daf25d52e378d2da9 100644
--- a/SuperBuild/patches/GEOS/geos-1-fixes-all.diff
+++ b/SuperBuild/patches/GEOS/geos-1-fixes-all.diff
@@ -1,93 +1,22 @@
-diff -burN geos-3.5.0.orig/CMakeLists.txt geos-3.5.0/CMakeLists.txt
---- geos-3.5.0.orig/CMakeLists.txt	2016-09-02 11:02:28.833742143 +0200
-+++ geos-3.5.0/CMakeLists.txt	2016-09-02 11:05:05.897748116 +0200
-@@ -55,6 +55,9 @@
- # Check custom global options
- #################################################################################
- 
-+option(GEOS_BUILD_STATIC
-+  "Set to OFF|ON (default) to control build of GEOS tests package" OFF)
-+
- option(GEOS_ENABLE_TESTS
-   "Set to OFF|ON (default) to control build of GEOS tests package" ON)
- 
-@@ -317,18 +320,18 @@
- 
-   # Define "make check" as alias for "make test"
-   add_custom_target(check COMMAND ctest)
--
-+add_subdirectory(tests)
- endif()
- 
- #################################################################################
- # Configure subdirectories
- #################################################################################
--include(GenerateSourceGroups)
-+#include(GenerateSourceGroups)
- 
- add_subdirectory(include)
- add_subdirectory(src)
- add_subdirectory(capi)
--add_subdirectory(tests)
-+
- add_subdirectory(tools)
- 
- #################################################################################
-diff -burN geos-3.5.0.orig/include/CMakeLists.txt geos-3.5.0/include/CMakeLists.txt
---- geos-3.5.0.orig/include/CMakeLists.txt	2016-09-02 11:02:28.837742143 +0200
-+++ geos-3.5.0/include/CMakeLists.txt	2016-09-02 11:03:03.581743464 +0200
-@@ -54,4 +54,4 @@
- #################################################################################
- # Group source files for IDE source explorers (e.g. Visual Studio)
- #################################################################################
--GenerateSourceGroups(include)
-+#GenerateSourceGroups(include)
-diff -burN geos-3.5.0.orig/src/CMakeLists.txt geos-3.5.0/src/CMakeLists.txt
---- geos-3.5.0.orig/src/CMakeLists.txt	2016-09-02 11:02:28.869742144 +0200
-+++ geos-3.5.0/src/CMakeLists.txt	2016-09-02 11:05:14.621748447 +0200
-@@ -62,7 +62,18 @@
- else()
- 
-   add_library(geos SHARED ${geos_SOURCES} ${geos_ALL_HEADERS})
-+  if(GEOS_BUILD_STATIC)
-   add_library(geos-static STATIC ${geos_SOURCES} ${geos_ALL_HEADERS})
-+  set_target_properties(geos-static
-+    PROPERTIES
-+    OUTPUT_NAME "geos"
-+    PREFIX "lib"
-+    CLEAN_DIRECT_OUTPUT 1)
-+  install(TARGETS geos geos-static
-+    RUNTIME DESTINATION bin
-+    LIBRARY DESTINATION lib
-+    ARCHIVE DESTINATION lib)
-+endif()
- 
-   set_target_properties(geos
-     PROPERTIES
-@@ -70,11 +81,6 @@
-     VERSION ${VERSION}
-     CLEAN_DIRECT_OUTPUT 1)
- 
--  set_target_properties(geos-static
--    PROPERTIES
--    OUTPUT_NAME "geos"
--    PREFIX "lib"
--    CLEAN_DIRECT_OUTPUT 1)
- 
- endif()
- 
-@@ -90,7 +96,7 @@
- #################################################################################
- 
- if(NOT GEOS_ENABLE_MACOSX_FRAMEWORK)
--  install(TARGETS geos geos-static
-+  install(TARGETS geos
-     RUNTIME DESTINATION bin
-     LIBRARY DESTINATION lib
-     ARCHIVE DESTINATION lib)
-@@ -99,4 +105,4 @@
- #################################################################################
- # Group source files for IDE source explorers (e.g. Visual Studio)
- #################################################################################
--GenerateSourceGroups(src)
-+#GenerateSourceGroups(src)
+diff -burN geos-3.6.1.orig/cmake/modules/GenerateSourceGroups.cmake geos-3.6.1/cmake/modules/GenerateSourceGroups.cmake
+--- geos-3.6.1.orig/cmake/modules/GenerateSourceGroups.cmake	1970-01-01 01:00:00.000000000 +0100
++++ geos-3.6.1/cmake/modules/GenerateSourceGroups.cmake	2017-06-19 11:19:32.143054641 +0200
+@@ -0,0 +1,17 @@
++#
++# Macro generates tree of IDE source groups based on folders structure
++# Source: http://www.cmake.org/pipermail/cmake/2013-November/056332.html
++# 
++macro(GenerateSourceGroups curdir)
++  file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*)
++  foreach(child ${children})
++    if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child})
++      GenerateSourceGroups(${curdir}/${child})
++    else()
++      string(REPLACE "/" "\\" groupname ${curdir})
++      # I would like to call the src root folder in a different name, only in visual studio (not mandatory requirement)
++	  string(REPLACE "src" "Source Files" groupname ${groupname})
++      source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child})
++    endif()
++  endforeach()
++endmacro()
+\ Pas de fin de ligne à la fin du fichier
diff --git a/SuperBuild/patches/GEOS/nmake.opt b/SuperBuild/patches/GEOS/nmake.opt
deleted file mode 100644
index ca21bd252387c8b166343bc966871399a2b36abd..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/GEOS/nmake.opt
+++ /dev/null
@@ -1,250 +0,0 @@
-#
-# nmake.opt - main configuration file for NMAKE makefiles
-#
-!MESSAGE **********************************************************************
-!MESSAGE *** GEOS Build Configuration ***
-
-# TODO: Confirm as redundant and remove, nmake /P displays _NMAKE_VER anyway.
-#!INCLUDE <ntwin32.mak>
-
-###############################################################################
-# For convenience, user may put custom settings to private mynmake.opt
-# and use EXT_NMAKE_OPT option while calling nmake.exe, as follows:
-#
-# nmake -f makefile.vc EXT_NMAKE_OPT=mynmake.opt
-
-!IFDEF EXT_NMAKE_OPT
-!MESSAGE *** Setting EXT_NMAKE_OPT $(EXT_NMAKE_OPT)
-!INCLUDE $(EXT_NMAKE_OPT)
-!ENDIF
-
-###############################################################################
-# Set BUILD_DEBUG to YES if you want to make debug build
-# and to prepare not optimized binaries.
-
-!IFNDEF BUILD_DEBUG 
-BUILD_DEBUG = NO
-!ENDIF
-
-!MESSAGE *** Setting BUILD_DEBUG $(BUILD_DEBUG)
-
-###############################################################################
-# Set ENABLE_INLINE to YES if you want to make debug build
-# and to prepare not optimized binaries.
-
-!IFNDEF ENABLE_INLINE
-ENABLE_INLINE = NO
-!ENDIF
-
-!MESSAGE *** Setting ENABLE_INLINE $(ENABLE_INLINE)
-
-###############################################################################
-# Set BUILD_BATCH to YES if you want feed compiler with all
-# source .c and .cpp files in single batch.
-
-!IFNDEF BUILD_BATCH
-BUILD_BATCH = NO
-!ENDIF
-
-!MESSAGE *** Setting BUILD_BATCH $(BUILD_BATCH)
-
-###############################################################################
-# Set WIN64=YES if you are building for 64-bit windows (x64).
-# Alternatively, pass WIN64=YES as NMAKE command line argument.
-###############################################################################
-!IFNDEF WIN64
-WIN64 = NO
-!ENDIF
-
-!MESSAGE *** Setting WIN64 $(WIN64)
-
-###############################################################################
-# Derive version of Visual C++ being used from NMAKE if not specified
-#
-# WARNING:
-# If we should expect variety of NMAKE build versions, tests below may fail
-# and we will need to fall back to setting GEOS_MSVC as command line parameter.
-
-!IF "$(_NMAKE_VER)" == ""
-GEOS_MSVC = 4.0
-!ERROR *** Failed to determine version of Visual C++
-!ELSEIF "$(_NMAKE_VER)" == "162"
-GEOS_MSVC = 5.0
-!ERROR *** Detected Visual C++ 5.0 - NOT SUPPORTED
-!ELSEIF "$(_NMAKE_VER)" == "6.00.8168.0"
-GEOS_MSVC = 6.0
-GEOS_MSC = 1200
-!ERROR *** Detected Visual C++ 6.0 - NOT SUPPORTED
-!ELSEIF "$(_NMAKE_VER)" == "7.00.9466"
-GEOS_MSVC = 7.0
-GEOS_MSC = 1300
-!ELSEIF "$(_NMAKE_VER)" == "7.10.3077"
-GEOS_MSVC = 7.1
-GEOS_MSC = 1310
-!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.42"
-GEOS_MSVC = 8.0
-GEOS_MSC = 1400
-!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.762"
-GEOS_MSVC = 8.0
-GEOS_MSC = 1400
-!ELSEIF "$(_NMAKE_VER)" == "9.00.21022.08"
-GEOS_MSVC = 9.0
-GEOS_MSC = 1500
-!ELSEIF "$(_NMAKE_VER)" == "9.00.30729.01"
-GEOS_MSVC = 9.0
-GEOS_MSC = 1500
-!ELSEIF "$(_NMAKE_VER)" == "10.00.30128.01"
-GEOS_MSVC = 10.0
-GEOS_MSC = 1600
-!ELSEIF "$(_NMAKE_VER)" == "10.00.30319.01"
-GEOS_MSVC = 10.0
-GEOS_MSC = 1600
-!ELSEIF "$(_NMAKE_VER)" == "11.00.40825.2"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.50522.1"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.50727.1"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.51106.1"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.60315.1"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.60430.2"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.60521.0"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.60610.1"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "11.00.61030.0"
-GEOS_MSVC = 11.0
-GEOS_MSC = 1700
-!ELSEIF "$(_NMAKE_VER)" == "12.00.21005.1"
-GEOS_MSVC = 12.0
-GEOS_MSC = 1800
-!ELSEIF "$(_NMAKE_VER)" == "14.00.22816.0"
-GEOS_MSVC = 14.0
-GEOS_MSC = 1900
-!ELSEIF "$(_NMAKE_VER)" == "14.00.23026.0"
-GEOS_MSVC = 14.0
-GEOS_MSC = 1900
-!ELSEIF "$(_NMAKE_VER)" == "14.00.23918.0"
-GEOS_MSVC = 14.0
-GEOS_MSC = 1900
-!ELSEIF "$(_NMAKE_VER)" == "14.00.24210.0"
-GEOS_MSVC = 14.0
-GEOS_MSC = 1900
-!ELSE
-GEOS_MSVC = 0.0
-GEOS_MSC = 0
-!ENDIF
-
-!IF "$(GEOS_MSVC)" == "0.0" && "$(GEOS_MSC)" == "0"
-!MESSAGE *** Cannot determine Visual C++ version
-!ERROR *** Aborting make job
-!ELSE
-!MESSAGE *** Using Microsoft NMAKE version $(_NMAKE_VER)
-!MESSAGE *** Using Microsoft Visual C++ version $(GEOS_MSVC)
-!MESSAGE *** Using Microsoft C/C++ version $(GEOS_MSC)
-!ENDIF
-
-###############################################################################
-# Optional use of Visual Leak Detector (VLD) http://vld.codeplex.com/
-# Uncomment this line to use VLD in debug configuration only:
-#MSVC_VLD_DIR=$(EXTLIBDIR)\Source\vld\vld
-
-!IF "$(BUILD_DEBUG)" == "YES"
-!IFDEF MSVC_VLD_DIR
-MSVC_VLD_FLAGS=-DMSVC_USE_VLD=1 -I$(MSVC_VLD_DIR)\include
-!IFDEF WIN64
-MSVC_VLD_LIB=/LIBPATH:$(MSVC_VLD_DIR)/lib/Win64
-!ELSE
-MSVC_VLD_LIB=/LIBPATH:$(MSVC_VLD_DIR)/lib/Win32
-!ENDIF
-!ENDIF
-!ENDIF
-
-###############################################################################
-# Include directories
-
-GEOS_INCLUDE = -I..\include -I..\capi
-
-!MESSAGE *** Setting GEOS_INCLUDE $(GEOS_INCLUDE)
-!MESSAGE *** Setting INCLUDE $(INCLUDE)
-
-###############################################################################
-# Compilation flags for Release and Debug modes
-
-GEOS_CPPFLAGS = /D "NOMINMAX" /D "WIN32_LEAN_AND_MEAN" /D "NOGDI"
-GEOS_CPPFLAGS = $(GEOS_CPPFLAGS) /D "GEOS_DLL_EXPORT" $(MSVC_VLD_FLAGS)
-
-!IF "$(BUILD_DEBUG)" == "YES"
-BUILD_PREFIX=_d
-GEOS_CFLAGS = /nologo /MDd /GR /Od /W4 /Zi
-GEOS_CPPFLAGS = /D "DEBUG" /D "_DEBUG" $(GEOS_CPPFLAGS)
-!ELSE
-GEOS_CFLAGS = /nologo /MD /GR /O2 /W3
-GEOS_CPPFLAGS = /D "NDEBUG" $(GEOS_CPPFLAGS)
-!ENDIF
-
-# Compiler version specific flags
-!IF $(GEOS_MSC) >= 1400
-GEOS_CFLAGS = $(GEOS_CFLAGS) /EHs
-GEOS_CPPFLAGS = $(GEOS_CPPFLAGS) /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_SCL_SECURE_NO_DEPRECATE"
-!ELSE
-GEOS_CFLAGS = $(GEOS_CFLAGS) /GX
-!ENDIF
-
-# For Visual C++ 9.0+ use multiple process build
-!IF "$(BUILD_BATCH)" == "YES"
-!IF $(GEOS_MSC) > 1400
-MPFLAGS = /MP
-!MESSAGE *** Setting /MP flag to number of effective processors
-!ENDIF
-!ENDIF
-
-!IF "$(ENABLE_INLINE)" == "YES"
-GEOS_CFLAGS = /D "GEOS_INLINE"
-!ENDIF
-
-!MESSAGE *** Using GEOS_CFLAGS $(GEOS_CFLAGS)
-!MESSAGE *** Using GEOS_CPPFLAGS $(GEOS_CPPFLAGS)
-
-CFLAGS=$(MPFLAGS) $(GEOS_CFLAGS) $(GEOS_CPPFLAGS) $(GEOS_INCLUDE)
-
-!MESSAGE *** Complete CFLAGS $(CFLAGS)
-
-###############################################################################
-# Output location
-
-LIBNAME = geos$(BUILD_PREFIX).lib
-DLLNAME = geos$(BUILD_PREFIX).dll
-SLIBNAME = geos_i$(BUILD_PREFIX).lib
-CDLLNAME = geos_c$(BUILD_PREFIX).dll
-CLIBNAME = geos_c_i$(BUILD_PREFIX).lib
-
-###############################################################################
-# Building toolset programs
-
-MAKE = nmake
-CC = cl
-RM = del
-CP = copy
-
-# Linker executable
-# - Dynamic-Linked Libraries
-# $(LINK) /dll
-# - Static Libraries (use of lib.exe wrapper is not portable, see VC++ Toolkit 2003)
-# $(LINK) /lib
-LINK = link.exe
-LINKER_FLAGS = $(MSVC_VLD_LIB)
-
-!MESSAGE **********************************************************************
-# EOF
diff --git a/SuperBuild/patches/GEOTIFF/geotiff-1-fix-rpath-macx.diff b/SuperBuild/patches/GEOTIFF/geotiff-1-fix-rpath-macx.diff
new file mode 100644
index 0000000000000000000000000000000000000000..64b0cfcc5278ebfe0e04afee03f083afc4cf8bc0
--- /dev/null
+++ b/SuperBuild/patches/GEOTIFF/geotiff-1-fix-rpath-macx.diff
@@ -0,0 +1,22 @@
+diff -burN libgeotiff-1.4.2.orig/CMakeLists.txt libgeotiff-1.4.2/CMakeLists.txt
+--- libgeotiff-1.4.2.orig/CMakeLists.txt	Tue Jul 25 17:16:02 2017
++++ libgeotiff-1.4.2/CMakeLists.txt	Tue Jul 25 17:16:40 2017
+@@ -451,12 +451,12 @@
+       VERSION ${LINK_VERSION}
+       SOVERSION ${LINK_SOVERSION}
+       CLEAN_DIRECT_OUTPUT 1 )
+-   if (APPLE)
+-      set_target_properties(
+-        ${GEOTIFF_LIBRARY_TARGET}
+-        PROPERTIES
+-        INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+-   endif()
++   # if (APPLE)
++   #    set_target_properties(
++   #      ${GEOTIFF_LIBRARY_TARGET}
++   #      PROPERTIES
++   #      INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
++   # endif()
+ 
+ ELSE(UNIX)
+ # Default:
diff --git a/SuperBuild/patches/GEOTIFF/geotiff-fix-configure-for-macx.diff b/SuperBuild/patches/GEOTIFF/geotiff-fix-configure-for-macx.diff
deleted file mode 100755
index 32c001b68d59f51198d6264b5173ec282cd5e270..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/GEOTIFF/geotiff-fix-configure-for-macx.diff
+++ /dev/null
@@ -1,30 +0,0 @@
-diff -burN libgeotiff-1.4.1.orig/configure libgeotiff-1.4.1/configure
---- libgeotiff-1.4.1.orig/configure	2016-04-15 17:57:22.000000000 +0200
-+++ libgeotiff-1.4.1/configure	2016-04-19 09:33:34.000000000 +0200
-@@ -10079,9 +10079,9 @@
-   esac
-   if test "$_lt_dar_can_shared" = "yes"; then
-     output_verbose_link_cmd=func_echo_all
--    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-     module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
--    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-     module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- 
-   else
-@@ -16101,7 +16101,7 @@
- 
-     PROJ_CONFIG="yes"
- 
--    elif test \( -f "$PROJ_HOME/lib/libproj.a" -o -f "$PROJ_HOME/lib/libproj.so" \) -a -f "$PROJ_HOME/include/proj_api.h"; then
-+    elif test \( -f "$PROJ_HOME/lib/libproj.a" -o -f "$PROJ_HOME/lib/libproj.so" -o -f "$PROJ_HOME/lib/libproj.dylib" \) -a -f "$PROJ_HOME/include/proj_api.h"; then
-     PROJ_LIB="-L$PROJ_HOME/lib -lproj"
-     PROJ_INC=$PROJ_HOME/include
- 
-@@ -21017,5 +21017,3 @@
- 
- 
- echo ""
--
--
diff --git a/SuperBuild/patches/GLFW/glfw-1-fixes-win.diff b/SuperBuild/patches/GLFW/glfw-1-fixes-all.diff
similarity index 100%
rename from SuperBuild/patches/GLFW/glfw-1-fixes-win.diff
rename to SuperBuild/patches/GLFW/glfw-1-fixes-all.diff
diff --git a/SuperBuild/patches/OSSIM/ossim-5-compat_geos36-all.diff b/SuperBuild/patches/OSSIM/ossim-5-compat_geos36-all.diff
new file mode 100644
index 0000000000000000000000000000000000000000..53f7312b8cac596f909c9e2a36e33d278637d120
--- /dev/null
+++ b/SuperBuild/patches/OSSIM/ossim-5-compat_geos36-all.diff
@@ -0,0 +1,36 @@
+diff -burN OSSIM.orig/ossim/src/ossim/base/ossimPolyArea2d.cpp OSSIM/ossim/src/ossim/base/ossimPolyArea2d.cpp
+--- OSSIM.orig/ossim/src/ossim/base/ossimPolyArea2d.cpp	2017-07-04 15:16:30.659669941 +0200
++++ OSSIM/ossim/src/ossim/base/ossimPolyArea2d.cpp	2017-07-05 09:46:23.142041689 +0200
+@@ -28,19 +28,13 @@
+ #include <exception>
+ #include <vector>
+ 
+-class ossimGeometryFactoryWrapper : public ossimReferenced
++class ossimGeometryFactoryWrapper : public ossimReferenced, public geos::geom::GeometryFactory
+ {
+ public:
+    ossimGeometryFactoryWrapper()
+-      : m_geomFactory(0)
+-   {
+-      geos::geom::PrecisionModel *pm =
+-         new geos::geom::PrecisionModel(geos::geom::PrecisionModel::FLOATING);
+-      m_geomFactory = new geos::geom::GeometryFactory(pm, -1); 
+-   }
+-   virtual ~ossimGeometryFactoryWrapper(){if(m_geomFactory) delete m_geomFactory;m_geomFactory=0;}
+-   
+-   geos::geom::GeometryFactory* m_geomFactory;
++      : geos::geom::GeometryFactory(new geos::geom::PrecisionModel(geos::geom::PrecisionModel::FLOATING),-1)
++    {}
++   virtual ~ossimGeometryFactoryWrapper(){}
+ };
+ 
+ class OssimPolyArea2dPrivate
+@@ -55,7 +49,7 @@
+    void deleteGeometry() { if(m_geometry) { delete m_geometry; m_geometry = 0; }}
+    void setGeometry(const ossimPolygon& polygon, const vector<ossimPolygon>& holes = vector<ossimPolygon>());
+    void setGeometry(GeometryPtr geom){deleteGeometry();m_geometry=geom;}
+-   geos::geom::GeometryFactory* geomFactory(){{return m_globalFactory.valid()?m_globalFactory->m_geomFactory:0;}}
++   geos::geom::GeometryFactory* geomFactory(){{return m_globalFactory.valid()?m_globalFactory.get():0;}}
+    GeometryPtr m_geometry;
+    static ossimRefPtr<ossimGeometryFactoryWrapper> m_globalFactory; 
+ };
diff --git a/SuperBuild/patches/PROJ/proj-1-cmakefixes-all.diff b/SuperBuild/patches/PROJ/proj-1-cmakefixes-all.diff
new file mode 100644
index 0000000000000000000000000000000000000000..a95c58fbfe34ecdfd12073c1132f9a68811c1f6e
--- /dev/null
+++ b/SuperBuild/patches/PROJ/proj-1-cmakefixes-all.diff
@@ -0,0 +1,34 @@
+diff -burN proj-4.9.3.orig/CMakeLists.txt proj-4.9.3/CMakeLists.txt
+--- proj-4.9.3.orig/CMakeLists.txt	2016-08-29 20:47:58.000000000 +0200
++++ proj-4.9.3/CMakeLists.txt	2017-07-26 12:34:26.071721900 +0200
+@@ -34,6 +34,7 @@
+ proj_version(MAJOR 4 MINOR 9 PATCH 3)
+ set(PROJ_API_VERSION "12")
+ set(PROJ_BUILD_VERSION "12.0.0")
++option(VERSIONED_OUTPUT "suffix version into output name of binaries." ON)
+ 
+ #################################################################################
+ # Build features and variants
+diff -burN proj-4.9.3.orig/src/lib_proj.cmake proj-4.9.3/src/lib_proj.cmake
+--- proj-4.9.3.orig/src/lib_proj.cmake	2016-08-29 20:47:58.000000000 +0200
++++ proj-4.9.3/src/lib_proj.cmake	2017-07-26 12:28:51.098731200 +0200
+@@ -274,11 +274,19 @@
+ 
+ 
+ if(WIN32)
++if(VERSIONED_OUTPUT)
+   set_target_properties(${PROJ_CORE_TARGET}
+     PROPERTIES
+     VERSION "${${PROJECT_INTERN_NAME}_BUILD_VERSION}"
+     OUTPUT_NAME "${PROJ_CORE_TARGET_OUTPUT_NAME}"
+     CLEAN_DIRECT_OUTPUT 1)
++    else()
++  set_target_properties(${PROJ_CORE_TARGET}
++    PROPERTIES
++    VERSION "${${PROJECT_INTERN_NAME}_BUILD_VERSION}"
++    CLEAN_DIRECT_OUTPUT 1)
++    endif() #VERSIONED_OUTPUT
++ 
+ elseif(BUILD_FRAMEWORKS_AND_BUNDLE)
+   set_target_properties(${PROJ_CORE_TARGET}
+     PROPERTIES
diff --git a/SuperBuild/patches/PROJ/proj-fix-rpath-for-macx.diff b/SuperBuild/patches/PROJ/proj-fix-rpath-for-macx.diff
deleted file mode 100644
index 1ab4acdab9cde44e6aef0930affcdcd525c7cee6..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/PROJ/proj-fix-rpath-for-macx.diff
+++ /dev/null
@@ -1,20 +0,0 @@
-diff -burN proj-4.8.0.orig/configure proj-4.8.0/configure
---- proj-4.8.0.orig/configure	2016-04-18 17:31:49.000000000 +0200
-+++ proj-4.8.0/configure	2016-04-18 17:32:47.000000000 +0200
-@@ -9044,9 +9044,9 @@
-   esac
-   if test "$_lt_dar_can_shared" = "yes"; then
-     output_verbose_link_cmd=func_echo_all
--    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-     module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
--    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-     module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
- 
-   else
-@@ -16296,4 +16296,3 @@
-   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
- $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
- fi
--
diff --git a/SuperBuild/patches/QT4/configure_qt4.bat.in b/SuperBuild/patches/QT4/configure_qt4.bat.in
index ce92ad480dce9d657b13a155cf2296568ddebc68..0439a883f043d14e36b2714fe150268641e7738b 100755
--- a/SuperBuild/patches/QT4/configure_qt4.bat.in
+++ b/SuperBuild/patches/QT4/configure_qt4.bat.in
@@ -4,7 +4,7 @@ set SB_SAVE_LIB=%LIB%
 set INCLUDE=%INCLUDE%;@QT4_INCLUDE_PREFIX_NATIVE@;@QT4_INCLUDE_PREFIX_NATIVE@\freetype2
 set LIB=%LIB%;@QT4_LIB_PREFIX_NATIVE@
 
-@QT4_CONFIGURE_SCRIPT@ -prefix @QT4_INSTALL_PREFIX_NATIVE@ -L @QT4_LIB_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@\freetype2 -opensource -confirm-license -release -shared -nomake demos -nomake examples -nomake tools -no-phonon-backend -no-phonon -no-script -no-scripttools -no-multimedia -no-audio-backend -no-webkit -no-declarative  -no-qt3support -no-xmlpatterns -system-sqlite -qt-sql-sqlite -plugin-sql-sqlite -no-openssl -no-libtiff -no-libmng -system-libpng -system-libjpeg  -system-zlib @QT4_SB_CONFIG@
+@QT4_CONFIGURE_SCRIPT@ -prefix @QT4_INSTALL_PREFIX_NATIVE@ -L @QT4_LIB_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@\freetype2 -opensource -confirm-license -release -shared -nomake demos -nomake examples -nomake tools -no-phonon-backend -no-phonon -no-script -no-scripttools -no-multimedia -no-audio-backend -no-webkit -no-declarative  -no-qt3support -no-xmlpatterns -no-sql-sqlite -no-openssl -no-libtiff -no-libmng -system-libpng -system-libjpeg  -system-zlib @QT4_SB_CONFIG@
 
 set INCLUDE=%SB_SAVE_INCLUDE%
 set LIB=%SB_SAVE_LIB%
diff --git a/SuperBuild/patches/QT4/configure_qt4.sh.in b/SuperBuild/patches/QT4/configure_qt4.sh.in
index 8f8a01a3d3b41bf303a9cbd0deccbd9ac44fff72..1ed3ef3f981f0bb5343f9d2202b5d5cd5150bc70 100755
--- a/SuperBuild/patches/QT4/configure_qt4.sh.in
+++ b/SuperBuild/patches/QT4/configure_qt4.sh.in
@@ -1 +1 @@
-@QT4_CONFIGURE_SCRIPT@ -prefix @QT4_INSTALL_PREFIX_NATIVE@ -L @QT4_LIB_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@/freetype2 -opensource -confirm-license -release -shared -nomake demos -nomake examples -nomake tools -no-phonon-backend -no-phonon -no-script -no-scripttools -no-multimedia -no-audio-backend -no-webkit -no-declarative  -no-qt3support -no-xmlpatterns -system-sqlite -qt-sql-sqlite -plugin-sql-sqlite -no-openssl -no-libtiff -no-libmng -system-libpng -system-libjpeg  -system-zlib @QT4_SB_CONFIG@
+@QT4_CONFIGURE_SCRIPT@ -prefix @QT4_INSTALL_PREFIX_NATIVE@ -L @QT4_LIB_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@ -I @QT4_INCLUDE_PREFIX_NATIVE@/freetype2 -opensource -confirm-license -release -shared -nomake demos -nomake examples -nomake tools -no-phonon-backend -no-phonon -no-script -no-scripttools -no-multimedia -no-audio-backend -no-webkit -no-declarative  -no-qt3support -no-xmlpatterns -no-sql-sqlite -no-openssl -no-libtiff -no-libmng -system-libpng -system-libjpeg  -system-zlib @QT4_SB_CONFIG@
diff --git a/SuperBuild/patches/README.md b/SuperBuild/patches/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f912b067aafc01467b1d278f7005259492412261
--- /dev/null
+++ b/SuperBuild/patches/README.md
@@ -0,0 +1,20 @@
+## Synopsis
+
+Illustrates how to include a patch to the superbuild sources. This patch will be apply before the compilation of the external project.
+
+## Example
+
+Here is how to make a patch for superbuild. The example is here used libgeos but it can be done for any external projects in the OTB Superbuild. 
+
+- cd /tmp
+- wget http://download.osgeo.org/geos/geos-3.6.1.tar.bz2
+- tar xjf geos-3.6.1.tar.bz2
+- cp -r geos-3.6.1 geos-3.6.1.orig
+
+(make changes to geos-3.6.1)
+
+And prepare diff between two directories
+
+- diff -burN geos-3.6.1.orig geos-3.6.1 > geos-1-fixes-all.diff
+
+diff file naming is <project>-<number for applying in correct order>-<all/win/linux/macx>.diff
diff --git a/SuperBuild/patches/SHARK/shark-1-disable-hdf5-all.diff b/SuperBuild/patches/SHARK/shark-1-disable-hdf5-all.diff
new file mode 100755
index 0000000000000000000000000000000000000000..e7fba1953d4d93c79ac864fc175ad957d97774e6
--- /dev/null
+++ b/SuperBuild/patches/SHARK/shark-1-disable-hdf5-all.diff
@@ -0,0 +1,21 @@
+diff -burN Shark.orig/CMakeLists.txt Shark/CMakeLists.txt
+--- Shark.orig/CMakeLists.txt	2016-09-02 17:04:54.000000000 +0200
++++ Shark/CMakeLists.txt	2017-07-31 16:41:18.563473752 +0200
+@@ -194,6 +194,8 @@
+ #####################################################################
+ #           HDF5 configuration
+ #####################################################################
++option(ENABLE_HDF5 "Use HDF5" ON)
++if(ENABLE_HDF5)
+ find_package(HDF5 COMPONENTS C CXX HL QUIET)
+ mark_as_advanced(HDF5_DIR)
+ if(HDF5_FOUND)
+@@ -215,7 +217,7 @@
+ else()
+ 	message(STATUS "HDF5 not found, skip")
+ endif()
+-
++endif() #ENABLE_HDF5
+ #####################################################################
+ #           ATLAS configuration
+ #####################################################################
diff --git a/SuperBuild/patches/SHARK/shark-1-disable-hdf5-linux.diff b/SuperBuild/patches/SHARK/shark-1-disable-hdf5-linux.diff
deleted file mode 100644
index d0b3df4d7f8355a0da6f4a26ff4d0c4187bca1df..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/SHARK/shark-1-disable-hdf5-linux.diff
+++ /dev/null
@@ -1,258 +0,0 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index df8be65..c6c3020 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -191,29 +191,32 @@ endif()
- #####################################################################
- #           HDF5 configuration
- #####################################################################
--find_package(HDF5 COMPONENTS C CXX HL QUIET)
--mark_as_advanced(HDF5_DIR)
--if(HDF5_FOUND)
--	if(HDF5_C_COMPILER_EXECUTABLE AND HDF5_CXX_COMPILER_EXECUTABLE)
--		message(STATUS "Checking HDF5 installation: HDF5 installation seems ok.")
--		include_directories( ${HDF5_INCLUDE_DIR} )
--		link_directories( ${HDF5_LIBRARY_DIR} )
--		list(APPEND LINK_LIBRARIES ${HDF5_LIBRARIES})
--	else()
--		message(STATUS "Checking HDF5 installation:HDF5 package might be broken.")
--		if(NOT( HDF5_C_COMPILER_EXECUTABLE))
--			message(STATUS "  C Compiler Extension not found.")
--		endif()
--		if(NOT( HDF5_CXX_COMPILER_EXECUTABLE))
--			message(STATUS "  CXX Compiler Extension not found.")
--		endif()
--			message(STATUS "Disabling HDF5.")
--		unset( HDF5_FOUND )
--	endif()
--else()
--	message(STATUS "HDF5 not found, skip")
-+option(ENABLE_HDF5 "Use HDF5" ON)
-+
-+if(ENABLE_HDF5)
-+  find_package(HDF5 COMPONENTS C CXX HL QUIET)
-+  mark_as_advanced(HDF5_DIR)
-+  if(HDF5_FOUND)
-+    if(HDF5_C_COMPILER_EXECUTABLE AND HDF5_CXX_COMPILER_EXECUTABLE)
-+      message(STATUS "Checking HDF5 installation: HDF5 installation seems ok.")
-+      include_directories( ${HDF5_INCLUDE_DIR} )
-+      link_directories( ${HDF5_LIBRARY_DIR} )
-+      list(APPEND LINK_LIBRARIES ${HDF5_LIBRARIES})
-+    else()
-+      message(STATUS "Checking HDF5 installation:HDF5 package might be broken.")
-+      if(NOT( HDF5_C_COMPILER_EXECUTABLE))
-+        message(STATUS "  C Compiler Extension not found.")
-+      endif()
-+      if(NOT( HDF5_CXX_COMPILER_EXECUTABLE))
-+        message(STATUS "  CXX Compiler Extension not found.")
-+      endif()
-+      message(STATUS "Disabling HDF5.")
-+      unset( HDF5_FOUND )
-+    endif()
-+  else()
-+    message(STATUS "HDF5 not found, skip")
-+  endif()
- endif()
--
- #####################################################################
- #           ATLAS configuration
- #####################################################################
-@@ -222,104 +225,104 @@ endif()
- option( ENABLE_CBLAS "Use Installed Linear Algebra Library" ON )
- 
- if( ENABLE_CBLAS )
--	set(CBLAS_VENDOR FALSE)
--	if( APPLE )
--		set(CBLAS_VENDOR "Accelerate")
--		set(CBLAS_INCLUDES "")
--		set(CBLAS_LIBRARIES "-framework Accelerate" )
--	else()
--		#todo: do a propper vendor check
--		find_library(OPENBLAS_LIBRARY openblas
--			HINTS ${CBLAS_ROOT}/lib /opt/local/lib
--		)
--		find_library(CBLAS_LIBRARY cblas
--			HINTS ${ATLAS_ROOT}/lib ${CBLAS_ROOT}/lib /opt/local/lib /usr/lib64/atlas/
--		)
--		find_library(CLAPACK_LIBRARY lapack
--			HINTS ${ATLAS_ROOT}/lib ${CBLAS_ROOT}/lib /opt/local/lib /usr/lib64/atlas/
--		)
--		find_library(ATLAS_LIBRARY atlas
--			HINTS ${ATLAS_ROOT}/lib ${CBLAS_ROOT}/lib /opt/local/lib /usr/lib64/atlas/
--		)
--		mark_as_advanced(
--			OPENBLAS_LIBRARY
--			CBLAS_LIBRARY
--			CLAPACK_LIBRARY
--			ATLAS_LIBRARY
--		)
--		#find the cblas.h include path
--		if(CBLAS_LIBRARY )
--			get_filename_component(CBLAS_LIB_PATH ${CBLAS_LIBRARY} PATH )
--		elseif( OPENBLAS_LIBRARY)	
--			get_filename_component(CBLAS_LIB_PATH ${OPENBLAS_LIBRARY} PATH )
--		endif()
--		if(CBLAS_LIB_PATH)
--			find_file(CBLAS_INCLUDES cblas.h 
--				PATHS ${CBLAS_LIB_PATH} ${CBLAS_LIB_PATH}/../include
--			)
--			get_filename_component(CBLAS_INCLUDES ${CBLAS_INCLUDES} PATH )
--		endif()
--		if(ATLAS_LIBRARY)
--			get_filename_component(ATLAS_LIBRARY_PATH ${ATLAS_LIBRARY} PATH )
--			find_file(CLAPACK_INCLUDES clapack.h 
--				PATHS
--				${ATLAS_LIBRARY_PATH} 
--				${ATLAS_LIBRARY_PATH}/../include
--				${ATLAS_LIBRARY_PATH}/../include/atlas
--				${ATLAS_LIBRARY_PATH}/../../include/atlas
--			)
--			get_filename_component(CLAPACK_INCLUDES ${CLAPACK_INCLUDES} PATH )
--			set(CBLAS_INCLUDES ${CBLAS_INCLUDES} ${CLAPACK_INCLUDES})
--		endif()
--
--		if( OPENBLAS_LIBRARY AND CBLAS_INCLUDES)
--			set(CBLAS_VENDOR "OpenBLAS")
--			set(CBLAS_LIBRARIES ${OPENBLAS_LIBRARY})
--		elseif( CBLAS_LIBRARY AND CLAPACK_LIBRARY AND ATLAS_LIBRARY AND CBLAS_INCLUDES)
--			set(CBLAS_VENDOR "ATLAS")
--			set(CBLAS_LIBRARIES ${CLAPACK_LIBRARY} ${CBLAS_LIBRARY} ${ATLAS_LIBRARY})
--		elseif( CBLAS_LIBRARY AND CBLAS_INCLUDES)
--			#check that we can compile a basic program with the libraries we have found
--			#vendor versions might come with additional libraries which would be bad.
--			try_compile(CBLAS_COMPILE 
--				"${PROJECT_BINARY_DIR}/cBlasCheck"
--				"${CMAKE_SOURCE_DIR}/cBlasCheck.cpp"
--				CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CBLAS_INCLUDES}"
--				LINK_LIBRARIES ${CBLAS_LIBRARY}
--			)
--			if(CBLAS_COMPILE)
--				set(CBLAS_VENDOR "GENERIC")
--				set(CBLAS_LIBRARIES ${CBLAS_LIBRARY})
--			else()
--				message(WARNING "Unknown CBLAS. Can not use it")
--			endif()
--		endif()
--	endif()
-+  set(CBLAS_VENDOR FALSE)
-+  if( APPLE )
-+    set(CBLAS_VENDOR "Accelerate")
-+    set(CBLAS_INCLUDES "")
-+    set(CBLAS_LIBRARIES "-framework Accelerate" )
-+  else()
-+    #todo: do a propper vendor check
-+    find_library(OPENBLAS_LIBRARY openblas
-+      HINTS ${CBLAS_ROOT}/lib /opt/local/lib
-+      )
-+    find_library(CBLAS_LIBRARY cblas
-+      HINTS ${ATLAS_ROOT}/lib ${CBLAS_ROOT}/lib /opt/local/lib /usr/lib64/atlas/
-+      )
-+    find_library(CLAPACK_LIBRARY lapack
-+      HINTS ${ATLAS_ROOT}/lib ${CBLAS_ROOT}/lib /opt/local/lib /usr/lib64/atlas/
-+      )
-+    find_library(ATLAS_LIBRARY atlas
-+      HINTS ${ATLAS_ROOT}/lib ${CBLAS_ROOT}/lib /opt/local/lib /usr/lib64/atlas/
-+      )
-+    mark_as_advanced(
-+      OPENBLAS_LIBRARY
-+      CBLAS_LIBRARY
-+      CLAPACK_LIBRARY
-+      ATLAS_LIBRARY
-+      )
-+    #find the cblas.h include path
-+    if(CBLAS_LIBRARY )
-+      get_filename_component(CBLAS_LIB_PATH ${CBLAS_LIBRARY} PATH )
-+    elseif( OPENBLAS_LIBRARY)	
-+      get_filename_component(CBLAS_LIB_PATH ${OPENBLAS_LIBRARY} PATH )
-+    endif()
-+    if(CBLAS_LIB_PATH)
-+      find_file(CBLAS_INCLUDES cblas.h 
-+	PATHS ${CBLAS_LIB_PATH} ${CBLAS_LIB_PATH}/../include
-+	)
-+      get_filename_component(CBLAS_INCLUDES ${CBLAS_INCLUDES} PATH )
-+    endif()
-+    if(ATLAS_LIBRARY)
-+      get_filename_component(ATLAS_LIBRARY_PATH ${ATLAS_LIBRARY} PATH )
-+      find_file(CLAPACK_INCLUDES clapack.h 
-+	PATHS
-+	${ATLAS_LIBRARY_PATH} 
-+	${ATLAS_LIBRARY_PATH}/../include
-+	${ATLAS_LIBRARY_PATH}/../include/atlas
-+	${ATLAS_LIBRARY_PATH}/../../include/atlas
-+	)
-+      get_filename_component(CLAPACK_INCLUDES ${CLAPACK_INCLUDES} PATH )
-+      set(CBLAS_INCLUDES ${CBLAS_INCLUDES} ${CLAPACK_INCLUDES})
-+    endif()
-+
-+    if( OPENBLAS_LIBRARY AND CBLAS_INCLUDES)
-+      set(CBLAS_VENDOR "OpenBLAS")
-+      set(CBLAS_LIBRARIES ${OPENBLAS_LIBRARY})
-+    elseif( CBLAS_LIBRARY AND CLAPACK_LIBRARY AND ATLAS_LIBRARY AND CBLAS_INCLUDES)
-+      set(CBLAS_VENDOR "ATLAS")
-+      set(CBLAS_LIBRARIES ${CLAPACK_LIBRARY} ${CBLAS_LIBRARY} ${ATLAS_LIBRARY})
-+    elseif( CBLAS_LIBRARY AND CBLAS_INCLUDES)
-+      #check that we can compile a basic program with the libraries we have found
-+      #vendor versions might come with additional libraries which would be bad.
-+      try_compile(CBLAS_COMPILE 
-+	"${PROJECT_BINARY_DIR}/cBlasCheck"
-+	"${CMAKE_SOURCE_DIR}/cBlasCheck.cpp"
-+	CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CBLAS_INCLUDES}"
-+	LINK_LIBRARIES ${CBLAS_LIBRARY}
-+	)
-+      if(CBLAS_COMPILE)
-+	set(CBLAS_VENDOR "GENERIC")
-+	set(CBLAS_LIBRARIES ${CBLAS_LIBRARY})
-+      else()
-+	message(WARNING "Unknown CBLAS. Can not use it")
-+      endif()
-+    endif()
-+  endif()
- 	
--	if(CBLAS_VENDOR)
--		message(STATUS "CBLAS FOUND: " ${CBLAS_VENDOR} " with include directory " ${CBLAS_INCLUDES} )
--		set(SHARK_USE_CBLAS 1)
--		list(APPEND EXTRA_INCLUDE_DIRECTORIES ${CBLAS_INCLUDES} )
--		list(APPEND LINK_LIBRARIES ${CBLAS_LIBRARIES})
--		include_directories ( ${CBLAS_INCLUDES} )
--	else()
--		message(STATUS "No usable CBLAS Library found. No fast linear Algebra used.")
--	endif()
-+  if(CBLAS_VENDOR)
-+    message(STATUS "CBLAS FOUND: " ${CBLAS_VENDOR} " with include directory " ${CBLAS_INCLUDES} )
-+    set(SHARK_USE_CBLAS 1)
-+    list(APPEND EXTRA_INCLUDE_DIRECTORIES ${CBLAS_INCLUDES} )
-+    list(APPEND LINK_LIBRARIES ${CBLAS_LIBRARIES})
-+    include_directories ( ${CBLAS_INCLUDES} )
-+  else()
-+    message(STATUS "No usable CBLAS Library found. No fast linear Algebra used.")
-+  endif()
- 	
--	#Special setup for ATLAS
--	if( CBLAS_VENDOR MATCHES "ATLAS" )
--		set( SHARK_USE_ATLAS_LAPACK 1) # ATLAS always contains some LAPACK methods that we can use
-+  #Special setup for ATLAS
-+  if( CBLAS_VENDOR MATCHES "ATLAS" )
-+    set( SHARK_USE_ATLAS_LAPACK 1) # ATLAS always contains some LAPACK methods that we can use
- 		
--		#check for full lapack
--		set(CMAKE_REQUIRE_QUIET 1)
--		set(CMAKE_REQUIRED_LIBRARIES ${CBLAS_LIBRARIES})
--		check_function_exists(dsyev_ ATLAS_FULL_LAPACK)
-+    #check for full lapack
-+    set(CMAKE_REQUIRE_QUIET 1)
-+    set(CMAKE_REQUIRED_LIBRARIES ${CBLAS_LIBRARIES})
-+    check_function_exists(dsyev_ ATLAS_FULL_LAPACK)
- 		
--		if( ATLAS_FULL_LAPACK )
--			set( SHARK_USE_LAPACK 1)
--			message(STATUS "Detected ATLAS with full LAPACK package. Using it!")
--		endif()
--	endif()
-+    if( ATLAS_FULL_LAPACK )
-+      set( SHARK_USE_LAPACK 1)
-+      message(STATUS "Detected ATLAS with full LAPACK package. Using it!")
-+    endif()
-+  endif()
- endif()
- #####################################################################
- #                       Static Code Analysis
diff --git a/SuperBuild/patches/TIFF/CMakeLists.txt b/SuperBuild/patches/TIFF/CMakeLists.txt
deleted file mode 100644
index 287ba9ceba8ccc92673fcc929496438f557a6050..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/TIFF/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Copyright (C) 2005-2017 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.
-#
-
-cmake_minimum_required(VERSION 2.8.3)
-
-project(tiff_install)
-
-file(GLOB ${PROJECT_NAME}_HEADERS "${TIFF_BUILD_DIR}/tif*.h" )
-file(GLOB ${PROJECT_NAME}_LIBS "${TIFF_BUILD_DIR}/libtiff*.lib" )
-file(GLOB ${PROJECT_NAME}_DLLS "${TIFF_BUILD_DIR}/libtiff*.dll" )
-
-foreach(${PROJECT_NAME}_HEADER ${${PROJECT_NAME}_HEADERS})
-install(FILES ${${PROJECT_NAME}_HEADER}
-  DESTINATION include
-  COMPONENT Development)
-endforeach()
-  
-foreach(${PROJECT_NAME}_LIB ${${PROJECT_NAME}_LIBS})
-install(FILES ${${PROJECT_NAME}_LIB}
-  DESTINATION lib
-  COMPONENT Development)
-endforeach()
-
-foreach(${PROJECT_NAME}_DLL ${${PROJECT_NAME}_DLLS})
-install(FILES ${${PROJECT_NAME}_DLL}
-  DESTINATION bin
-  COMPONENT Development)
-endforeach()
\ No newline at end of file
diff --git a/SuperBuild/patches/TIFF/nmake.opt b/SuperBuild/patches/TIFF/nmake.opt
deleted file mode 100644
index cb1c9ea849db145f3ce36c0e00aeeecfaa6ea0ff..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/TIFF/nmake.opt
+++ /dev/null
@@ -1,218 +0,0 @@
-# $Id: nmake.opt,v 1.18 2006/06/07 16:33:45 dron Exp $
-#
-# Copyright (C) 2004, Andrey Kiselev <dron@ak4719.spb.edu>
-#
-# Permission to use, copy, modify, distribute, and sell this software and 
-# its documentation for any purpose is hereby granted without fee, provided
-# that (i) the above copyright notices and this permission notice appear in
-# all copies of the software and related documentation, and (ii) the names of
-# Sam Leffler and Silicon Graphics may not be used in any advertising or
-# publicity relating to the software without the specific, prior written
-# permission of Sam Leffler and Silicon Graphics.
-# 
-# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
-# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
-# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
-# 
-# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
-# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
-# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
-# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
-# OF THIS SOFTWARE.
-
-# Compile time parameters for MS Visual C++ compiler.
-# You may edit this file to specify building options.
-
-#
-###### Edit the following lines to choose a feature set you need. #######
-#
-
-# 
-# Select WINMODE_CONSOLE to build a library which reports errors to stderr, or
-# WINMODE_WINDOWED to build such that errors are reported via MessageBox().
-#
-WINMODE_CONSOLE = 1
-#WINMODE_WINDOWED = 1
-
-#
-# Comment out the following lines to disable internal codecs.
-#
-# Support for CCITT Group 3 & 4 algorithms
-CCITT_SUPPORT	= 1
-# Support for Macintosh PackBits algorithm
-PACKBITS_SUPPORT = 1
-# Support for LZW algorithm
-LZW_SUPPORT	= 1
-# Support for ThunderScan 4-bit RLE algorithm
-THUNDER_SUPPORT	= 1
-# Support for NeXT 2-bit RLE algorithm
-NEXT_SUPPORT	= 1
-# Support for LogLuv high dynamic range encoding
-LOGLUV_SUPPORT	= 1
-
-#
-# Uncomment and edit following lines to enable JPEG support.
-#
-JPEG_SUPPORT = 1
-JPEGDIR 	 = @CMAKE_WIN_INSTALL_PREFIX@
-JPEG_INCLUDE = -I$(JPEGDIR)\include
-JPEG_LIB 	 = $(JPEGDIR)\lib\jpeg.lib
-
-#
-# Uncomment and edit following lines to enable ZIP support
-# (required for Deflate compression and Pixar log-format)
-#
-ZIP_SUPPORT	 = 1
-ZLIBDIR 	 = @CMAKE_WIN_INSTALL_PREFIX@
-ZLIB_INCLUDE = -I$(ZLIBDIR)\include
-ZLIB_LIB 	 = $(ZLIBDIR)\lib\zlib.lib
-
-#
-# Uncomment and edit following lines to enable ISO JBIG support
-#
-#JBIG_SUPPORT	= 1
-#JBIGDIR 	= d:/projects/jbigkit
-#JBIG_INCLUDE	= -I$(JBIGDIR)/libjbig
-#JBIG_LIB 	= $(JBIGDIR)/libjbig/jbig.lib
-
-#
-# Uncomment following line to enable Pixar log-format algorithm
-# (Zlib required).
-#
-#PIXARLOG_SUPPORT = 1
-
-#
-# Comment out the following lines to disable strip chopping
-# (whether or not to convert single-strip uncompressed images to mutiple
-# strips of specified size to reduce memory usage). Default strip size
-# is 8192 bytes, it can be configured via the STRIP_SIZE_DEFAULT parameter
-#
-STRIPCHOP_SUPPORT = 1
-STRIP_SIZE_DEFAULT = 8192
-
-#
-# Comment out the following lines to disable treating the fourth sample with
-# no EXTRASAMPLE_ value as being ASSOCALPHA. Many packages produce RGBA
-# files but don't mark the alpha properly.
-#
-EXTRASAMPLE_AS_ALPHA_SUPPORT = 1
-
-#
-# Comment out the following lines to disable picking up YCbCr subsampling
-# info from the JPEG data stream to support files lacking the tag.
-# See Bug 168 in Bugzilla, and JPEGFixupTestSubsampling() for details.
-#
-CHECK_JPEG_YCBCR_SUBSAMPLING = 1
-
-#
-####################### Compiler related options. #######################
-#
-
-#
-# Pick debug or optimized build flags.  We default to an optimized build
-# with no debugging information.
-# NOTE: /EHsc option required if you want to build the C++ stream API
-#
-OPTFLAGS =	/Ox /MD /EHsc /W3 /D_CRT_SECURE_NO_DEPRECATE -DHAVE_SNPRINTF
-#OPTFLAGS = 	/Zi 
-
-#
-# Uncomment following line to enable using Windows Common RunTime Library
-# instead of Windows specific system calls. See notes on top of tif_unix.c
-# module for details.
-#
-USE_WIN_CRT_LIB = 1
-
-# Compiler specific options. You may probably want to adjust compilation
-# parameters in CFLAGS variable. Refer to your compiler documentation
-# for the option reference.
-#
-MAKE	=	nmake /nologo
-CC	=	cl /nologo
-CXX	=	cl /nologo
-AR	=	lib /nologo
-LD	=	link /nologo
-
-CFLAGS  =	$(OPTFLAGS) $(INCL) $(EXTRAFLAGS)
-CXXFLAGS =	$(OPTFLAGS) $(INCL) $(EXTRAFLAGS)
-EXTRAFLAGS =
-LIBS	=
-
-# Name of the output shared library
-DLLNAME	= libtiff.dll
-
-#
-########### There is nothing to edit below this line normally. ###########
-#
-
-# Set the native cpu bit order
-EXTRAFLAGS	= -DFILLODER_LSB2MSB $(EXTRAFLAGS)
-
-!IFDEF WINMODE_WINDOWED
-EXTRAFLAGS	= -DTIF_PLATFORM_WINDOWED $(EXTRAFLAGS)
-LIBS		= user32.lib $(LIBS)
-!ELSE
-EXTRAFLAGS	= -DTIF_PLATFORM_CONSOLE $(EXTRAFLAGS)
-!ENDIF
-
-# Codec stuff
-!IFDEF CCITT_SUPPORT
-EXTRAFLAGS	= -DCCITT_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF PACKBITS_SUPPORT
-EXTRAFLAGS	= -DPACKBITS_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF LZW_SUPPORT
-EXTRAFLAGS	=  -DLZW_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF THUNDER_SUPPORT
-EXTRAFLAGS	= -DTHUNDER_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF NEXT_SUPPORT
-EXTRAFLAGS	= -DNEXT_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF LOGLUV_SUPPORT
-EXTRAFLAGS	= -DLOGLUV_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF JPEG_SUPPORT
-LIBS		= $(LIBS) $(JPEG_LIB)
-EXTRAFLAGS	= -DJPEG_SUPPORT -DOJPEG_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF ZIP_SUPPORT
-LIBS		= $(LIBS) $(ZLIB_LIB)
-EXTRAFLAGS	= -DZIP_SUPPORT $(EXTRAFLAGS)
-!IFDEF PIXARLOG_SUPPORT
-EXTRAFLAGS	= -DPIXARLOG_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-!ENDIF
-
-!IFDEF JBIG_SUPPORT
-LIBS		= $(LIBS) $(JBIG_LIB)
-EXTRAFLAGS	= -DJBIG_SUPPORT $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF STRIPCHOP_SUPPORT
-EXTRAFLAGS	= -DSTRIPCHOP_DEFAULT=TIFF_STRIPCHOP -DSTRIP_SIZE_DEFAULT=$(STRIP_SIZE_DEFAULT) $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF EXTRASAMPLE_AS_ALPHA_SUPPORT
-EXTRAFLAGS	= -DDEFAULT_EXTRASAMPLE_AS_ALPHA $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF CHECK_JPEG_YCBCR_SUBSAMPLING
-EXTRAFLAGS	= -DCHECK_JPEG_YCBCR_SUBSAMPLING $(EXTRAFLAGS)
-!ENDIF
-
-!IFDEF USE_WIN_CRT_LIB
-EXTRAFLAGS	= -DAVOID_WIN32_FILEIO $(EXTRAFLAGS)
-!ELSE
-EXTRAFLAGS	= -DUSE_WIN32_FILEIO $(EXTRAFLAGS)
-!ENDIF
diff --git a/SuperBuild/patches/TIFF/tiff-1-cmakefixes-all.diff b/SuperBuild/patches/TIFF/tiff-1-cmakefixes-all.diff
new file mode 100644
index 0000000000000000000000000000000000000000..a0c3b6f08bcaa234f96f07d266cf1bdbaae189bc
--- /dev/null
+++ b/SuperBuild/patches/TIFF/tiff-1-cmakefixes-all.diff
@@ -0,0 +1,163 @@
+diff -burN tiff-4.0.8.orig/CMakeLists.txt tiff-4.0.8/CMakeLists.txt
+--- tiff-4.0.8.orig/CMakeLists.txt	Thu Jul 20 12:53:54 2017
++++ tiff-4.0.8/CMakeLists.txt	Thu Jul 20 13:17:05 2017
+@@ -601,21 +601,35 @@
+   set(CXX_SUPPORT TRUE)
+ endif()
+ 
+-# OpenGL and GLUT
+-find_package(OpenGL)
+-find_package(GLUT)
+-set(HAVE_OPENGL FALSE)
+-if(OPENGL_FOUND AND OPENGL_GLU_FOUND AND GLUT_FOUND)
++# OpenGL support
++option(with_opengl "Enable opengl support (requires opengl and glut packages)" ON)
++if(with_opengl)
++  # OpenGL and GLUT
++  find_package(OpenGL)
++  find_package(GLUT)
++  set(HAVE_OPENGL FALSE)
++  if(OPENGL_FOUND AND OPENGL_GLU_FOUND AND GLUT_FOUND)
+   set(HAVE_OPENGL TRUE)
+-endif()
+-# Purely to satisfy the generated headers:
+-check_include_file(GL/gl.h HAVE_GL_GL_H)
+-check_include_file(GL/glu.h HAVE_GL_GLU_H)
+-check_include_file(GL/glut.h HAVE_GL_GLUT_H)
+-check_include_file(GLUT/glut.h HAVE_GLUT_GLUT_H)
+-check_include_file(OpenGL/gl.h HAVE_OPENGL_GL_H)
+-check_include_file(OpenGL/glu.h HAVE_OPENGL_GLU_H)
++  endif()
++  # Purely to satisfy the generated headers:
++  check_include_file(GL/gl.h HAVE_GL_GL_H)
++  check_include_file(GL/glu.h HAVE_GL_GLU_H)
++  check_include_file(GL/glut.h HAVE_GL_GLUT_H)
++  check_include_file(GLUT/glut.h HAVE_GLUT_GLUT_H)
++  check_include_file(OpenGL/gl.h HAVE_OPENGL_GL_H)
++  check_include_file(OpenGL/glu.h HAVE_OPENGL_GLU_H)
++else() #with_opengl
++  set(HAVE_OPENGL FALSE)
++  #force  opengl headers check to FALSE.
++  set(HAVE_GL_GL_H FALSE)
++  set(HAVE_GL_GLU_H FALSE)
++  set(HAVE_GL_GLUT_H FALSE)
++  set(HAVE_GLUT_GLUT_H FALSE)
++  set(HAVE_OPENGL_GL_H FALSE)
++  set(HAVE_OPENGL_GLU_H FALSE)
++endif() #with_opengl
+ 
++
+ # Win32 IO
+ set(win32_io FALSE)
+ if(WIN32)
+@@ -713,19 +727,38 @@
+ if(LIBLZMA_LIBRARIES)
+   list(APPEND TIFF_LIBRARY_DEPS ${LIBLZMA_LIBRARIES})
+ endif()
+-
+ #report_values(TIFF_INCLUDES TIFF_LIBRARY_DEPS)
+ 
++# NEED_LIBPORT is later updated in port/CMakeLists.txt and 
++# used in libtiff/CMakeLists.txt to generate tif_config.h.
++# see libtiff/tif_config.h.cmake.in for usage
++set(NEED_LIBPORT FALSE)
++
+ # Process subdirectories
+ add_subdirectory(port)
+ add_subdirectory(libtiff)
+-add_subdirectory(tools)
+-add_subdirectory(test)
+-add_subdirectory(contrib)
++
++option(with_tools "build executables in tools directory" ON)
++if(with_tools)
++  add_subdirectory(tools)
++endif()
++option(with_test "build executables in tests directory" ON)
++if(with_test)
++  add_subdirectory(test)
++endif()
++
++option(with_contrib "build executables in contrib directory" ON)
++if(with_contrib)
++  add_subdirectory(contrib)
++endif()
++
+ add_subdirectory(build)
+-add_subdirectory(man)
+-add_subdirectory(html)
+-
++
++option(with_docs "build html and man docs" ON)
++if(with_docs)
++  add_subdirectory(man)
++  add_subdirectory(html)
++endif()
+ #message(STATUS "EXTRA_DIST: ${EXTRA_DIST}")
+ 
+ message(STATUS "")
+diff -burN tiff-4.0.8.orig/contrib/iptcutil/iptcutil.c tiff-4.0.8/contrib/iptcutil/iptcutil.c
+--- tiff-4.0.8.orig/contrib/iptcutil/iptcutil.c	Thu Jul 20 12:53:54 2017
++++ tiff-4.0.8/contrib/iptcutil/iptcutil.c	Thu Jul 20 13:14:55 2017
+@@ -19,7 +19,7 @@
+ # include <fcntl.h>
+ #endif
+ 
+-#ifdef WIN32
++#ifdef _MSC_VER
+ #define STRNICMP strnicmp
+ #else 
+ #define STRNICMP strncasecmp
+diff -burN tiff-4.0.8.orig/libtiff/tif_config.h.cmake.in tiff-4.0.8/libtiff/tif_config.h.cmake.in
+--- tiff-4.0.8.orig/libtiff/tif_config.h.cmake.in	Thu Jul 20 12:53:54 2017
++++ tiff-4.0.8/libtiff/tif_config.h.cmake.in	Thu Jul 20 13:15:21 2017
+@@ -259,3 +259,9 @@
+ 
+ /* Define to `unsigned int' if <sys/types.h> does not define. */
+ #undef size_t
++
++#ifdef _MSC_VER
++#pragma warning(disable : 4996) /* function deprecation warnings */
++#endif
++
++#cmakedefine NEED_LIBPORT 1
+diff -burN tiff-4.0.8.orig/port/CMakeLists.txt tiff-4.0.8/port/CMakeLists.txt
+--- tiff-4.0.8.orig/port/CMakeLists.txt	Thu Jul 20 12:53:54 2017
++++ tiff-4.0.8/port/CMakeLists.txt	Thu Jul 20 13:15:32 2017
+@@ -32,25 +32,35 @@
+   strtoull.c)
+ 
+ set(port_USED_FILES ${port_SOURCES} ${port_HEADERS})
+-
++  set(LIBPORT_USED FALSE)
+ if(NOT HAVE_GETOPT)
+   list(APPEND port_USED_FILES getopt.c)
++    set(LIBPORT_USED TRUE)
+ endif()
+ if(NOT HAVE_LFIND)
+   list(APPEND port_USED_FILES lfind.c)
++    set(LIBPORT_USED TRUE)
+ endif()
+ if(MSVC AND NOT HAVE_SNPRINTF)
+   list(APPEND port_USED_FILES snprintf.c)
++    set(LIBPORT_USED TRUE)
+ endif()
+ if(NOT HAVE_STRCASECMP)
+   list(APPEND port_USED_FILES strcasecmp.c)
++    set(LIBPORT_USED TRUE)
+ endif()
+ if(NOT HAVE_STRTOUL)
+   list(APPEND port_USED_FILES strtoul.c)
++    set(LIBPORT_USED TRUE)
+ endif()
+ if(NOT HAVE_STRTOULL)
+   list(APPEND port_USED_FILES strtoull.c)
++  set(LIBPORT_USED TRUE)
+ endif()
++
++# We set NEED_LIBPORT with PARENT_SCOPE 
++# because it is used in libtiff/CMakeLists.txt
++set(NEED_LIBPORT ${LIBPORT_USED} PARENT_SCOPE)
+ 
+ add_library(port STATIC ${port_USED_FILES})
+ 
diff --git a/SuperBuild/patches/TIFF/tiff-1-noopengl-linux.diff b/SuperBuild/patches/TIFF/tiff-1-noopengl-linux.diff
deleted file mode 100755
index 04b1ef4f181fe243c5d9413e76a129e57981689d..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/TIFF/tiff-1-noopengl-linux.diff
+++ /dev/null
@@ -1,38 +0,0 @@
-diff -burN tiff-4.0.6.orig/CMakeLists.txt tiff-4.0.6/CMakeLists.txt
---- tiff-4.0.6.orig/CMakeLists.txt	2016-10-27 17:24:17.000000000 +0200
-+++ tiff-4.0.6/CMakeLists.txt	2016-10-27 17:25:43.000000000 +0200
-@@ -602,19 +602,23 @@
- endif()
- 
- # OpenGL and GLUT
--find_package(OpenGL)
--find_package(GLUT)
--set(HAVE_OPENGL FALSE)
--if(OPENGL_FOUND AND OPENGL_GLU_FOUND AND GLUT_FOUND)
-+option(WITH_OPENGL "Enable opengl and glut support" ON)
-+
-+if(WITH_OPENGL)  
-+  find_package(OpenGL)
-+  find_package(GLUT)
-+  set(HAVE_OPENGL FALSE)
-+  if(OPENGL_FOUND AND OPENGL_GLU_FOUND AND GLUT_FOUND)
-   set(HAVE_OPENGL TRUE)
-+  endif()
-+  # Purely to satisfy the generated headers:
-+  check_include_file(GL/gl.h HAVE_GL_GL_H)
-+  check_include_file(GL/glu.h HAVE_GL_GLU_H)
-+  check_include_file(GL/glut.h HAVE_GL_GLUT_H)
-+  check_include_file(GLUT/glut.h HAVE_GLUT_GLUT_H)
-+  check_include_file(OpenGL/gl.h HAVE_OPENGL_GL_H)
-+  check_include_file(OpenGL/glu.h HAVE_OPENGL_GLU_H)
- endif()
--# Purely to satisfy the generated headers:
--check_include_file(GL/gl.h HAVE_GL_GL_H)
--check_include_file(GL/glu.h HAVE_GL_GLU_H)
--check_include_file(GL/glut.h HAVE_GL_GLUT_H)
--check_include_file(GLUT/glut.h HAVE_GLUT_GLUT_H)
--check_include_file(OpenGL/gl.h HAVE_OPENGL_GL_H)
--check_include_file(OpenGL/glu.h HAVE_OPENGL_GLU_H)
- 
- # Win32 IO
- set(win32_io FALSE)
diff --git a/SuperBuild/patches/TIFF/tiff-1-noopengl-macx.diff b/SuperBuild/patches/TIFF/tiff-1-noopengl-macx.diff
deleted file mode 100755
index 04b1ef4f181fe243c5d9413e76a129e57981689d..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/TIFF/tiff-1-noopengl-macx.diff
+++ /dev/null
@@ -1,38 +0,0 @@
-diff -burN tiff-4.0.6.orig/CMakeLists.txt tiff-4.0.6/CMakeLists.txt
---- tiff-4.0.6.orig/CMakeLists.txt	2016-10-27 17:24:17.000000000 +0200
-+++ tiff-4.0.6/CMakeLists.txt	2016-10-27 17:25:43.000000000 +0200
-@@ -602,19 +602,23 @@
- endif()
- 
- # OpenGL and GLUT
--find_package(OpenGL)
--find_package(GLUT)
--set(HAVE_OPENGL FALSE)
--if(OPENGL_FOUND AND OPENGL_GLU_FOUND AND GLUT_FOUND)
-+option(WITH_OPENGL "Enable opengl and glut support" ON)
-+
-+if(WITH_OPENGL)  
-+  find_package(OpenGL)
-+  find_package(GLUT)
-+  set(HAVE_OPENGL FALSE)
-+  if(OPENGL_FOUND AND OPENGL_GLU_FOUND AND GLUT_FOUND)
-   set(HAVE_OPENGL TRUE)
-+  endif()
-+  # Purely to satisfy the generated headers:
-+  check_include_file(GL/gl.h HAVE_GL_GL_H)
-+  check_include_file(GL/glu.h HAVE_GL_GLU_H)
-+  check_include_file(GL/glut.h HAVE_GL_GLUT_H)
-+  check_include_file(GLUT/glut.h HAVE_GLUT_GLUT_H)
-+  check_include_file(OpenGL/gl.h HAVE_OPENGL_GL_H)
-+  check_include_file(OpenGL/glu.h HAVE_OPENGL_GLU_H)
- endif()
--# Purely to satisfy the generated headers:
--check_include_file(GL/gl.h HAVE_GL_GL_H)
--check_include_file(GL/glu.h HAVE_GL_GLU_H)
--check_include_file(GL/glut.h HAVE_GL_GLUT_H)
--check_include_file(GLUT/glut.h HAVE_GLUT_GLUT_H)
--check_include_file(OpenGL/gl.h HAVE_OPENGL_GL_H)
--check_include_file(OpenGL/glu.h HAVE_OPENGL_GLU_H)
- 
- # Win32 IO
- set(win32_io FALSE)
diff --git a/Utilities/Maintenance/SuperbuildDownloadList.sh b/Utilities/Maintenance/SuperbuildDownloadList.sh
index 6b09c62d4173125b529c295ed58ebea2bda67d7e..d7bd8c493517194cf2ef22accbc6b0e4565d3291 100755
--- a/Utilities/Maintenance/SuperbuildDownloadList.sh
+++ b/Utilities/Maintenance/SuperbuildDownloadList.sh
@@ -20,77 +20,62 @@
 #
 
 
-export LC_ALL=C
-if [ $# -eq 2 ]; then
-DOWNLOAD_DIR=$(readlink -f $1)
-OUTPUT_DIR=$(readlink -f $2)
-else
-echo 'Usage: '$0' <download_directory> <archive_output_directory>'
-exit 1
+
+if [ $# -lt 2 ]; then
+    echo "Usage: $0 <download_directory> <archive_output_directory>"
+    exit 1
 fi
 
-WGET="wget -nv -q"
+export LC_ALL=C
 
-SB_CMAKE_DIR_REL=$(dirname $0)/../../SuperBuild/CMake
-SB_CMAKE_DIR=$(readlink -f ${SB_CMAKE_DIR_REL})
+DOWNLOAD_DIR=$(readlink -f "$1")
+OUTPUT_DIR=$(readlink -f "$2")
+WGET=$(which wget)
 
-cd $(dirname $0)/../../
 
-GIT_BRANCH=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
+CUR_DIR="$( cd "$( dirname "$0" )" && pwd )"
 
+SB_CMAKE_DIR_REL=$CUR_DIR/../../SuperBuild/CMake
+SB_CMAKE_DIR=$(readlink -f "${SB_CMAKE_DIR_REL}")
+cd "$CUR_DIR/../../" || echo "cannot cd to CUR_DIR/../../"
+GIT_BRANCH=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
 #if a branch contains release-X.Y then xdk is taken from packages/xdk/OTB-X.Y
 if [[ "$GIT_BRANCH" =~ release-* ]]; then
-    VERSION=$(echo ${GIT_BRANCH}| sed 's/.*release-//'| cut -d'-' -f 1)
+    VERSION=$(echo "${GIT_BRANCH}"| sed 's/.*release-//'| cut -d'-' -f 1)
 else
     VERSION="develop"
 fi
-DOWNLOAD_LIST=$(grep -h -E "^[^#]*\"https?://.*(\.tar\.gz|\.tar\.bz2|\.tgz|\.tar\.xz|\.zip|export=download).*\"" ${SB_CMAKE_DIR}/*.cmake | grep -o -E "https?://[^\"]*" | sed "s/\/\(download\)\?$//" | sort | uniq)
+CMAKE_FILES=$(find $SB_CMAKE_DIR -maxdepth 1 -type f -name "External_*")
+DOWNLOAD_LIST=$(grep -h -E '^[^#]*\"https?://.*(\.tar\.gz|\.tar\.bz2|\.tgz|\.tar\.xz|\.zip|export=download).*\"' ${CMAKE_FILES} |
+		    grep -o -E 'https?://[^\"]*' | sort | uniq)
 
 DOWNLOAD_NAMES=
 
-mkdir -p ${DOWNLOAD_DIR}
-cd ${DOWNLOAD_DIR}
+#echo "DOWNLOAD_LIST=$DOWNLOAD_LIST"
 
+mkdir -p "${DOWNLOAD_DIR}"
+cd "${DOWNLOAD_DIR}" || echo "cannot cd to DOWNLOAD_DIR"
 echo "Downloading files to ${DOWNLOAD_DIR}/"
-
 for url in ${DOWNLOAD_LIST}; do
-  # clean log file
-
-  file_name=$(echo "${url}" | grep -o -E "[^\/]+$")
-  docs_google=$(echo "${file_name}" | grep -F "export=download")
-  if [ "${docs_google}" = "" ]; then
-      if [ -f "$file_name" ]; then
-          echo "$file_name exists, skipping"
-      fi;
-      $WGET -N ${url}
-      ret="$?"
-   if [ $ret -gt 0 -a $ret -ne 8  ]; then
-       echo "Download failed for URL: '${url}'. wget finished with exit status '$ret'."
-       exit 1;
-   fi
-  else
-    # look into the original file for a valid download name
-    file_name=$(grep -h -A 3 -B 3 -F "${url}" ${SB_CMAKE_DIR}/*.cmake | grep -E "^[^#]*DOWNLOAD_NAME" | grep -o -E "[^ ]*\.(tar\.gz|tar\.bz2|tar\.xz|zip)" | uniq)
-    if [ -z "$file_name" ]; then
-        echo "Can't find correct filename for url ${url} : skip download"
-        exit 1;
-    else
-        # echo "Download ${file_name}..."
-        $WGET ${url} -O ${file_name}
-    fi
+  file_name=$(echo "${url}" | grep -o -E '[^\/]+$')
+  $WGET -N "${url}"
+  ret="$?"
+  if [ $ret -gt 0 ] && [ $ret -ne 8 ]; then
+     echo "Download failed for URL: '${url}'. wget finished with exit status '$ret'."
+     exit 1;
   fi
 
   if [ "$file_name" != "" ]; then
-      DOWNLOAD_NAMES="${DOWNLOAD_NAMES} ${file_name}"
+     DOWNLOAD_NAMES="${DOWNLOAD_NAMES} ${file_name}"
+  else
+     echo "invalid filename for url=${url}" && exit 1;
   fi
-
 done
 
 ARCHIVE_NAME="SuperBuild-archives-$VERSION"
 echo "Creating archive ${OUTPUT_DIR}/$ARCHIVE_NAME.tar.bz2"
-
-cd ${OUTPUT_DIR}
-tar -cjf $ARCHIVE_NAME.tar.bz2 -C ${DOWNLOAD_DIR} ${DOWNLOAD_NAMES}
-
+cd "${OUTPUT_DIR}" || echo "cannot cd to OUTPUT_DIR"
+touch "${DOWNLOAD_DIR}/OTBSuperBuild.readme"
+tar -cjf "$ARCHIVE_NAME.tar.bz2" -C "${DOWNLOAD_DIR}" ${DOWNLOAD_NAMES} OTBSuperBuild.readme
 echo "Saving md5sum to ${OUTPUT_DIR}/$ARCHIVE_NAME.md5"
-md5sum $ARCHIVE_NAME.tar.bz2 > $ARCHIVE_NAME.md5
+md5sum "$ARCHIVE_NAME.tar.bz2" > "$ARCHIVE_NAME.md5"