diff --git a/Documentation/Cookbook/Art/QtImages/rescale_documentation.png b/Documentation/Cookbook/Art/QtImages/rescale_documentation.png
deleted file mode 100644
index 70cea29e59f15f04ac7a8ccbf119aba372409c16..0000000000000000000000000000000000000000
Binary files a/Documentation/Cookbook/Art/QtImages/rescale_documentation.png and /dev/null differ
diff --git a/Documentation/Cookbook/Art/QtImages/rescale_logs.png b/Documentation/Cookbook/Art/QtImages/rescale_logs.png
deleted file mode 100644
index ed6abd8f90e348f63154d77c9b593a344df38bd6..0000000000000000000000000000000000000000
Binary files a/Documentation/Cookbook/Art/QtImages/rescale_logs.png and /dev/null differ
diff --git a/Documentation/Cookbook/Art/QtImages/rescale_param.png b/Documentation/Cookbook/Art/QtImages/rescale_param.png
index e3b9cff8ce3de5dc72fc386da55c34dc9040fada..bb235c7528fd6ac2ac52097ed01fc5f3db2c080e 100644
Binary files a/Documentation/Cookbook/Art/QtImages/rescale_param.png and b/Documentation/Cookbook/Art/QtImages/rescale_param.png differ
diff --git a/Documentation/Cookbook/Art/QtImages/rescale_progress.png b/Documentation/Cookbook/Art/QtImages/rescale_progress.png
deleted file mode 100644
index bedf4336133a201ddc550eceda4ef17600c7ccc8..0000000000000000000000000000000000000000
Binary files a/Documentation/Cookbook/Art/QtImages/rescale_progress.png and /dev/null differ
diff --git a/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in b/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
index ff3c204aa76e02eedb85f763d3a476f749d3c16c..1db3cde6aab86c666b516b5c7cde100f4ddada27 100644
--- a/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
+++ b/Documentation/Cookbook/CMake/RunApplicationsRstGenerator.sh.cmake.in
@@ -5,4 +5,4 @@
 export PYTHONPATH=@PYTHONPATH_COOKBOOK@:$PYTHONPATH
 export OTB_APPLICATION_PATH=@CMAKE_BINARY_DIR@/lib/otb/applications
 
-python3 @CMAKE_CURRENT_SOURCE_DIR@/Scripts/otbGenerateWrappersRstDoc.py -o "$1"
+python3 @CMAKE_CURRENT_SOURCE_DIR@/Scripts/otbGenerateWrappersRstDoc.py "$1"
diff --git a/Documentation/Cookbook/CMakeLists.txt b/Documentation/Cookbook/CMakeLists.txt
index 766102aab683e1727b8443e476e12b5f15eef865..ea309686b45bc86903ccde0896df068ec64a9fc1 100644
--- a/Documentation/Cookbook/CMakeLists.txt
+++ b/Documentation/Cookbook/CMakeLists.txt
@@ -120,6 +120,8 @@ set(OTB_COPYRIGHT_TEXT "${OTB_COPYRIGHT_YEAR} CNES.The OTB CookBook is licensed
 
 configure_file(${RST_SOURCE_DIR}/conf.py.in ${SPHINX_CONF_DIR}/conf.py @ONLY)
 
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/_static DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
 add_custom_target(generate_otbapps_rst
   COMMAND ${SH_INTERP} ${CMAKE_CURRENT_BINARY_DIR}/RunApplicationsRstGenerator.sh
   ${RST_BINARY_DIR}
@@ -142,7 +144,6 @@ add_custom_target(CookBookHTML
   -b html
   ${RST_BINARY_DIR}
   ${HTML_DIR}
-  -W
   -v
   -c ${SPHINX_CONF_DIR}
   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
@@ -163,7 +164,6 @@ add_custom_target(CookBookArchive
    -b latex
    ${RST_BINARY_DIR}
    ${LATEX_DIR}
-   -W
    -v
    -c ${SPHINX_CONF_DIR}
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
diff --git a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
index 7bb739bed0feff46340b2ba82c01a19525465858..b3bd9d0460bab2a4b52fdc3b4968a31c04c03311 100755
--- a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
+++ b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
@@ -19,40 +19,17 @@
 # limitations under the License.
 #
 
-import otbApplication
 import os
 import sys
-import glob
-from optparse import OptionParser
-
-##############################################################################
-# Parameters
-linesep = os.linesep
-pixeltypes = {' uchar' : 1, ' int8' : 0, ' uint8' : 1, ' int16' : 2, ' uint16': 3, ' int32' : 4, ' uint32' : 5, ' float' : 6, ' double': 7}
-
+import argparse
 import re
 
-#Special/Exceptional cases
-def RstifyDescription(s):
-    s = s.replace(':\n', ':\n\n')
-    s = s.replace('\n', ' ')
-    s = s.replace('*','\*')
-    if not len(s) == 0 and not s.endswith('.'):
-        s += '.'
-    return s
+import otbApplication
+from otbApplication import ParameterType_Bool, ParameterType_Int, ParameterType_Radius, ParameterType_RAM, ParameterType_Float, ParameterType_String, ParameterType_StringList, ParameterType_InputFilename, ParameterType_OutputFilename, ParameterType_InputImage, ParameterType_ComplexInputImage, ParameterType_OutputImage, ParameterType_ComplexOutputImage, ParameterType_InputVectorData, ParameterType_OutputVectorData, ParameterType_Directory, ParameterType_Choice, ParameterType_InputImageList, ParameterType_InputVectorDataList, ParameterType_InputFilenameList, ParameterType_InputProcessXML, ParameterType_OutputProcessXML, ParameterType_ListView, ParameterType_Group
 
-def ConvertString(s):
-    '''Convert a string for compatibility in txt dump'''
-    s = s.strip()
-    s = s.replace('*','\*')
-    return s
+from otb_warnings import application_documentation_warnings
 
-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
+linesep = os.linesep
 
 def EncloseString(s):
     if not s.startswith("\"") :
@@ -76,6 +53,7 @@ def ExpandPath(filename,path,exp):
         return os.path.join(path,filename)
 
 def GetPixelType(value):
+    pixeltypes = {' uchar' : 1, ' int8' : 0, ' uint8' : 1, ' int16' : 2, ' uint16': 3, ' int32' : 4, ' uint32' : 5, ' float' : 6, ' double': 7}
     # look for type
     foundcode = -1
     foundname = ""
@@ -86,437 +64,336 @@ def GetPixelType(value):
             break
     return foundcode,foundname
 
-def GetParametersDepth(paramlist):
-    depth = 0
-    for param in paramlist:
-        depth = max(param.count("."),depth)
-    return depth
-
-def GenerateChoice(app,param,paramlist, count = 0):
-    output = " Available choices are: " + linesep
-    spaces = ' ' * count
-    for (choicekey,choicename) in zip(app.GetChoiceKeys(param),app.GetChoiceNames(param)):
-        output += linesep + spaces + "- **"+ ConvertString(choicename) + "**"
-        choicedesc = app.GetParameterDescription(param+"."+choicekey)
-        if len(choicedesc) >= 2:
-            output+= " : " + ConvertString(choicedesc)
-        output += linesep + linesep
-        # List option associated to one choice
-        options = []
-        for p in paramlist:
-            if p.startswith(param+"."+choicekey+"."):
-                options.append(p)
-        if len(options) > 0:
-            count += 1
-            spaces = ' ' * count
-            for option in options:
-                output+= linesep + spaces + "- **"+ ConvertString(app.GetParameterName(option))+ "** : " + RstifyDescription(app.GetParameterDescription(option)) + linesep
-            output+= linesep
-    return output
-
-def GenerateParameterType(app,param):
-    if app.GetParameterType(param) == otbApplication.ParameterType_Empty \
-       or app.GetParameterType(param) == otbApplication.ParameterType_Bool:
-        return "Boolean"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Int \
-       or app.GetParameterType(param) == otbApplication.ParameterType_Radius \
-       or app.GetParameterType(param) == otbApplication.ParameterType_RAM:
-        return "Int"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Float:
-        return "Float"
-    if app.GetParameterType(param) == otbApplication.ParameterType_String:
-        return "String"
-    if app.GetParameterType(param) == otbApplication.ParameterType_StringList:
-        return "String list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputFilename :
-        return "Input File name"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputFilename :
-        return "Output File name"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Directory :
-        return "Directory"
-    if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-        return "Choices"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputImage \
-            or app.GetParameterType(param) == otbApplication.ParameterType_ComplexInputImage:
-        return "Input image"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputVectorData:
-        return "Input vector data"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputImage \
-            or app.GetParameterType(param) == otbApplication.ParameterType_ComplexOutputImage :
-        return "Output image"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputVectorData:
-        return "Output vector data"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputImageList:
-        return "Input image list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputVectorDataList:
-        return "Input vector data list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputFilenameList :
-        return "Input File name list"
-    if app.GetParameterType(param) == otbApplication.ParameterType_ListView:
-        if app.GetListViewSingleSelectionMode(param):
-            return "String"
-        else:
-            return "String List"
-    if app.GetParameterType(param) == otbApplication.ParameterType_Group:
-        return "Group"
-    if app.GetParameterType(param) == otbApplication.ParameterType_InputProcessXML:
-        return "XML input parameters file"
-    if app.GetParameterType(param) == otbApplication.ParameterType_OutputProcessXML:
-        return "XML output parameters file"
-
-def FindLengthOfLargestColumnText(app,paramlist):
-    output= ""
-    colLength = [2] * 3
-    for param in paramlist:
-        if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-            for (choicekey,choicename) in zip(app.GetChoiceKeys(param),app.GetChoiceNames(param)):
-                lenp= len(param + " " + choicekey)
-                if colLength[0] < lenp:
-                    colLength[0] = lenp
-                lenpdescr = len(choicename)
-                if colLength[1] < lenpdescr:
-                    colLength[1] = lenpdescr
-        else:
-            if colLength[0] < len(param):
-                colLength[0] = len(param)
-            lenpdescr = len(GenerateParameterType(app, param))
-            if colLength[2] < lenpdescr:
-                colLength[2] = lenpdescr
-        lenptype = len(app.GetParameterName(param))
-        if colLength[1] < lenptype:
-            colLength[1] = lenptype
-    return colLength
-
-def RstTableHeaderLine(strlist, listlen, delimiter):
-    line = "+"
-    for i in range(len(strlist)):
-        line += delimiter * listlen[i] + '+'
-    line += linesep
-    return line
-
-def RstTableHeading(strlist, listlen):
-    heading = RstTableHeaderLine(strlist, listlen, '-')
-    for i in range(len(strlist)):
-         spaces = ' ' * ((listlen[i] - len(strlist[i])) )
-         heading += '|' + strlist[i] +  spaces
-    heading += '|' + linesep
-    heading += RstTableHeaderLine(strlist, listlen, '=')
-    return heading
-
-def MakeText(text, size):
-    dsize = (size - len(text))
-    output= '|' + text  + ' ' * (dsize)
-    return output
-
-def GenerateParametersTable(app,paramlist):
-    colLength = FindLengthOfLargestColumnText(app, paramlist)
-    output = linesep + ".. [#] Table: Parameters table for " + ConvertString(app.GetDocName()) + "." + linesep + linesep
-    headerlist = ["Parameter Key", "Parameter Name", "Parameter Type"]
-    for i in range(len(headerlist)):
-        colLength[i] = len(headerlist[i]) if colLength[i] < len(headerlist[i]) else colLength[i]
-    output += RstTableHeading(headerlist, colLength)
-    for param in paramlist:
-        output += MakeText(param, colLength[0])
-        output += MakeText(app.GetParameterName(param), colLength[1])
-        output += MakeText(GenerateParameterType(app, param), colLength[2])
-        output += '|' + linesep
-        output += RstTableHeaderLine(headerlist, colLength, '-')
-        if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-            for (choicekey,choicename) in zip(app.GetChoiceKeys(param),app.GetChoiceNames(param)):
-                output += MakeText(param + " " + choicekey, colLength[0])
-                output += MakeText(choicename,colLength[1])
-                output += MakeText(" *Choice*", colLength[2])
-                output += '|' + linesep
-                output += RstTableHeaderLine(headerlist, colLength, '-')
-    return output
-
-def unique(seq):
-    # order preserving
-    checked = []
-    for e in seq:
-        if e not in checked:
-            checked.append(e)
-    return checked
-
-def ApplicationParametersToRst(app,paramlist,deep = False,current=""):
-    output = ""
-    # First run
-    if len(current)==0:
-        output += "This section describes in details the parameters available for this application. Table [#]_ presents a summary of these parameters and the parameters keys to be used in command-line and programming languages. Application key is *" + app.GetName() + "* ."  + linesep
-        output += GenerateParametersTable(app,paramlist)
-        firstlevelparams = []
-        for param in paramlist:
-            paramsplit = param.partition(".")
-            firstlevelparams.append(paramsplit[0])
-        firstlevelparams = unique(firstlevelparams)
-
-        if deep:
-            for param in firstlevelparams:
-                output += linesep
-                output += "**" + ConvertString(app.GetParameterName(param)) + "**" + linesep
-                output += RstifyDescription(app.GetParameterDescription(param))
-                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                    output += GenerateChoice(app,param,paramlist)
-                    output += linesep
-                else:
-                    output += linesep
-                    output += ApplicationParametersToRst(app,paramlist,deep,param)
-        else:
-            output+= linesep
-            for param in firstlevelparams:
-                output+= "- **"+ ConvertString(app.GetParameterName(param))+ ":** " + RstifyDescription(app.GetParameterDescription(param))
-                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                    output += GenerateChoice(app,param,paramlist)
-                output += linesep + linesep
-            output+=  linesep
-    else:
-        currentlevelparams = []
-        for param in paramlist:
-            if param.startswith(current+".") and param.count(".") == current.count(".")+1:
-                currentlevelparams.append(param)
-        if len(currentlevelparams) > 0:
-            output+= linesep
-            for param in currentlevelparams:
-                output+= "- **"+ ConvertString(app.GetParameterName(param))+ ":** " + RstifyDescription(app.GetParameterDescription(param)) + linesep
-                output+= ApplicationParametersToRst(app,paramlist,deep,param) + linesep
-                if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                    output += GenerateChoice(app,param,paramlist, 1)
-            output+= linesep
-
-    return output
-
-def ApplicationParametersToRstV2(app,paramlist,deep = False,current=""):
+def GetApplicationExamplePythonSnippet(app,idx,expand = False, inputpath="",outputpath=""):
+    appname = "app"
     output = ""
-    # current level
-    level = 0
-    # First run
-    if len(current)==0:
-        output += "This section describes in details the parameters available for this application. Table [#]_ presents a summary of these parameters and the parameters keys to be used in command-line and programming languages. Application key is *" + app.GetName() + "* ."  + linesep
-        output += GenerateParametersTable(app,paramlist)
-    else:
-        level = len(current.split('.'))
-    indentLevel = level
-    if deep == False:
-        indentLevel += 1
-    # compute prefix
-    bulletStyle = "-*+"
-    prefix = ""
-    if indentLevel > 0:
-        prefix = (' ' * (indentLevel-1)) + bulletStyle[(indentLevel-1)%3] + ' '
-    # find parameter for current param
-    currentlevelparams = []
-    for param in paramlist:
-        if param.startswith(current) and len(param.split('.')) == level+1:
-            currentlevelparams.append(param)
-    if len(currentlevelparams) > 0:
-        output+= linesep
-        for param in currentlevelparams:
-            if app.GetParameterType(param) == otbApplication.ParameterType_Group and level == 0:
-                output+= prefix+"**["+ ConvertString(app.GetParameterName(param))+ "]**"
-            else:
-                output+= prefix+"**"+ ConvertString(app.GetParameterName(param))+ "**"
-            descr =  RstifyDescription(app.GetParameterDescription(param))
-            if len(descr):
-                output+= ": "+descr
-            if app.GetParameterType(param) ==  otbApplication.ParameterType_Choice:
-                output+= " Available choices are: "
-                additionalKeys = []
-                for choiceKey in app.GetChoiceKeys(param):
-                    additionalKeys.append(param+'.'+choiceKey)
-                nextParamList = paramlist + tuple(additionalKeys)
-            else:
-                nextParamList = paramlist
-            output+= linesep
-            ret = ApplicationParametersToRstV2(app,nextParamList,deep,param)
-            if indentLevel == 0 and len(ret)==0:
-                output+= linesep
-            output+= ret
-        output+= linesep
-    return output
 
-def GetApplicationExampleCommandLine(app,idx):
+    output += ".. code-block:: python\n\n"
 
-    output = "%s%s%s\t%s" % ("::", linesep , linesep, "otbcli_")
-    output+= ConvertString(app.GetName())
-    for i in range(0, app.GetExampleNumberOfParameters(idx)):
-        output+=" -" + app.GetExampleParameterKey(idx,i)+ " " + app.GetExampleParameterValue(idx,i)
-    output += linesep + linesep
-    return output
+    # Render example comment
+    if len(app.GetExampleComment(idx)) > 0:
+        output += "\t# {}\n".format(app.GetExampleComment(idx))
 
-def GetApplicationExamplePythonSnippet(app,idx,expand = False, inputpath="",outputpath=""):
-    appname = app.GetName()
-    printable = []
-    output = linesep + "::" + linesep + linesep
-    output+= "\t#!/usr/bin/python" + linesep
-
-    output+= linesep
-    output+= "\t# Import the otb applications package" + linesep
-    output+= "\timport otbApplication" + linesep + linesep
-    output+= "\t# The following line creates an instance of the " + ConvertString(app.GetName()) + " application " + linesep
-    output+= "\t" + ConvertString(app.GetName()) + " = otbApplication.Registry.CreateApplication(\"" + ConvertString(app.GetName()) + "\")" + linesep + linesep
-    output+= "\t# The following lines set all the application parameters:" + linesep
+    output += "\timport otbApplication" + linesep + linesep
+    output += "\t" + appname + " = otbApplication.Registry.CreateApplication(\"" + app.GetName() + "\")" + linesep + linesep
     for i in range(0, app.GetExampleNumberOfParameters(idx)):
         param = app.GetExampleParameterKey(idx,i)
         value = app.GetExampleParameterValue(idx,i)
         paramtype = app.GetParameterType(param)
         paramrole = app.GetParameterRole(param)
-        if paramtype == otbApplication.ParameterType_ListView:
-            break
-        if paramtype == otbApplication.ParameterType_Group:
-            break
-        if paramtype ==  otbApplication.ParameterType_Choice:
+        if paramtype == ParameterType_ListView:
+            break # TODO
+        if paramtype == ParameterType_Group:
+            break # TODO
+        if paramtype ==  ParameterType_Choice:
             #app.SetParameterString(param,value)
-            output+= "\t" + appname + ".SetParameterString(" + EncloseString(param) + "," + EncloseString(value) + ")" + linesep
-        if paramtype == otbApplication.ParameterType_Empty:
-            app.EnableParameter(param)
-            output+= "\t" + appname + ".EnableParameter("+EncloseString(param)+")" + linesep
-        if paramtype == otbApplication.ParameterType_Bool:
-            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+","+EncloseString(value)+")" + linesep
-        if paramtype == otbApplication.ParameterType_Int \
-                or paramtype == otbApplication.ParameterType_Radius \
-                or paramtype == otbApplication.ParameterType_RAM:
+            output+= "\t" + appname + ".SetParameterString(" + EncloseString(param) + "," + EncloseString(value) + ")"
+        if paramtype == ParameterType_Bool:
+            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+","+EncloseString(value)+")"
+        if paramtype == ParameterType_Int \
+                or paramtype == ParameterType_Radius \
+                or paramtype == ParameterType_RAM:
             # app.SetParameterString(param,value)
-            output += "\t" + appname + ".SetParameterInt("+EncloseString(param)+", "+value+")" + linesep
-        if paramtype == otbApplication.ParameterType_Float:
+            output += "\t" + appname + ".SetParameterInt("+EncloseString(param)+", "+value+")"
+        if paramtype == ParameterType_Float:
             # app.SetParameterString(param,value)
-            output += "\t" + appname + ".SetParameterFloat("+EncloseString(param)+", "+value + ")" + linesep
-        if paramtype == otbApplication.ParameterType_String:
+            output += "\t" + appname + ".SetParameterFloat("+EncloseString(param)+", "+value + ")"
+        if paramtype == ParameterType_String:
             # app.SetParameterString(param,value)
-            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(value)+")" + linesep
-        if paramtype == otbApplication.ParameterType_StringList:
+            output+= "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(value)+")"
+        if paramtype == ParameterType_StringList:
             values = value.split(" ")
             # app.SetParameterStringList(param,values)
-            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+", "+str(values)+")" + linesep
-        if paramtype == otbApplication.ParameterType_InputFilename \
-            or paramtype == otbApplication.ParameterType_OutputFilename \
-            or paramtype == otbApplication.ParameterType_Directory:
+            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+", "+str(values)+")"
+        if paramtype == ParameterType_InputFilename \
+            or paramtype == ParameterType_OutputFilename \
+            or paramtype == ParameterType_Directory:
             if paramrole == 0:
                 # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand)) + ")" + linesep
-                printable.append(["in","file",ExpandPath(value,inputpath,expand)])
+                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand)) + ")"
             elif paramrole == 1:
                 # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,outputpath,expand))+")" + linesep
-                printable.append(["out","file",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_InputImage :
+                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,outputpath,expand))+")"
+        if paramtype == ParameterType_InputImage :
             # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"+linesep
-            printable.append(["in","img",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_ComplexInputImage:
+            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"
+        if paramtype == ParameterType_ComplexInputImage:
             # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")" + linesep
-            printable.append(["in","cimg",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_InputVectorData:
+            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"
+        if paramtype == ParameterType_InputVectorData:
             # app.SetParameterString(param,EncloseString(ExpandPath(value,inputpath,expand)))
-            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")" + linesep
-            printable.append(["in","vdata",ExpandPath(value,inputpath,expand)])
-        if paramtype == otbApplication.ParameterType_OutputImage :
+            output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value,inputpath,expand))+")"
+        if paramtype == ParameterType_OutputImage :
             foundcode,foundname = GetPixelType(value)
             if foundcode != -1:
-                # app.SetParameterString(param,EncloseString(ExpandPath(value[:-len(foundname),outputpath,expand))))
-                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value[:-len(foundname)],outputpath,expand))+")" + linesep
-           #app.SetParameterOutputImagePixelType(param,foundcode)
-                if foundcode == 1:
-                    printable.append(["out","ucimg",ExpandPath(value[:len(foundname)],inputpath,expand)])
-                else:
-                    printable.append(["out","img",ExpandPath(value[:len(foundname)],inputpath,expand)])
-                output += "\t" + appname + ".SetParameterOutputImagePixelType("+EncloseString(param)+", "+str(foundcode)+")" + linesep
+                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(ExpandPath(value[:-len(foundname)],outputpath,expand))+")"
+                output += "\n"
+                output += "\t" + appname + ".SetParameterOutputImagePixelType("+EncloseString(param)+", "+str(foundcode)+")"
             else:
-                # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-                output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")" + linesep
-                printable.append(["out","img",ExpandPath(value,outputpath,expand)])
-        if paramtype == otbApplication.ParameterType_ComplexOutputImage :
+                output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")"
+        if paramtype == ParameterType_ComplexOutputImage :
             # TODO: handle complex type properly
             # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")" + linesep
-            printable.append(["out","cimg",ExpandPath(value,outputpath,expand)])
-        if paramtype == otbApplication.ParameterType_OutputVectorData:
+            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")"
+        if paramtype == ParameterType_OutputVectorData:
             # app.SetParameterString(param,EncloseString(ExpandPath(value,outputpath,expand)))
-            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")" + linesep
-            printable.append(["out","vdata",ExpandPath(value,outputpath,expand)])
-        if paramtype == otbApplication.ParameterType_InputImageList:
+            output += "\t" + appname +".SetParameterString("+EncloseString(param)+", "+ EncloseString(ExpandPath(value,outputpath,expand)) + ")"
+        if paramtype == ParameterType_InputImageList:
             values = value.split(" ")
             values = [ExpandPath(val,inputpath,expand) for val in values]
             # app.SetParameterStringList(param,values)
-            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param) + ", " + str(values) + ")" + linesep
-        if paramtype == otbApplication.ParameterType_InputVectorDataList:
+            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param) + ", " + str(values) + ")"
+        if paramtype == ParameterType_InputVectorDataList:
             values = value.split(" ")
             values = [ExpandPath(val,inputpath,expand) for val in values]
             #app.SetParameterStringList(param,values)
-            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+ ", " + str(values) + ")" + linesep
+            output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+ ", " + str(values) + ")"
         output+=linesep
-    output += "\t# The following line execute the application" + linesep
-    output+= "\t" + appname + ".ExecuteAndWriteOutput()"+ linesep
-    return output,printable
+    output += linesep
+    output+= "\t" + appname + ".ExecuteAndWriteOutput()" + linesep + linesep
+    return output
+
+def render_choice(app, key):
+    "Render a choice parameter to rst"
+
+    # First render all the choice values
+    choice_keys = app.GetChoiceKeys(key)
+    choice_names = app.GetChoiceNames(key)
+
+    choice_entries = ""
+    for (choice_key, choice_name) in zip(choice_keys, choice_names):
+        # For the description, replace newlines by |br| because we are in a bullet list item
+        choice_description = app.GetParameterDescription(key + "." + choice_key).replace("\n", " |br| ")
+        choice_entries += template_parameter_choice_entry.format(
+            name=choice_name,
+            #key=choice_key, # if we want to show the key in choice parameter values
+            description=choice_description
+        )
+
+    # Then render the full choice parameter
+    return template_parameter_choice.format(
+        name=app.GetParameterName(key),
+        key=key,
+        value="[" + "|".join(choice_keys) + "]",
+        flags=rst_parameter_flags(app, key),
+        description=app.GetParameterDescription(key),
+        choices=choice_entries,
+    )
+
+def rst_section(text, delimiter, ref=None):
+    "Make a rst section title"
+
+    output = ""
+
+    if ref is not None:
+        output += ".. _" + ref + ":\n\n"
+
+    output += text + "\n" + delimiter * len(text) + "\n\n"
+    return output
+
+def rst_parameter_value(app, key):
+    "Render a parameter value to rst"
+
+    type = app.GetParameterType(key)
+
+    # ListView is a special case depending on its mode
+    if type == ParameterType_ListView:
+        if app.GetListViewSingleSelectionMode(key):
+            return "string"
+        else:
+            return "string1 string2..."
+
+    # For all other types it's a simple mapping
+    values = {}
+    values.update({ParameterType_Bool: "bool"})
+    values.update(dict.fromkeys([ParameterType_Int, ParameterType_Radius, ParameterType_RAM], "int"))
+    values.update({ParameterType_Float: "float"})
+    values.update({ParameterType_String: "string"})
+    values.update({ParameterType_StringList: "string1 string2..."})
+    values.update(dict.fromkeys([ParameterType_InputFilename, ParameterType_OutputFilename], "filename [dtype]"))
+    values.update(dict.fromkeys([ParameterType_InputImage, ParameterType_ComplexInputImage], "image"))
+    values.update(dict.fromkeys([ParameterType_OutputImage, ParameterType_ComplexOutputImage], "image [dtype]"))
+    values.update(dict.fromkeys([ParameterType_InputVectorData, ParameterType_OutputVectorData], "vectorfile"))
+    values.update({ParameterType_Directory: "directory"})
+    values.update({ParameterType_Choice: "choice"})
+    values.update({ParameterType_InputImageList: "image1 image2..."})
+    values.update({ParameterType_InputVectorDataList: "vectorfile1 vectorfile2..."})
+    values.update({ParameterType_InputFilenameList: "filename1 filename2..."})
+    values.update(dict.fromkeys([ParameterType_InputProcessXML, ParameterType_OutputProcessXML], "filename.xml"))
+
+    if type in values:
+        return values[type]
+    else:
+        raise ValueError("Cannot show parameter value for type ", type)
+
+def rst_parameter_flags(app, key):
+    """
+    Display the mandatory and default value flags of a parameter
+    The display logic tries to follow the logic in WrapperCommandLineLauncher::DisplayParameterHelp
+    The default value is formatted using GetParameterAsString to use the same formatting as the cli interface
+    """
+
+    if app.IsMandatory(key) and not app.HasValue(key):
+        return "*Mandatory* "
+    elif app.HasValue(key) and app.GetParameterType(key) != ParameterType_Group and app.GetParameterAsString(key) != "":
+        return "*Default value: {}* ".format(app.GetParameterAsString(key))
+    else:
+        return ""
+
+def detect_abuse(app):
+    "Detect choice parameter values which are also used as groups"
+
+    fake_groups = {}
+    keys = app.GetParametersKeys()
+    choice_keys = [k for k in keys if app.GetParameterType(k) == ParameterType_Choice]
+
+    # For each choice parameter
+    for key in choice_keys:
+
+        # Consider all its possible values
+        for choice_key in app.GetChoiceKeys(key):
+            fullkey = key + "." + choice_key
+
+            # See if that value is also used as a group anywhere in the application
+            for k in keys:
+                if k.startswith(fullkey) and k != fullkey:
+
+                    # In that case, mark the first element of that group
+                    if fullkey not in fake_groups.values():
+                        fake_groups[k] = fullkey
+
+    return fake_groups
+
+def render_parameters(app):
+    "Render application parameters to rst"
+
+    output = ""
+
+    fake_markers = detect_abuse(app)
+
+    previous_level = 1
+    for key in app.GetParametersKeys():
+        type = app.GetParameterType(key)
+
+        # If reducing level not on a group parameter, render a horizontal line
+        current_level = 1 + key.count(".")
+        if current_level < previous_level and type != ParameterType_Group:
+            output += "\n\n------------\n\n"
+        previous_level = current_level
+
+        # Choice parameter values can act as groups
+        # Detect that case to add a section title
+        if key in fake_markers:
+            output += rst_section(app.GetParameterName(fake_markers[key]) + " options", "^")
+
+        if type == ParameterType_Group:
+            output += template_parameter_group.format(
+                name=rst_section(app.GetParameterName(key), "^"),
+                description=app.GetParameterDescription(key)
+            )
+
+        elif type == ParameterType_Choice:
+            output += render_choice(app, key)
+
+        else:
+            output += template_parameter.format(
+                name=app.GetParameterName(key),
+                key=key,
+                value=rst_parameter_value(app, key),
+                description=app.GetParameterDescription(key),
+                flags=rst_parameter_flags(app, key),
+            )
 
-def GetApplicationExamplePython(app,idx):
-    output, printable = GetApplicationExamplePythonSnippet(app,idx)
-    output+= linesep
     return output
 
-def RstHeading(text, delimiter, ref=None):
-    heading = ""
-    if ref:
-        heading += ".. _" + ref + ":" + linesep + linesep
-    heading += text + linesep
-    heading += delimiter * len(text)  + linesep
-    heading += linesep
-    return heading
+def render_example_cli(app, index):
+    "Render a command line example to rst (includes indentation)"
 
-def ApplicationToRst(appname):
     output = ""
-    app = None
-    try:
-        app = otbApplication.Registry.CreateApplication(appname)
-    except e:
-        print(e)
+
+    # Render comment
+    if len(app.GetExampleComment(index)) > 0:
+        output += "    # " + app.GetExampleComment(index) + "\n"
+
+    output += "    otbcli_" + app.GetName()
+    for i in range(app.GetExampleNumberOfParameters(index)):
+        output += " -" + app.GetExampleParameterKey(index, i) + " " + app.GetExampleParameterValue(index, i)
+    output += "\n"
+    return output
+
+def render_all_examples_cli(app):
+    "Render all command line examples to rst"
+
+    if app.GetNumberOfExamples() == 0:
+        return "    # No example found"
+    if app.GetNumberOfExamples() == 1:
+        return render_example_cli(app, 0)
+    else:
+        output = ""
+        for i in range(app.GetNumberOfExamples()):
+            if i > 0:
+                output += "\n"
+            output += render_example_cli(app, i)
+        return output
+
+def render_all_examples_python(app):
+    "Render all python examples to rst"
+    output = ""
+    for i in range(app.GetNumberOfExamples()):
+        output += GetApplicationExamplePythonSnippet(app, i)
+    return output
+
+def render_limitations(app):
+    "Render app DocLimitations to rst"
+
+    limitations = app.GetDocLimitations()
+    if limitations is None or len(limitations) == 0 or limitations == "None":
+        return ""
+    else:
+        return rst_section("Limitations", "-") + limitations
+
+def render_see_also(app):
+    "Render app See Also to rst"
+
+    see_also = app.GetDocSeeAlso()
+    if see_also is None or len(see_also) < 2:
+        return ""
+    else:
+        return rst_section("See also", "-") + "| " + see_also.replace("\n", "\n| ") # use line blocks for see also
+
+def multireplace(string, replacements):
+    "multiple string replace (from https://stackoverflow.com/a/6117124/5815110)"
+    substrs = sorted(replacements, key=len, reverse=True)
+    regexp = re.compile('|'.join(map(re.escape, substrs)))
+    return regexp.sub(lambda match: replacements[match.group(0)], string)
+
+def make_links(text, allapps):
+    "Replace name of applications by internal rst links"
+
+    rep = {appname: ":ref:`{}`".format("app-" + appname) for appname in allapps}
+    return multireplace(text, rep)
+
+def render_application(appname, allapps):
+    "Render app to rst"
+
+    app = otbApplication.Registry.CreateApplication(appname)
+
     # TODO: remove this when bug 440 is fixed
     app.Init()
-    output += RstHeading(app.GetName() + ' - ' + app.GetDocName(), '^')
-    output += app.GetDescription() + linesep * 2
-    output += RstHeading("Detailed description", '-')
-    output += app.GetDocLongDescription() + linesep * 2
-    limitations = app.GetDocLimitations()
-    output += RstHeading("Parameters", '-')
-    depth = GetParametersDepth(app.GetParametersKeys())
-    deep = depth > 0
-    output += ApplicationParametersToRstV2(app,app.GetParametersKeys(),deep) + linesep
-    if app.GetNumberOfExamples() > 1:
-        output += RstHeading("Examples", '-') + linesep
-        #output += appdetailslevel + "{Examples}" + "\\label{appexamples:" + appname + "}" + linesep
-        for i in range(0,app.GetNumberOfExamples()):
-            output += ":Example "+  str(i+1) + ':' + linesep + linesep
-#            output += RstHeading("Example "+  str(i+1) , '-')
-            output += app.GetExampleComment(i)
-            output+= "To run this example in command-line, use the following: " + linesep
-            output += linesep + GetApplicationExampleCommandLine(app,i)
-            output+= "To run this example from Python, use the following code snippet: " + linesep
-            output += GetApplicationExamplePython(app,i)
-    elif app.GetNumberOfExamples() == 1:
-        output += RstHeading("Example", '-')
-        if( len(app.GetExampleComment(0)) > 1):
-            output += app.GetExampleComment(0)
-        output+= "To run this example in command-line, use the following: " + linesep
-        output += GetApplicationExampleCommandLine(app,0)
-        output+= "To run this example from Python, use the following code snippet: " + linesep
-        output += GetApplicationExamplePython(app,0)
-
-    if len(limitations)>=2:
-        output += RstHeading("Limitations", '~')
-#        output += ":Limitations:" + linesep + linesep
-        output += ConvertString(app.GetDocLimitations()) + linesep + linesep
-
-    output += RstHeading("Authors", '~')
-#    output += ":Authors:" + linesep + linesep
-    output += "This application has been written by " + ConvertString(app.GetDocAuthors()) + "." + linesep + linesep
-    seealso = app.GetDocSeeAlso()
-    if len(seealso) >=2:
-        output += RstHeading("See Also", '~')
-#        output += ":See Also:" + linesep + linesep
-        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 += ConvertToLineBlock(app.GetDocSeeAlso()) + linesep + linesep
+
+    application_documentation_warnings(app)
+
+    output = template_application.format(
+        label="app-" + appname,
+        heading=rst_section(app.GetName(), '='),
+        description=app.GetDescription(),
+        longdescription=make_links(app.GetDocLongDescription(), allapps),
+        parameters=render_parameters(app),
+        examples_cli=render_all_examples_cli(app),
+        examples_python=render_all_examples_python(app),
+        limitations=render_limitations(app),
+        see_also=make_links(render_see_also(app), allapps)
+    )
 
     return output
 
@@ -524,87 +401,68 @@ def GetApplicationTags(appname):
      app = otbApplication.Registry.CreateApplication(appname)
      return app.GetDocTags()
 
-import shutil
-
 def RstPageHeading(text, maxdepth, ref=None):
-    output = RstHeading(text, "=", ref=ref) + linesep
+    output = rst_section(text, "=", ref=ref)
     output += ".. toctree::" + linesep
     output += "\t:maxdepth: " + maxdepth + linesep
     output += linesep + linesep
     return output
 
-def GenerateRstForApplications():
-    out = ""
+def GenerateRstForApplications(rst_dir):
+    "Generate .rst files for all applications"
+
     blackList = ["TestApplication", "Example", "ApplicationExample"]
-    allApps = None
-    try:
-        allApps = otbApplication.Registry.GetAvailableApplications( )
-        print(allApps)
-    except:
-        print('error in otbApplication.Registry.GetAvailableApplications()')
-        sys.exit(1)
+    allApps = otbApplication.Registry.GetAvailableApplications()
 
     if not allApps:
-        print('No OTB applications available. Please check OTB_APPLICATION_PATH env variable')
-        sys.exit(1)
+        raise RuntimeError("No OTB applications available. Please check OTB_APPLICATION_PATH env variable.")
 
     writtenTags = []
     appNames = [app for app in allApps if app not in blackList]
 
-    print("All apps: %s" % (appNames,))
+    appIndexFile = open(rst_dir + '/Applications.rst', 'w')
+    appIndexFile.write(RstPageHeading("Applications", "2", ref="apprefdoc"))
 
-    appIndexFile = open(RST_DIR + '/Applications.rst', 'w')
-    appIndexFile.write(RstPageHeading("Applications Reference Documentation", "2", ref="apprefdoc"))
-    for appName in appNames:
-        tags = GetApplicationTags(appName)
+    print("Generating rst for {} applications".format(len(appNames)))
 
-        if not tags:
-            print("No tags for application: "  +  appName)
-            sys.exit(1)
+    for appName in appNames:
 
+        # Get application first tag
+        tags = GetApplicationTags(appName)
+        if not tags or len(tags) == 0:
+            raise RuntimeError("No tags for application: " + appName)
         tag = tags[0]
+        tag_ = tag.replace(" ", "_")
 
-        tag_ = tag
-        if tag.find(' '):
-            tag_ = tag.replace(' ', '_')
-
-        if not tag_:
-            print('empty tag found for ' + appName)
+        # Add it to the index (i.e. https://www.orfeo-toolbox.org/CookBook/Applications.html)
+        if not tag in writtenTags:
+            appIndexFile.write('\tApplications/' + tag_ + '.rst\n')
+            writtenTags.append(tag)
 
-        if not tag_ in writtenTags:
-            appIndexFile.write('\tApplications/' + tag_ + '.rst' + linesep)
-            writtenTags.append(tag_)
-
-        tagFileName = RST_DIR + '/Applications/'  + tag_ + '.rst'
+        # Create or update tag index file (e.g. https://www.orfeo-toolbox.org/CookBook/Applications/Feature_Extraction.html)
+        tagFileName = rst_dir + '/Applications/'  + tag_ + '.rst'
         if os.path.isfile(tagFileName):
-            tagFile = open(tagFileName, 'a')
-            tagFile.write("\tapp_" + appName + linesep)
-            tagFile.close()
+            with open(tagFileName, 'a') as tagFile:
+                tagFile.write("\tapp_" + appName + "\n")
         else:
-            tagFile = open(tagFileName, 'w')
-            tagFile.write( RstPageHeading(tag, "1") )
-            tagFile.write("\tapp_" + appName + linesep)
-            tagFile.close()
-
-        print("Generating " + appName + ".rst" +  " on tag " + tag_)
-        appFile = open(RST_DIR + '/Applications/app_'  + appName + '.rst', 'w')
-        out = ApplicationToRst(appName)
-        appFile.write(out)
-        appFile.close()
-
-    return out
+            with open(tagFileName, 'w') as tagFile:
+                tagFile.write( RstPageHeading(tag, "1") )
+                tagFile.write("\tapp_" + appName + "\n")
 
+        # Write application rst
+        with open(rst_dir + '/Applications/app_'  + appName + '.rst', 'w') as appFile:
+            appFile.write(render_application(appName, appNames))
 
 if __name__ == "__main__":
-    parser = OptionParser(usage="Export application(s) to rst file.")
-    parser.add_option("-a",dest="appname",help="Generate rst only for this application (eg: OrthoRectification)")
-    parser.add_option("-m",dest="module",help="Generate rst only for this module (eg: Image Manipulation)")
-    parser.add_option("-o",dest="rstdir",help="directory where rst files are generated")
-    (options, args) = parser.parse_args()
-
-    RST_DIR = options.rstdir
-
-    if not options.appname is None:
-        out = ApplicationToRst(options.appname)
-    else:
-        GenerateRstForApplications()
+    parser = argparse.ArgumentParser(usage="Export application(s) to rst file")
+    parser.add_argument("rst_dir", help="Directory where rst files are generated")
+    args = parser.parse_args()
+
+    # Load rst templates
+    template_application = open("templates/application.rst").read()
+    template_parameter = open("templates/parameter.rst").read()
+    template_parameter_group = open("templates/parameter_group.rst").read()
+    template_parameter_choice_entry = open("templates/parameter_choice_entry.rst").read()
+    template_parameter_choice = open("templates/parameter_choice.rst").read()
+
+    GenerateRstForApplications(args.rst_dir)
diff --git a/Documentation/Cookbook/Scripts/otb_warnings.py b/Documentation/Cookbook/Scripts/otb_warnings.py
new file mode 100644
index 0000000000000000000000000000000000000000..34566d2d851a6547ef50cf71f0d613ce4934987e
--- /dev/null
+++ b/Documentation/Cookbook/Scripts/otb_warnings.py
@@ -0,0 +1,66 @@
+import sys
+import re
+
+def parameter_warnings(app_warn, app, key):
+
+    def warn(message):
+        app_warn("Parameter '{}' ".format(key) + message)
+
+    name = app.GetParameterName(key)
+    description = app.GetParameterDescription(key)
+
+    if name[-1] == " ":
+        warn("name ends with a space")
+
+    if ":" in name:
+        warn("name contains a special character (:)")
+
+    if "." in name:
+        warn("name contains a special character (.)")
+
+    # disabled because there are so many for now
+    #if description == "":
+        #warn("missing description")
+
+    # disabled because there are so many for now
+    #if len(description) > 0 and description[-1] != ".":
+        #warn("description does not end with a period")
+
+    if len(description) > 0 and " :" in description:
+        warn("description has a space before a colon")
+
+def application_documentation_warnings(app):
+    "Emit warnings about application documentation"
+
+    def warn(message):
+        print("OTB Documentation Warning ({}): {}".format(app.GetName(), message), file=sys.stderr)
+
+    description = app.GetDescription()
+    longdescription = app.GetDocLongDescription()
+
+    # disable because there are so many for now
+    #if not longdescription[-1] == ".":
+        #warn("Application Long Description does not end with a period (.)")
+
+    if re.search("\\n [a-zA-Z]", longdescription):
+        warn("Application Long Description contains '\\n ' pattern (usually not intended)")
+
+    if " :" in longdescription:
+        warn("Application Long Description has a space before a colon")
+
+    if app.GetNumberOfExamples() == 0:
+        warn("Application has no examples")
+
+    keys = app.GetParametersKeys()
+    for key in app.GetParametersKeys():
+        parameter_warnings(warn, app, key)
+
+    if "ram" in keys and not keys[-3] == "ram":
+        warn("'ram' parameter is not third from last")
+
+    if "inxml" in keys and not keys[-2] == "inxml":
+        warn("'inxml' parameter is not second from last parameter")
+
+    if "outxml" in keys and not keys[-1] == "outxml":
+        warn("'outxml' is not last parameter")
+
diff --git a/Documentation/Cookbook/_static/css/otb_theme.css b/Documentation/Cookbook/_static/css/otb_theme.css
new file mode 100644
index 0000000000000000000000000000000000000000..d9553257a4b6723ee18d887b60bd59303193afac
--- /dev/null
+++ b/Documentation/Cookbook/_static/css/otb_theme.css
@@ -0,0 +1,10 @@
+.wy-nav-content {
+    max-width: 800px;
+}
+
+/* Reduce the effect of the p bottom margin before lists
+ * Very useful for choice parameters in app doc for example
+ */
+p + ul {
+    margin-top: -18px;
+}
diff --git a/Documentation/Cookbook/rst/AdvancedUse.rst b/Documentation/Cookbook/rst/AdvancedUse.rst
index e9813689ce2575da5c16082f6123c12f08ab6419..d3c436edfe24ab5ca026b594f11ea25c40c37027 100644
--- a/Documentation/Cookbook/rst/AdvancedUse.rst
+++ b/Documentation/Cookbook/rst/AdvancedUse.rst
@@ -334,6 +334,8 @@ The available syntax for boolean options are:
 -  OFF, Off, off, false, False, 0 are available for setting a ’false’
    boolean value
 
+-----------------------------------------------
+
 ::
 
    &nodata=(double) value / [int:double, int:double ...]
@@ -394,10 +396,10 @@ Some examples are provided below:
 
 ::
 
-    $ otbcli_Convert -in OTB-Data/Examples/QB_1_ortho.tif -out "/tmp/example1.tif?&gdal:co:TILED=YES&gdal:co:COMPRESS=DEFLATE"
+    $ otbcli_DynamicConvert -in OTB-Data/Examples/QB_1_ortho.tif -out "/tmp/example1.tif?&gdal:co:TILED=YES&gdal:co:COMPRESS=DEFLATE"
 
 - Process only first band from a file
 
 ::
 
-    $ otbcli_Convert -in "OTB-Data/Examples/QB_1_ortho.tif?&bands=1" -out /tmp/example2.tif
+    $ otbcli_DynamicConvert -in "OTB-Data/Examples/QB_1_ortho.tif?&bands=1" -out /tmp/example2.tif
diff --git a/Documentation/Cookbook/rst/Installation.rst b/Documentation/Cookbook/rst/Installation.rst
index 3c61ef0b18af363a3f3b9bb2cc88556424cd405c..d24b59a50f35c10ec818cb2c20ce3ba50616cc0d 100644
--- a/Documentation/Cookbook/rst/Installation.rst
+++ b/Documentation/Cookbook/rst/Installation.rst
@@ -24,7 +24,7 @@ Windows
 .. include:: Installation_Windows.rst
 
 Linux
-------------
+-----
 
 .. include:: Installation_Linux.rst
 
diff --git a/Documentation/Cookbook/rst/OTB-Applications.rst b/Documentation/Cookbook/rst/OTB-Applications.rst
index 3fe1052e956dc584cb898cc474347ac184a04f65..45ffa46e87f12388756a1e077ce92c5605b501a7 100644
--- a/Documentation/Cookbook/rst/OTB-Applications.rst
+++ b/Documentation/Cookbook/rst/OTB-Applications.rst
@@ -1,7 +1,7 @@
 A brief tour of OTB Applications
 ================================
 
-OTB ships with more than 90 ready to use applications for remote sensing tasks.
+OTB ships with more than 100 ready to use applications for remote sensing tasks.
 They usually expose existing processing functions from the underlying C++
 library, or integrate them into high level pipelines. OTB applications allow the user 
 to:
@@ -33,9 +33,9 @@ The complete list of applications is described in the Chapter :ref:`apprefdoc`.
 All standard applications share the same implementation and automatically expose
 generated interfaces.
 However they are accessed in a slightly different way: the command-line interface is prefixed by ``otbcli_``, while the Qt interface is prefixed by
-``otbgui_``. For cwinstance, calling ``otbcli_Convert`` will launch the
-command-line interface of the Convert application, while
-``otbgui_Convert`` will launch the GUI.
+``otbgui_``. For instance, calling ``otbcli_DynamicConvert`` will launch the
+command-line interface of the DynamicConvert application, while
+``otbgui_DynamicConvert`` will launch the GUI.
 
 Command-line launcher
 ---------------------
@@ -84,44 +84,55 @@ example based on the OrthoRectification application:
 ::
 
     $ otbcli_OrthoRectification
-
-    ERROR: Waiting for at least one parameter...
-
-    ====================== HELP CONTEXT ======================
-    NAME: OrthoRectification
-    DESCRIPTION: This application allows to ortho-rectify optical images from supported sensors.
-
-    EXAMPLE OF USE:
+    ERROR: Waiting for at least one parameter.
+
+
+    This is the Ortho-rectification (OrthoRectification) application, version 6.7.0
+
+    This application allows ortho-rectifying optical and radar images from supported sensors.
+    Complete documentation: https://www.orfeo-toolbox.org/CookBook/Applications/app_OrthoRectification.html or -help
+
+    Parameters:
+            -io                      <group>          Input and output data
+    MISSING -io.in                   <string>         Input Image  (mandatory)
+    MISSING -io.out                  <string> [pixel] Output Image  [pixel=uint8/uint16/int16/uint32/int32/float/double/cint16/cint32/cfloat/cdouble] (default value is float) (mandatory)
+            -map                     <string>         Map Projection [utm/lambert2/lambert93/wgs/epsg] (mandatory, default value is utm)
+            -map.utm.zone            <int32>          Zone number  (mandatory, default value is 31)
+            -map.utm.northhem        <boolean>        Northern Hemisphere  (mandatory, default value is false)
+            -map.epsg.code           <int32>          EPSG Code  (mandatory, default value is 4326)
+            -outputs                 <group>          Output Image Grid
+            -outputs.mode            <string>         Parameters estimation modes [auto/autosize/autospacing/outputroi/orthofit] (mandatory, default value is auto)
+    MISSING -outputs.ulx             <float>          Upper Left X  (mandatory)
+    MISSING -outputs.uly             <float>          Upper Left Y  (mandatory)
+    MISSING -outputs.sizex           <int32>          Size X  (mandatory)
+    MISSING -outputs.sizey           <int32>          Size Y  (mandatory)
+    MISSING -outputs.spacingx        <float>          Pixel Size X  (mandatory)
+    MISSING -outputs.spacingy        <float>          Pixel Size Y  (mandatory)
+            -outputs.lrx             <float>          Lower right X  (optional, off by default)
+            -outputs.lry             <float>          Lower right Y  (optional, off by default)
+            -outputs.ortho           <string>         Model ortho-image  (optional, off by default)
+            -outputs.isotropic       <boolean>        Force isotropic spacing by default  (mandatory, default value is true)
+            -outputs.default         <float>          Default pixel value  (optional, off by default, default value is 0)
+            -elev                    <group>          Elevation management
+            -elev.dem                <string>         DEM directory  (optional, off by default)
+            -elev.geoid              <string>         Geoid File  (optional, off by default)
+            -elev.default            <float>          Default elevation  (mandatory, default value is 0)
+            -interpolator            <string>         Interpolation [bco/nn/linear] (mandatory, default value is bco)
+            -interpolator.bco.radius <int32>          Radius for bicubic interpolation  (mandatory, default value is 2)
+            -opt                     <group>          Speed optimization parameters
+            -opt.rpc                 <int32>          RPC modeling (points per axis)  (optional, off by default, default value is 10)
+            -opt.ram                 <int32>          Available RAM (MB)  (optional, off by default, default value is 128)
+            -opt.gridspacing         <float>          Resampling grid spacing  (optional, off by default, default value is 4)
+            -inxml                   <string>         Load parameters from XML  (optional, off by default)
+            -progress                <boolean>        Report progress
+            -help                    <string list>    Display long help (empty list), or help for given parameters keys
+
+    Use -help param1 [... paramN] to see detailed documentation of those parameters.
+
+    Examples:
     otbcli_OrthoRectification -io.in QB_TOULOUSE_MUL_Extract_500_500.tif -io.out QB_Toulouse_ortho.tif
 
-    DOCUMENTATION: http://www.orfeo-toolbox.org/Applications/OrthoRectification.html
-    ======================= PARAMETERS =======================
-            -progress                        <boolean>        Report progress
-    MISSING -io.in                           <string>         Input Image
-    MISSING -io.out                          <string> [pixel] Output Image  [pixel=uint8/int8/uint16/int16/uint32/int32/float/double]
-            -map                             <string>         Output Map Projection [utm/lambert2/lambert93/transmercator/wgs/epsg]
-    MISSING -map.utm.zone                    <int32>          Zone number
-            -map.utm.northhem                <boolean>        Northern Hemisphere
-            -map.transmercator.falseeasting  <float>          False easting
-            -map.transmercator.falsenorthing <float>          False northing
-            -map.transmercator.scale         <float>          Scale factor
-            -map.epsg.code                   <int32>          EPSG Code
-            -outputs.mode                    <string>         Parameters estimation modes [auto/autosize/autospacing]
-    MISSING -outputs.ulx                     <float>          Upper Left X
-    MISSING -outputs.uly                     <float>          Upper Left Y
-    MISSING -outputs.sizex                   <int32>          Size X
-    MISSING -outputs.sizey                   <int32>          Size Y
-    MISSING -outputs.spacingx                <float>          Pixel Size X
-    MISSING -outputs.spacingy                <float>          Pixel Size Y
-            -outputs.isotropic               <boolean>        Force isotropic spacing by default
-            -elev.dem                        <string>         DEM directory
-            -elev.geoid                      <string>         Geoid File
-            -elev.default                    <float>          Average Elevation
-            -interpolator                    <string>         Interpolation [nn/linear/bco]
-            -interpolator.bco.radius         <int32>          Radius for bicubic interpolation
-            -opt.rpc                         <int32>          RPC modeling (points per axis)
-            -opt.ram                         <int32>          Available memory for processing (in MB)
-            -opt.gridspacing                 <float>          Resampling grid spacing
+
 
 For a detailed description of the application behaviour and parameters,
 please check the application reference documentation presented
@@ -169,12 +180,10 @@ In this interface, every optional parameter has a check box that you
 have to tick if you want to set a value and use this parameter. The
 mandatory parameters cannot be unchecked.
 
-The interface of the application is shown here as an example.
+The interface of the application is shown here as an example:
 
 .. figure:: Art/QtImages/rescale_param.png
-.. figure:: Art/QtImages/rescale_logs.png
-.. figure:: Art/QtImages/rescale_progress.png
-.. figure:: Art/QtImages/rescale_documentation.png
+    :align: center
 
 Python interface
 ----------------
diff --git a/Documentation/Cookbook/rst/conf.py.in b/Documentation/Cookbook/rst/conf.py.in
index c9e101cb7ab2865e843b0479c3be4ae0d4d6e501..661328eebb88a9fdfe277d2163de1a534e736ffc 100644
--- a/Documentation/Cookbook/rst/conf.py.in
+++ b/Documentation/Cookbook/rst/conf.py.in
@@ -21,6 +21,11 @@ import sphinx_rtd_theme
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #sys.path.insert(0, os.path.abspath('.'))
 
+# Customize read the docs theme a bit with a custom css
+# taken from https://stackoverflow.com/a/43186995/5815110
+def setup(app):
+    app.add_stylesheet("css/otb_theme.css")
+
 # -- General configuration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
@@ -75,7 +80,7 @@ release = '@OTB_VERSION@'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['@RST_BUILD_DIR@']
+exclude_patterns = ['@RST_BUILD_DIR@', 'templates/*.rst']
 #exclude_patterns = ['_build']
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
@@ -167,6 +172,16 @@ html_static_path = ['_static']
 # If true, the index is split into individual pages for each letter.
 #html_split_index = False
 
+html_context = {
+    'display_gitlab': True,
+    'gitlab_host': "gitlab.orfeo-toolbox.org",
+    'gitlab_user': 'orfeotoolbox',
+    'gitlab_repo': 'OTB',
+    'gitlab_version': 'develop',
+    'conf_py_path': '/Documentation/Cookbook/rst/',
+    #'source_url_prefix': "https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/tree/develop/Documentation/Cookbook/rst/",
+}
+
 # If true, links to the reST sources are added to the pages.
 html_show_sourcelink = True
 
diff --git a/Documentation/Cookbook/rst/recipes/python.rst b/Documentation/Cookbook/rst/recipes/python.rst
index b03145be78c074b5c761bc2233162a98a553f4cb..7813b897cda68c188a431261a3154f77d60fb691 100644
--- a/Documentation/Cookbook/rst/recipes/python.rst
+++ b/Documentation/Cookbook/rst/recipes/python.rst
@@ -375,41 +375,3 @@ that relate to geometry, projections, and also calibration.
 Future developments will probably offer a more adapted structure to import and
 export images between OTB and the Python world.
 
-Setting of EmptyParameter
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Most of the parameters are set using functions ``SetParameterXXX()``, except for
-one type of parameter: the ``EmptyParameter``. This class was the first
-implementation of a boolean. It is now **deprecated**, you should use ``BoolParameter``
-instead.
-
-Let's take an example with the application ``ReadImageInfo`` when it was still
-using an ``EmptyParameter`` for parameter ``keywordlist``:
-
-.. code-block:: python
-
-    import otbApplication as otb
-    app = otb.Registry.CreateApplication("ReadImageInfo")
-
-If you want the get the state of parameter ``keywordlist``, a boolean, use:
-
-.. code-block:: python
-
-    app.IsParameterEnabled("keywordlist")
-
-To set this parameter ON/OFF, use the functions:
-
-.. code-block:: python
-
-    app.EnableParameter("keywordlist")
-    app.DisableParameter("keywordlist")
-
-Don't try to use other functions to set the state of a boolean. For instance,
-try the following commands:
-
-.. code-block:: python
-
-    app.SetParameterInt("keywordlist", 0)
-    app.IsParameterEnabled("keywordlist")
-
-You will get a state ``True`` even if you asked the opposite.
diff --git a/Documentation/Cookbook/rst/templates/application.rst b/Documentation/Cookbook/rst/templates/application.rst
new file mode 100644
index 0000000000000000000000000000000000000000..68db4a8b3cc9c224fcdc107d8c4e3f9f21f97329
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/application.rst
@@ -0,0 +1,41 @@
+.. _{label}:
+
+{heading}
+{description}
+
+Description
+-----------
+
+{longdescription}
+
+Parameters
+----------
+
+.. contents:: :local:
+
+.. |br| raw:: html
+
+   <br />
+
+.. |em| raw:: html
+
+   &emsp;
+
+{parameters}
+
+Examples
+--------
+
+From the command-line:
+
+.. code-block:: bash
+
+{examples_cli}
+
+From Python:
+
+{examples_python}
+
+{limitations}
+
+{see_also}
diff --git a/Documentation/Cookbook/rst/templates/parameter.rst b/Documentation/Cookbook/rst/templates/parameter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2182bcf2bf4a9657e4266c089ea453d8a5dcd698
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter.rst
@@ -0,0 +1,3 @@
+**{name}** :code:`-{key} {value}` {flags}|br|
+{description}
+
diff --git a/Documentation/Cookbook/rst/templates/parameter_choice.rst b/Documentation/Cookbook/rst/templates/parameter_choice.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0add118a800affaf524a97125fb3a2f7ec0ca337
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter_choice.rst
@@ -0,0 +1,5 @@
+**{name}** :code:`-{key} {value}` {flags}|br|
+{description}
+
+{choices}
+
diff --git a/Documentation/Cookbook/rst/templates/parameter_choice_entry.rst b/Documentation/Cookbook/rst/templates/parameter_choice_entry.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e835a8c2d70ea36c0bc829366d5a13c8bda6855a
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter_choice_entry.rst
@@ -0,0 +1,2 @@
+* **{name}** |br| {description}
+
diff --git a/Documentation/Cookbook/rst/templates/parameter_group.rst b/Documentation/Cookbook/rst/templates/parameter_group.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0869424eb0787fbf68936bcdbab51d1094741a5e
--- /dev/null
+++ b/Documentation/Cookbook/rst/templates/parameter_group.rst
@@ -0,0 +1,4 @@
+{name}
+
+{description}
+
diff --git a/Documentation/SoftwareGuide/Latex/Tutorial.tex b/Documentation/SoftwareGuide/Latex/Tutorial.tex
index 4a09dc660223796abaa0b3f92bb28d4e81660960..f501ed333c838f9091bfaccd9f136d8f2f6c8487 100644
--- a/Documentation/SoftwareGuide/Latex/Tutorial.tex
+++ b/Documentation/SoftwareGuide/Latex/Tutorial.tex
@@ -39,7 +39,7 @@ Open the \code{CMakeLists.txt} file and write in the few lines:
 \begin{cmakecode}
 PROJECT(Tutorials)
 
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 3.1.0)
 
 FIND_PACKAGE(OTB)
 IF(OTB_FOUND)
@@ -102,7 +102,7 @@ Follow the following steps:
 \begin{cmakecode}
 project(MyFirstProcessing)
 
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.1.0)
 
 find_package(OTB REQUIRED)
 include(${OTB_USE_FILE})
diff --git a/Examples/Application/ApplicationExample.cxx b/Examples/Application/ApplicationExample.cxx
index 946ca706697a8313a73b46efe2718b7e41b9df0e..f606036a9fc14edd629bc4dc4a71ba5d503bfe6f 100644
--- a/Examples/Application/ApplicationExample.cxx
+++ b/Examples/Application/ApplicationExample.cxx
@@ -153,7 +153,7 @@ private:
 
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
 
-    AddParameter(ParameterType_Empty, "param1", "Example of boolean parameter");
+    AddParameter(ParameterType_Bool, "param1", "Example of boolean parameter");
     MandatoryOff("param1");
 
     AddParameter(ParameterType_Int, "param2", "Example of integer parameter");
diff --git a/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx b/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx
index 7f8b71c8d7e488e5fc8ab3624c6e7de374f8aefa..970814f0720562547f6bd77ce209311c5cda35d0 100644
--- a/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx
+++ b/Modules/Applications/AppClassification/app/otbClassificationMapRegularization.cxx
@@ -60,14 +60,21 @@ private:
   void DoInit() override
   {
     SetName("ClassificationMapRegularization");
-    SetDescription("Filters the input labeled image using Majority Voting in a ball shaped neighbordhood.");
+    SetDescription("Filters the input labeled image using Majority Voting in a ball shaped neighbordhood");
+
     SetDocName("Classification Map Regularization");
-    SetDocLongDescription("This application filters the input labeled image (with a maximal class label = 65535) using Majority Voting in a ball shaped neighbordhood. Majority Voting takes the more representative value of all the pixels identified by the ball shaped structuring element and then sets the center pixel to this majority label value.\n\
-    -NoData is the label of the NOT classified pixels in the input image. These input pixels keep their NoData label in the output image.\n\
-    -Pixels with more than 1 majority class are marked as Undecided if the parameter 'ip.suvbool == true', or keep their Original labels otherwise.");
+
+    SetDocLongDescription(
+        "This application filters the input labeled image (with a maximal class label = 65535) using Majority Voting in a ball shaped neighbordhood."
+        "Majority Voting takes the more representative value of all the pixels identified by the ball shaped structuring element and then sets the center pixel to this majority label value.\n\n"
+
+        "* NoData is the label of the NOT classified pixels in the input image. These input pixels keep their NoData label in the output image.\n\n"
+        "* Pixels with more than 1 majority class are marked as Undecided if the parameter 'ip.suvbool == true', or keep their Original labels otherwise.");
+
     SetDocLimitations("The input image must be a single band labeled image (with a maximal class label = 65535). The structuring element radius must have a minimum value equal to 1 pixel. Please note that the Undecided value must be different from existing labels in the input labeled image.");
+
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("Documentation of the ClassificationMapRegularization application.");
+    SetDocSeeAlso("");
 
     AddDocTag(Tags::Learning);
     AddDocTag(Tags::Analysis);
diff --git a/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx b/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx
index 7092df394fc92e3f6ecae017b8e303ab31fe4bc7..493c5a4661474f0f01e45d49ac28300889335fbd 100644
--- a/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx
+++ b/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx
@@ -82,7 +82,7 @@ private:
     SetDescription("This application computes the chosen descriptors for each studied polyline contained in the input VectorData.");
 
     SetDocName("Compute Polyline Feature From Image");
-    SetDocLongDescription("The first step in the classifier fusion based validation is to compute the chosen descriptors for each studied polyline. ");
+    SetDocLongDescription("The first step in the classifier fusion based validation is to compute the chosen descriptors for each studied polyline.");
     SetDocLimitations("Since it does not rely on streaming process, take care of the size of input image before launching application.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
diff --git a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
index 554edc2407ec481df0d1c1559f820cc190ef4385..948b0f07a9afdfcf246db4e3856fa8a9c8218e95 100644
--- a/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
+++ b/Modules/Applications/AppClassification/app/otbFusionOfClassifications.cxx
@@ -136,7 +136,7 @@ private:
     SetParameterDescription("method.dempstershafer","Fusion of classification maps by the Dempster Shafer combination method for each output pixel.");
 
     AddParameter(ParameterType_InputFilenameList, "method.dempstershafer.cmfl", "Confusion Matrices");
-    SetParameterDescription("method.dempstershafer.cmfl", "A list of confusion matrix files (*.CSV format) to define the masses of belief and the class labels. Each file should be formatted the following way: "
+    SetParameterDescription("method.dempstershafer.cmfl", "A list of confusion matrix files (.csv format) to define the masses of belief and the class labels. Each file should be formatted the following way: "
         "the first line, beginning with a '#' symbol, should be a list of the class labels present in the corresponding input classification image, organized in the same order as the confusion matrix rows/columns.");
 
     AddParameter(ParameterType_Choice, "method.dempstershafer.mob", "Mass of belief measurement");
diff --git a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
index 59f3cd2936e063053862000c47e6d1d59d7aefa9..e05dcc1964584268ebe1b6318b907cd6188462db 100644
--- a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
@@ -116,17 +116,16 @@ private:
     SetDefaultOutputPixelType( "out", ImagePixelType_uint8);
 
     AddParameter(ParameterType_OutputImage, "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"
-      "  - OpenCV\n"
-      "    * Boost : sum of votes\n"
-      "    * DecisionTree : (not supported)\n"
-      "    * GradientBoostedTree : (not supported)\n"
-      "    * 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");
+    SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\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"
+      "* Boost: sum of votes\n"
+      "* DecisionTree: (not supported)\n"
+      "* GradientBoostedTree: (not supported)\n"
+      "* 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");
     SetDefaultOutputPixelType( "confmap", ImagePixelType_double);
     MandatoryOff("confmap");
 
diff --git a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
index c0a1a8935fd88ad7937e25c645de9b694118ee2b..a7decdb4bfada38b99d1448a658439843874dcb0 100644
--- a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
@@ -43,18 +43,27 @@ public:
     // Documentation
     SetDocName( "Train a classifier from multiple images" );
     SetDocLongDescription(
-            "This application performs a classifier training from multiple pairs of input images and training vector data. "
-                    "Samples are composed of pixel values in each band optionally centered and reduced using an XML statistics file produced by "
-                    "the ComputeImagesStatistics application.\n The training vector data must contain polygons with a positive integer field "
-                    "representing the class label. The name of this field can be set using the \"Class label field\" parameter. Training and validation "
-                    "sample lists are built such that each class is equally represented in both lists. One parameter allows controlling the ratio "
-                    "between the number of samples in training and validation sets. Two parameters allow managing the size of the training and "
-                    "validation sets per class and per image.\n Several classifier parameters can be set depending on the chosen classifier. In the "
-                    "validation process, the confusion matrix is organized the following way: rows = reference labels, columns = produced labels. "
-                    "In the header of the optional confusion matrix output file, the validation (reference) and predicted (produced) class labels"
-                    " are ordered according to the rows/columns of the confusion matrix.\n This application is based on LibSVM, OpenCV Machine Learning "
-                    "(2.3.1 and later), and Shark ML. The output of this application is a text model file, whose format corresponds to the "
-                    "ML model type chosen. There is no image nor vector data output." );
+        "Train a classifier from multiple pairs of images and training vector data. "
+        "Samples are composed of pixel values in each band optionally centered and reduced using an XML statistics file produced by "
+        "the ComputeImagesStatistics application.\n\n"
+
+        "The training vector data must contain polygons with a positive integer field "
+        "representing the class label. The name of this field can be set using the *Class label field* parameter.\n\n"
+
+        "Training and validation sample lists are built such that each class is equally represented in both lists. One parameter allows controlling the ratio "
+        "between the number of samples in training and validation sets. Two parameters allow managing the size of the training and "
+        "validation sets per class and per image.\n\n"
+
+        "In the validation process, the confusion matrix is organized the following way:\n\n"
+        "* Rows: reference labels,\n"
+        "* Columns: produced labels.\n\n"
+
+        "In the header of the optional confusion matrix output file, the validation (reference) and predicted (produced) class labels"
+        " are ordered according to the rows/columns of the confusion matrix.\n\n"
+
+        "This application is based on LibSVM, OpenCV Machine Learning, and Shark ML. "
+        "The output of this application is a text model file, whose format corresponds to the "
+        "ML model type chosen. There is no image nor vector data output.");
     SetDocLimitations( "None" );
     SetDocAuthors( "OTB-Team" );
     SetDocSeeAlso( "OpenCV documentation for machine learning http://docs.opencv.org/modules/ml/doc/ml.html " );
diff --git a/Modules/Applications/AppClassification/app/otbTrainRegression.cxx b/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
index 6b980fad7e7505015df7810e221046571a1a2e65..a95eb953ca3c276b974198d6a0d09edfc3d3b6e3 100644
--- a/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
@@ -110,15 +110,17 @@ void DoInit() override
     "This application trains a classifier from multiple input images or a csv "
     "file, in order to perform regression. Predictors are composed of pixel "
     "values in each band optionally centered and reduced using an XML "
-    "statistics file produced by the ComputeImagesStatistics application.\n "
+    "statistics file produced by the ComputeImagesStatistics application.\n\n"
+
     "The output value for each predictor is assumed to be the last band "
     "(or the last column for CSV files). Training and validation predictor "
     "lists are built such that their size is inferior to maximum bounds given "
     "by the user, and the proportion corresponds to the balance parameter. "
     "Several classifier parameters can be set depending on the chosen "
     "classifier. In the validation process, the mean square error is computed "
-    "between the ground truth and the estimated model.\n"
-    " This application is based on LibSVM and on OpenCV Machine Learning "
+    "between the ground truth and the estimated model.\n\n"
+
+    "This application is based on LibSVM and on OpenCV Machine Learning "
     "classifiers, and is compatible with OpenCV 2.3.1 and later.");
   SetDocLimitations("None");
   SetDocAuthors("OTB-Team");
diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
index 6f142bb04a28b69588cecb36045ab82eec2e7055..4ca8e9b0313e2de2959e2aaecdaf4fabb381fe17 100644
--- a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
@@ -67,7 +67,7 @@ protected:
       "Learning (2.3.1 and later), and Shark ML The output of this application "
       "is a text model file, whose format corresponds to the ML model type "
       "chosen. There is no image nor vector data output.");
-    SetDocLimitations( " " );
+    SetDocLimitations("");
     SetDocAuthors( "OTB Team" );
     SetDocSeeAlso( " " );
 
diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
index abc87f0098e65f42903a1bbb57a7a0bdc527df64..648b1d465fc5a24ea97791c0a6434c1de05b6ff4 100644
--- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
@@ -131,20 +131,16 @@ private:
       "Put the same field names as the TrainVectorClassifier application.");
 
     AddParameter(ParameterType_Bool, "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"
-      "  - OpenCV\n"
-      "    * Boost : sum of votes\n"
-      "    * DecisionTree : (not supported)\n"
-      "    * GradientBoostedTree : (not supported)\n"
-      "    * 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");
+    SetParameterDescription( "confmap", "Confidence map of the produced classification. The confidence index depends on the model: \n\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"
+      "* Boost: sum of votes\n"
+      "* DecisionTree: (not supported)\n"
+      "* GradientBoostedTree: (not supported)\n"
+      "* 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");
 
     AddParameter(ParameterType_OutputFilename, "out", "Output vector data file containing class labels");
     SetParameterDescription("out","Output vector data file storing sample values (OGR format)."
diff --git a/Modules/Applications/AppClassification/include/otbTrainBoost.hxx b/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
index 7ea1b673f9f35569f19323f6762fae16eac6a536..575e004a95c866725d88ce3ffc4248e04e5293ba 100644
--- a/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitBoostParams()
   {
     AddChoice("classifier.boost", "Boost classifier");
-    SetParameterDescription("classifier.boost", "This group of parameters allows setting Boost classifier parameters. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/boosting.html}.");
+    SetParameterDescription("classifier.boost", "http://docs.opencv.org/modules/ml/doc/boosting.html");
     //BoostType
     AddParameter(ParameterType_Choice, "classifier.boost.t", "Boost Type");
     AddChoice("classifier.boost.t.discrete", "Discrete AdaBoost");
diff --git a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
index 324bc7dd1d8dceabab88635e39d853f1b7c0c2e2..5308a30f35433d29a5871e08b8e346eba5a355aa 100644
--- a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
@@ -35,8 +35,7 @@ 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}.");
+    "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
@@ -65,7 +64,6 @@ LearningApplicationBase<TInputValue,TOutputValue>
     "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");
   //SetParameterDescription("classifier.dt.sur","These splits allow working with missing data and compute variable importance correctly.");
 
   //MaxCategories
diff --git a/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx b/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx
index 719bf8b06e8f4ba74002c635570afb0da5b9babb..40453e232fa851a00aee2d831857d0507995207d 100644
--- a/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainGradientBoostedTree.hxx
@@ -38,8 +38,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
   AddChoice("classifier.gbt", "Gradient Boosted Tree classifier");
   SetParameterDescription(
       "classifier.gbt",
-      "This group of parameters allows setting Gradient Boosted Tree classifier parameters. "
-      "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/gradient_boosted_trees.html}.");
+      "http://docs.opencv.org/modules/ml/doc/gradient_boosted_trees.html");
 
   if (m_RegressionFlag)
     {
@@ -79,9 +78,6 @@ LearningApplicationBase<TInputValue,TOutputValue>
         "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.");
 
-  //UseSurrogates : don't need to be exposed !
-  //AddParameter(ParameterType_Empty, "classifier.gbt.sur", "Surrogate splits will be built");
-  //SetParameterDescription("classifier.gbt.sur","These splits allow working with missing data and compute variable importance correctly.");
 #endif
 }
 
diff --git a/Modules/Applications/AppClassification/include/otbTrainKNN.hxx b/Modules/Applications/AppClassification/include/otbTrainKNN.hxx
index 74639e3a704ef168760b1b1f17a55a34fa069a4c..774253afec19ebefc491dbed3e3a118cbfda06a7 100644
--- a/Modules/Applications/AppClassification/include/otbTrainKNN.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainKNN.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitKNNParams()
   {
     AddChoice("classifier.knn", "KNN classifier");
-    SetParameterDescription("classifier.knn", "This group of parameters allows setting KNN classifier parameters. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/k_nearest_neighbors.html}.");
+    SetParameterDescription("classifier.knn", "http://docs.opencv.org/modules/ml/doc/k_nearest_neighbors.html");
 
     //K parameter
     AddParameter(ParameterType_Int, "classifier.knn.k", "Number of Neighbors");
diff --git a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx
index 72becd8d6bf493c27efaebac78c0312525e90591..3e6f722b8e99cc7d752e29542bc8538d6c273108 100644
--- a/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainNeuralNetwork.hxx
@@ -35,10 +35,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
 ::InitNeuralNetworkParams()
 {
   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}.");
+  SetParameterDescription("classifier.ann", "http://docs.opencv.org/modules/ml/doc/neural_networks.html");
 
   //TrainMethod
   AddParameter(ParameterType_Choice, "classifier.ann.t", "Train Method Type");
diff --git a/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx b/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx
index 59f882356f70ba8946705f707e5ab138997f997b..b1086f997cc577625c3143466129601d8267b731 100644
--- a/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainNormalBayes.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitNormalBayesParams()
   {
     AddChoice("classifier.bayes", "Normal Bayes classifier");
-    SetParameterDescription("classifier.bayes", "Use a Normal Bayes Classifier. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/normal_bayes_classifier.html}.");
+    SetParameterDescription("classifier.bayes", "http://docs.opencv.org/modules/ml/doc/normal_bayes_classifier.html");
 
   }
 
diff --git a/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx b/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx
index 1751f927026bf15c6e0e940df7993c63798e93bd..c306d2f36db5d0e80019b0f6f10762a121ae46ad 100644
--- a/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainRandomForests.hxx
@@ -34,9 +34,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
 ::InitRandomForestsParams()
 {
   AddChoice("classifier.rf", "Random forests classifier");
-  SetParameterDescription("classifier.rf",
-                          "This group of parameters allows setting Random Forests classifier parameters. "
-                          "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/random_trees.html}.");
+  SetParameterDescription("classifier.rf", "http://docs.opencv.org/modules/ml/doc/random_trees.html");
   //MaxDepth
   AddParameter(ParameterType_Int, "classifier.rf.max", "Maximum depth of the tree");
   SetParameterInt("classifier.rf.max",5);
@@ -59,10 +57,6 @@ LearningApplicationBase<TInputValue,TOutputValue>
                           "and the values of the train samples in this node are smaller than this regression accuracy parameter, "
                           "then the node will not be split.");
 
-  //UseSurrogates : don't need to be exposed !
-  //AddParameter(ParameterType_Empty, "classifier.rf.sur", "Surrogate splits will be built");
-  //SetParameterDescription("classifier.rf.sur","These splits allow working with missing data and compute variable importance correctly.");
-
   //MaxNumberOfCategories
   AddParameter(ParameterType_Int, "classifier.rf.cat",
                "Cluster possible values of a categorical variable into K <= cat clusters to find a suboptimal split");
diff --git a/Modules/Applications/AppClassification/include/otbTrainSVM.hxx b/Modules/Applications/AppClassification/include/otbTrainSVM.hxx
index 1e3f47d30fdec82dbd10b4eac21f14cb62cc27c4..16b6343312e93c57b2d46dcb5e30de43491748d9 100644
--- a/Modules/Applications/AppClassification/include/otbTrainSVM.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainSVM.hxx
@@ -34,8 +34,7 @@ namespace Wrapper
   ::InitSVMParams()
   {
     AddChoice("classifier.svm", "SVM classifier (OpenCV)");
-    SetParameterDescription("classifier.svm", "This group of parameters allows setting SVM classifier parameters. "
-        "See complete documentation here \\url{http://docs.opencv.org/modules/ml/doc/support_vector_machines.html}.");
+    SetParameterDescription("classifier.svm", "http://docs.opencv.org/modules/ml/doc/support_vector_machines.html");
     AddParameter(ParameterType_Choice, "classifier.svm.m", "SVM Model Type");
     SetParameterDescription("classifier.svm.m", "Type of SVM formulation.");
     if (this->m_RegressionFlag)
diff --git a/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx b/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx
index f2008908f1f0cb88aca8afbfe72e0f9cfa082824..4c24dc1287247b41f2d7418db2919f928549c522 100644
--- a/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainSharkKMeans.hxx
@@ -31,10 +31,7 @@ template<class TInputValue, class TOutputValue>
 void LearningApplicationBase<TInputValue, TOutputValue>::InitSharkKMeansParams()
 {
   AddChoice( "classifier.sharkkm", "Shark kmeans classifier" );
-  SetParameterDescription( "classifier.sharkkm",
-                           "This group of parameters allows setting Shark kMeans classifier parameters. "
-                                   "See complete documentation here "
-                                   "\\url{http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html}.\n " );
+  SetParameterDescription("classifier.sharkkm", "http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html ");
   //MaxNumberOfIterations
   AddParameter( ParameterType_Int, "classifier.sharkkm.maxiter",
                 "Maximum number of iteration for the kmeans algorithm." );
diff --git a/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx b/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx
index 3160740f3f9ba3bdb50d38d6821b520d2d7b4d27..3559eeabc32ba7a978851b840d66b2b73014f8cb 100644
--- a/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainSharkRandomForests.hxx
@@ -38,8 +38,7 @@ LearningApplicationBase<TInputValue,TOutputValue>
 
   AddChoice("classifier.sharkrf", "Shark Random forests classifier");
   SetParameterDescription("classifier.sharkrf",
-                          "This group of parameters allows setting Shark Random Forests classifier parameters. "
-                          "See complete documentation here \\url{http://image.diku.dk/shark/doxygen_pages/html/classshark_1_1_r_f_trainer.html}.\n It is noteworthy that training is parallel.");
+                          "http://image.diku.dk/shark/doxygen_pages/html/classshark_1_1_r_f_trainer.html.\n It is noteworthy that training is parallel.");
   //MaxNumberOfTrees
   AddParameter(ParameterType_Int, "classifier.sharkrf.nbtrees",
                "Maximum number of trees in the forest");
diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
index e14d7753b4165fb5d472e1d206d582c98553e859..f06d2c78776166f8305b2ffcdd5d36cbddaad72f 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
+++ b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
@@ -108,7 +108,7 @@ private:
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription("out", "output image. Components are ordered by decreasing eigenvalues.");
     MandatoryOff("out");
-    AddParameter(ParameterType_Group, "rescale", "Rescale Output.");
+    AddParameter(ParameterType_Group, "rescale", "Rescale Output");
 
     MandatoryOff("rescale");
     //  AddChoice("rescale.no","No rescale");
@@ -132,10 +132,10 @@ private:
     SetParameterDescription("method.pca", "Principal Component Analysis.");
     AddChoice("method.napca", "NA-PCA");
     SetParameterDescription("method.napca", "Noise Adjusted Principal Component Analysis.");
-    AddParameter(ParameterType_Int, "method.napca.radiusx", "Set the x radius of the sliding window.");
+    AddParameter(ParameterType_Int, "method.napca.radiusx", "Set the x radius of the sliding window");
     SetMinimumParameterIntValue("method.napca.radiusx", 1);
     SetDefaultParameterInt("method.napca.radiusx", 1);
-    AddParameter(ParameterType_Int, "method.napca.radiusy", "Set the y radius of the sliding window.");
+    AddParameter(ParameterType_Int, "method.napca.radiusy", "Set the y radius of the sliding window");
     SetMinimumParameterIntValue("method.napca.radiusy", 1);
     SetDefaultParameterInt("method.napca.radiusy", 1);
 
@@ -143,7 +143,7 @@ private:
     SetParameterDescription("method.maf", "Maximum Autocorrelation Factor.");
     AddChoice("method.ica", "ICA");
     SetParameterDescription("method.ica", "Independent Component Analysis.");
-    AddParameter(ParameterType_Int, "method.ica.iter", "number of iterations ");
+    AddParameter(ParameterType_Int, "method.ica.iter", "number of iterations");
     SetMinimumParameterIntValue("method.ica.iter", 1);
     SetDefaultParameterInt("method.ica.iter", 20);
     MandatoryOff("method.ica.iter");
@@ -158,14 +158,14 @@ private:
     //SetParameterDescription("method.vd","Virtual Dimension.");
     //MandatoryOff("method");
 
-    AddParameter(ParameterType_Int, "nbcomp", "Number of Components.");
+    AddParameter(ParameterType_Int, "nbcomp", "Number of Components");
     SetParameterDescription("nbcomp", "Number of relevant components kept. By default all components are kept.");
     SetDefaultParameterInt("nbcomp", 0);
     MandatoryOff("nbcomp");
     SetMinimumParameterIntValue("nbcomp", 0);
 
-    AddParameter(ParameterType_Bool, "normalize", "Normalize.");
-    SetParameterDescription("normalize", "center AND reduce data before Dimensionality reduction.");
+    AddParameter(ParameterType_Bool, "normalize", "Normalize");
+    SetParameterDescription("normalize", "Center and reduce data before Dimensionality reduction.");
 
     AddParameter(ParameterType_OutputFilename, "outmatrix", "Transformation matrix output (text format)");
     SetParameterDescription("outmatrix", "Filename to store the transformation matrix (csv format)");
diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx
index d9dd8e8816fec2cce2502a81b624a59ce33817ab..4c74b5f1837b0ae47d98f627b57ae58bd404009b 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx
+++ b/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx
@@ -137,7 +137,7 @@ private:
                           "the model. The input pixels"
                           " can be optionally centered and reduced according "
                           "to the statistics file produced by the "
-                          "ComputeImagesStatistics application. ");
+                          "ComputeImagesStatistics application.");
 
     SetDocLimitations("The input image must contain the feature bands used for"
                       " the model training. "
diff --git a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
index dbaced29bca148c94a1e056fbd7e2fd4239942bb..34905e71732644a6edb9a86b2caff9d6cffb1bd3 100644
--- a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
+++ b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
@@ -106,7 +106,7 @@ private:
 
     // Documentation
     SetDocName("DomainTransform");
-    SetDocLongDescription("Domain Transform application for wavelet and fourier");
+    SetDocLongDescription("Domain Transform application for wavelet and fourier.");
     SetDocLimitations("This application is not streamed, check your system resources when processing large images");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("otbWaveletImageFilter, otbWaveletInverseImageFilter, otbWaveletTransform");
@@ -122,8 +122,8 @@ private:
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription("out", "This parameter holds the output file name to"
       " which transformed image will be written. This has a slightly different"
-      " behaviour depending on transform type. \n For Wavelet, output is a"
-      " single band image for both forward and inverse transform. \n For FFT"
+      " behaviour depending on transform type. \nFor Wavelet, output is a"
+      " single band image for both forward and inverse transform. For FFT"
       " forward transform, output is two band image where first band represents"
       " real part and second band represents imaginary part of a complex image.");
 
diff --git a/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx b/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
index 20be637f3db3a1656e48916d6150f385bd3c6a36..ec740ac5f4a937e492ceee933f5839b8160b222e 100644
--- a/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
+++ b/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
@@ -108,9 +108,9 @@ private:
                             "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.");
+    AddParameter(ParameterType_Int, "filter.touzi.xradius", "X radius of the neighborhood");
     SetDefaultParameterInt("filter.touzi.xradius", 1);
-    AddParameter(ParameterType_Int, "filter.touzi.yradius", "The Y radius of the neighborhood.");
+    AddParameter(ParameterType_Int, "filter.touzi.yradius", "Y radius of the neighborhood");
     SetDefaultParameterInt("filter.touzi.yradius", 1);
 
     // Canny Section
diff --git a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
index c07919eae5f97c234103857807ea2098a4396388..eadc312fb14c87b0f0f0f5c1ed61947843c8a899 100644
--- a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
+++ b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
@@ -164,13 +164,13 @@ private:
       "over the image and then use the whole dynamic: meaning flattening the "
       "histogram. That gives us gain for each bin that transform the original "
       "histogram into the flat one. This gain is then apply on the original "
-      "image." 
-      "\nThe application proposes several options to allow a finer result: "
-      "\n- There is an option to limit contrast. We choose to limit the contrast "
+      "image.\n\n"
+      "The application proposes several options to allow a finer result:\n\n"
+      "* There is an option to limit contrast. We choose to limit the contrast "
       "by modifying the original histogram. To do so we clip the histogram at a "
       "given height and redistribute equally among the bins the clipped population. "
-      "Then we add a local version of the algorithm. "
-       "\n- It is possible to apply the algorithm on tiles of the image, instead "
+      "Then we add a local version of the algorithm.\n"
+      "* It is possible to apply the algorithm on tiles of the image, instead "
       "of on the whole image. That gives us gain depending on "
       "the value of the pixel and its position in the image. In order to "
       "smoothen the result we interpolate the gain between tiles.");
diff --git a/Modules/Applications/AppFusion/app/otbPansharpening.cxx b/Modules/Applications/AppFusion/app/otbPansharpening.cxx
index fce89cc116cddd05c4d3271cbc0d05304cff703a..fda0827b4f9b2e1ce06b91c22de6607540572aed 100644
--- a/Modules/Applications/AppFusion/app/otbPansharpening.cxx
+++ b/Modules/Applications/AppFusion/app/otbPansharpening.cxx
@@ -94,7 +94,7 @@ private:
     SetParameterDescription("inxs"," Input XS image.");
 
     AddParameter(ParameterType_OutputImage,  "out",   "Output image");
-    SetParameterDescription("out"," Output image.");
+    SetParameterDescription("out", "Output image.");
 
     AddParameter(ParameterType_Choice, "method", "Algorithm");
     SetParameterDescription("method", "Selection of the pan-sharpening method.");
diff --git a/Modules/Applications/AppImageUtils/app/CMakeLists.txt b/Modules/Applications/AppImageUtils/app/CMakeLists.txt
index e89f03ee6f9ca3ae2b2e931e455411704f99a63d..b3834d621c17924421e8e9158e31a697d18b0e76 100644
--- a/Modules/Applications/AppImageUtils/app/CMakeLists.txt
+++ b/Modules/Applications/AppImageUtils/app/CMakeLists.txt
@@ -23,12 +23,6 @@ otb_create_application(
   SOURCES        otbDownloadSRTMTiles.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
 
-
-otb_create_application(
-  NAME           Convert
-  SOURCES        otbConvert.cxx
-  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
-
 otb_create_application(
   NAME           PixelValue
   SOURCES        otbPixelValue.cxx
diff --git a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
index aa7dc56e68168f2397d4dd10c38f28992045efbc..e86d90c5184dabba1929ef7e39f56aee4206a660 100644
--- a/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbColorMapping.cxx
@@ -251,21 +251,26 @@ private:
   void DoInit() override
   {
     SetName("ColorMapping");
-    SetDescription("Maps an input label image to 8-bits RGB using look-up tables.");
+    SetDescription("Map a label image to 8-bits RGB using look-up tables.");
 
     SetDocName("Color Mapping");
-    SetDocLongDescription("This application allows one to map a label image to a 8-bits RGB image (in both ways) using different methods.\n"
-                          " -The custom method allows one to use a custom look-up table. The look-up table is loaded "
-                          "from a text file where each line describes an entry. The typical use of this method is to colorise a "
-                          "classification map.\n -The continuous method allows mapping a range of values in a scalar input image "
-                          "to a colored image using continuous look-up table, in order to enhance image interpretation. Several "
-                          "look-up tables can been chosen with different color ranges.\n-The optimal method computes an optimal "
-                          "look-up table. When processing a segmentation label image (label to color), the color difference between"
-                          " adjacent segmented regions is maximized. When processing an unknown color image (color to label), all "
-                          "the present colors are mapped to a continuous label list.\n - The support image method uses a color support "
-                          "image to associate an average color to each region.");
+    SetDocLongDescription(
+        "Map a label image to a 8-bits RGB image (both ways) using different methods:\n\n"
+
+        "* **Custom**: use a custom look-up table. The look-up table is loaded "
+        "from a text file where each line describes an entry. The typical use of this method is to colorise a "
+        "classification map.\n"
+        "* **Continuous**: Map a range of values in a scalar input image "
+        "to a colored image using continuous look-up table, in order to enhance image interpretation. Several "
+        "look-up tables can been chosen with different color ranges.\n"
+        "* **Optimal**: Compute an optimal "
+        "look-up table. When processing a segmentation label image (label to color), the color difference between"
+        " adjacent segmented regions is maximized. When processing an unknown color image (color to label), all "
+        "the present colors are mapped to a continuous label list.\n"
+        "* **Support image**: Use a color support image to associate an average color to each region.");
+
     SetDocLimitations("The segmentation optimal method does not support streaming, and thus large images. The operation color to label "
-                      "is not implemented for the methods continuous LUT and support image LUT.\n ColorMapping using support image is not threaded.");
+                      "is not implemented for the methods continuous LUT and support image LUT.\n\nColorMapping using support image is not threaded.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("ImageSVMClassifier");
 
@@ -299,7 +304,7 @@ private:
 
     // --- OPERATION --- : Label to color / Color to label
     AddParameter(ParameterType_Choice, "op", "Operation");
-    SetParameterDescription("op","Selection of the operation to execute (default is : label to color).");
+    SetParameterDescription("op", "Selection of the operation to execute (default is: label to color).");
 
     AddChoice("op.labeltocolor","Label to color");
 
diff --git a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx
index 643d643fdf9535afb3ab02106bfafb96a0daf276..f2eb49f7afbf7ae154ac9e92e079fee5bf14a38c 100644
--- a/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbCompareImages.cxx
@@ -56,7 +56,10 @@ private:
 
     // Documentation
     SetDocName("Images comparison");
-    SetDocLongDescription("This application computes MSE (Mean Squared Error), MAE (Mean Absolute Error) and PSNR (Peak Signal to Noise Ratio) between the channel of two images (reference and measurement). The user has to set the used channel and can specify a ROI.");
+    SetDocLongDescription(
+        "Compute MSE (Mean Squared Error), MAE (Mean Absolute Error) and PSNR (Peak Signal to Noise Ratio) between two image bands (reference and measurement). "
+        "The user has to set the used channel and can specify a ROI."
+    );
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("BandMath application, ImageStatistics");
@@ -65,17 +68,17 @@ private:
 
     AddParameter(ParameterType_Group, "ref", "Reference image properties");
     AddParameter(ParameterType_InputImage,  "ref.in",   "Reference image");
-    SetParameterDescription("ref.in", "Image used as reference in the comparison");
+    SetParameterDescription("ref.in", "Image used as reference in the comparison.");
     AddParameter(ParameterType_Int,  "ref.channel",   "Reference image channel");
-    SetParameterDescription("ref.channel", "Used channel for the reference image");
+    SetParameterDescription("ref.channel", "Used channel for the reference image.");
     SetDefaultParameterInt("ref.channel", 1);
     SetMinimumParameterIntValue("ref.channel", 1);
 
     AddParameter(ParameterType_Group, "meas", "Measured image properties");
     AddParameter(ParameterType_InputImage,  "meas.in",   "Measured image");
-    SetParameterDescription("meas.in", "Image used as measured in the comparison");
+    SetParameterDescription("meas.in", "Image used as measured in the comparison.");
     AddParameter(ParameterType_Int,  "meas.channel",   "Measured image channel");
-    SetParameterDescription("meas.channel", "Used channel for the measured image");
+    SetParameterDescription("meas.channel", "Used channel for the measured image.");
     SetDefaultParameterInt("meas.channel", 1);
     SetMinimumParameterIntValue("meas.channel", 1);
 
@@ -102,19 +105,19 @@ private:
     SetParameterDescription("roi.sizey","Size along y in pixels.");
 
     AddParameter(ParameterType_Float, "mse",  "MSE");
-    SetParameterDescription("mse", "Mean Squared Error value");
+    SetParameterDescription("mse", "Mean Squared Error value.");
     SetParameterRole("mse", Role_Output );
 
     AddParameter(ParameterType_Float, "mae",  "MAE");
-    SetParameterDescription("mae", "Mean Absolute Error value");
+    SetParameterDescription("mae", "Mean Absolute Error value.");
     SetParameterRole("mae", Role_Output );
 
     AddParameter(ParameterType_Float, "psnr",  "PSNR");
-    SetParameterDescription("psnr", "Peak Signal to Noise Ratio value");
+    SetParameterDescription("psnr", "Peak Signal to Noise Ratio value.");
     SetParameterRole("psnr", Role_Output);
 
     AddParameter(ParameterType_Float, "count",  "count");
-    SetParameterDescription("count", "Nb of pixels which are different");
+    SetParameterDescription("count", "Nb of pixels which are different.");
     SetParameterRole("count", Role_Output);
 
     AddRAMParameter();
diff --git a/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx b/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
index 0c9d52659cf8864c387b70388470f51b9114db59..7f84bc254a493d2cff68f7446af7f1c7353e50bb 100644
--- a/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
@@ -57,16 +57,16 @@ private:
   void DoInit() override
   {
     SetName("ConcatenateImages");
-    SetDescription("Concatenate a list of images of the same size into a single multi-channel one.");
+    SetDescription("Concatenate a list of images of the same size into a single multi-channel image.");
 
     // Documentation
     SetDocName("Images Concatenation");
-    SetDocLongDescription("This application performs images channels concatenation. "
+    SetDocLongDescription("Concatenate a list of images of the same size into a single multi-channel image. "
       "It reads the input image list (single or multi-channel) "
       "and generates a single multi-channel image. The channel order is the same as the list.");
     SetDocLimitations("All input images must have the same size.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("Rescale application, Convert, SplitImage");
+    SetDocSeeAlso("Rescale application, DynamicConvert, SplitImage");
 
     AddDocTag(Tags::Manip);
     AddDocTag("Concatenation");
diff --git a/Modules/Applications/AppImageUtils/app/otbConvert.cxx b/Modules/Applications/AppImageUtils/app/otbConvert.cxx
deleted file mode 100644
index 05575df8512d384840f57638bd15d53fcf559069..0000000000000000000000000000000000000000
--- a/Modules/Applications/AppImageUtils/app/otbConvert.cxx
+++ /dev/null
@@ -1,519 +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 <numeric>
-
-#include "otbWrapperApplication.h"
-#include "otbWrapperApplicationFactory.h"
-
-#include "otbVectorRescaleIntensityImageFilter.h"
-#include "otbFunctorImageFilter.h"
-#include "otbStreamingShrinkImageFilter.h"
-#include "itkListSample.h"
-#include "otbListSampleToHistogramListGenerator.h"
-#include "itkImageRegionConstIterator.h"
-
-#include "otbImageListToVectorImageFilter.h"
-#include "otbMultiToMonoChannelExtractROI.h"
-#include "otbImageList.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-
-class Convert : public Application
-{
-public:
-  /** Standard class typedefs. */
-  typedef Convert                       Self;
-  typedef Application                   Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Standard macro */
-  itkNewMacro(Self);
-
-  itkTypeMacro(Convert, otb::Application);
-
-  /** Filters typedef */
-  typedef itk::Statistics::ListSample<FloatVectorImageType::PixelType> ListSampleType;
-  typedef itk::Statistics::DenseFrequencyContainer2 DFContainerType;
-  typedef ListSampleToHistogramListGenerator<ListSampleType,
-                                             FloatVectorImageType::InternalPixelType,
-                                             DFContainerType> HistogramsGeneratorType;
-  typedef StreamingShrinkImageFilter<FloatVectorImageType,
-                                     FloatVectorImageType> ShrinkFilterType;
-
-private:
-
-  void DoInit() override
-  {
-    SetName("Convert");
-    SetDescription("Convert an image to a different format, optionally rescaling the data"
-                   " and/or changing the pixel type.");
-    // Documentation
-    SetDocName("Image Conversion");
-    SetDocLongDescription("This application performs an image pixel type conversion "
-      "(short, ushort, uchar, int, uint, float and double types are handled). "
-      "The output image is written in the specified format (ie. that corresponds "
-      "to the given extension).\n The conversion can include a rescale of the data range, "
-      "by default it's set from 2% to 98% of the data values. The rescale can be linear or log2. \n "
-      "The choice of the output channels can be done with the extended filename, "
-      "but less easy to handle. To do this, a 'channels' parameter allows you to select "
-      "the desired bands at the output. There are 3 modes, the available choices are: \n"
-        " * grayscale :  to display mono image as standard color image \n"
-        " * rgb : select 3 bands in the input image (multi-bands) \n"
-        " * all : keep all bands.");
-    SetDocLimitations("The application does not support complex pixel types as output.");
-    SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("Rescale");
-
-    AddDocTag(Tags::Deprecated);
-    AddDocTag(Tags::Manip);
-    AddDocTag("Conversion");
-    AddDocTag("Image Dynamic");
-
-    AddParameter(ParameterType_InputImage, "in", "Input image");
-    SetParameterDescription("in", "Input image");
-
-    AddParameter(ParameterType_Choice, "type", "Rescale type");
-    SetParameterDescription("type", "Transfer function for the rescaling");
-    AddChoice("type.none", "None");
-    AddChoice("type.linear", "Linear");
-    AddChoice("type.log2", "Log2");
-    SetParameterString("type", "none");
-
-    AddParameter(ParameterType_Float,"type.linear.gamma","Gamma correction factor");
-    SetParameterDescription("type.linear.gamma","Gamma correction factor");
-    SetDefaultParameterFloat("type.linear.gamma",1.0);
-    MandatoryOff("type.linear.gamma");
-
-    AddParameter(ParameterType_InputImage,  "mask",   "Input mask");
-    SetParameterDescription("mask",
-      "Optional mask to indicate which pixels are valid for computing the histogram quantiles. "
-      "Only pixels where the mask is less than 0.5 will contribute to the histogram. "
-      "The mask must have the same dimensions as the input image.");
-    MandatoryOff("mask");
-    DisableParameter("mask");
-
-    AddParameter(ParameterType_Group,"hcp","Histogram Cutting Parameters");
-    SetParameterDescription("hcp","Parameters to cut the histogram edges before rescaling");
-
-    AddParameter(ParameterType_Float, "hcp.high", "High Cut Quantile");
-    SetParameterDescription("hcp.high", "Quantiles to cut from histogram high values "
-      "before computing min/max rescaling (in percent, 2 by default)");
-    MandatoryOff("hcp.high");
-    SetDefaultParameterFloat("hcp.high", 2.0);
-    DisableParameter("hcp.high");
-
-    AddParameter(ParameterType_Float, "hcp.low", "Low Cut Quantile");
-    SetParameterDescription("hcp.low", "Quantiles to cut from histogram low values "
-      "before computing min/max rescaling (in percent, 2 by default)");
-    MandatoryOff("hcp.low");
-    SetDefaultParameterFloat("hcp.low", 2.0);
-    DisableParameter("hcp.low");
-
-    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
-    SetParameterDescription("out", "Output image");
-    SetDefaultOutputPixelType("out",ImagePixelType_uint8);
-
-    AddParameter(ParameterType_Choice, "channels", "Channels selection");
-    SetParameterDescription("channels", "It's possible to select the channels "
-      "of the output image. There are 3 modes, the available choices are:");
-
-    AddChoice("channels.all", "Default mode");
-    SetParameterDescription("channels.all", "Select all bands in the input image, (1,...,n).");
-
-    AddChoice("channels.grayscale", "Grayscale mode");
-    SetParameterDescription("channels.grayscale", "Display single channel as standard color image.");
-    AddParameter(ParameterType_Int, "channels.grayscale.channel", "Grayscale channel");
-    SetDefaultParameterInt("channels.grayscale.channel", 1);
-    SetMinimumParameterIntValue("channels.grayscale.channel", 1);
-
-    AddChoice("channels.rgb", "RGB composition");
-    SetParameterDescription("channels.rgb", "Select 3 bands in the input image "
-      "(multi-bands), by default (1,2,3).");
-
-    AddParameter(ParameterType_Int, "channels.rgb.red", "Red Channel");
-    SetParameterDescription("channels.rgb.red", "Red channel index.");
-    SetMinimumParameterIntValue("channels.rgb.red", 1);
-    AddParameter(ParameterType_Int, "channels.rgb.green", "Green Channel");
-    SetParameterDescription("channels.rgb.green", "Green channel index.");
-    SetMinimumParameterIntValue("channels.rgb.green", 1);
-    AddParameter(ParameterType_Int, "channels.rgb.blue", "Blue Channel");
-    SetParameterDescription("channels.rgb.blue", "Blue channel index.");
-    SetMinimumParameterIntValue("channels.rgb.blue", 1);
-
-    AddRAMParameter();
-
-    // Doc example parameter settings
-    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
-    SetDocExampleParameterValue("out", "otbConvertWithScalingOutput.png");
-    SetDocExampleParameterValue("type", "linear");
-    SetDocExampleParameterValue("channels", "rgb");
-
-    SetOfficialDocLink();
-  }
-
-  void DoUpdateParameters() override
-  {
-    // Read information
-    if ( HasValue("in") )
-      {
-      typedef otb::ImageMetadataInterfaceBase ImageMetadataInterfaceType;
-      ImageMetadataInterfaceType::Pointer metadataInterface =
-      ImageMetadataInterfaceFactory::CreateIMI(GetParameterImage("in")->GetMetaDataDictionary());
-
-      int nbBand = GetParameterImage("in")->GetNumberOfComponentsPerPixel();
-      SetMaximumParameterIntValue("channels.grayscale.channel", nbBand);
-      SetMaximumParameterIntValue("channels.rgb.red", nbBand);
-      SetMaximumParameterIntValue("channels.rgb.green", nbBand);
-      SetMaximumParameterIntValue("channels.rgb.blue", nbBand);
-
-      if (nbBand > 1)
-        {
-        // get band index : Red/Green/Blue
-        int bandRed = metadataInterface->GetDefaultDisplay()[0] + 1;
-        int bandGreen = metadataInterface->GetDefaultDisplay()[1] + 1;
-        int bandBlue = metadataInterface->GetDefaultDisplay()[2] + 1;
-        SetDefaultParameterInt("channels.rgb.red", bandRed);
-        SetDefaultParameterInt("channels.rgb.green", bandGreen);
-        SetDefaultParameterInt("channels.rgb.blue", bandBlue);
-        }
-      }
-
-
-  }
-
-  template<class TImageType>
-  void GenericDoExecute()
-  {
-
-    // Clear previously registered filters
-    m_Filters.clear();
-    
-    std::string rescaleType = this->GetParameterString("type");
-
-    if( (rescaleType != "none") && (rescaleType != "linear") && (rescaleType != "log2") )
-      {
-      itkExceptionMacro("Unknown rescale type "<<rescaleType<<".");
-      }
-
-    if( rescaleType == "none" )
-      {
-      // selected channel
-      typename TImageType::Pointer tempImage;
-      tempImage = GetSelectedChannels<TImageType>();
-
-      SetParameterOutputImage<TImageType>("out", tempImage);
-
-      }
-    else // linear or log2
-      {
-      FloatVectorImageType::Pointer mask;
-
-      if (IsParameterEnabled("mask")) mask = this->GetParameterImage("mask");
-
-      // selected channel
-      typename FloatVectorImageType::Pointer tempImage;
-      tempImage = GetSelectedChannels<FloatVectorImageType>();
-
-      const unsigned int nbComp(tempImage->GetNumberOfComponentsPerPixel());
-
-      typedef otb::VectorRescaleIntensityImageFilter<FloatVectorImageType, TImageType> RescalerType;
-      typename TImageType::PixelType minimum;
-      typename TImageType::PixelType maximum;
-      minimum.SetSize(nbComp);
-      maximum.SetSize(nbComp);
-      minimum.Fill( itk::NumericTraits<typename TImageType::InternalPixelType>::min() );
-      maximum.Fill( itk::NumericTraits<typename TImageType::InternalPixelType>::max() );
-
-      typename RescalerType::Pointer rescaler = RescalerType::New();
-
-      rescaler->SetOutputMinimum(minimum);
-      rescaler->SetOutputMaximum(maximum);
-
-      // We need to subsample the input image in order to estimate its
-      // histogram
-
-      typename ShrinkFilterType::Pointer shrinkFilter = ShrinkFilterType::New();
-
-      // Shrink factor is computed so as to load a quicklook of 1000
-      // pixels square at most
-      typename FloatVectorImageType::SizeType imageSize = tempImage->GetLargestPossibleRegion().GetSize();
-      unsigned int shrinkFactor =
-        std::max(imageSize[0], imageSize[1]) < 1000 ? 1 : std::max(imageSize[0], imageSize[1])/1000;
-
-      otbAppLogDEBUG( << "Shrink factor used to compute Min/Max: "<<shrinkFactor );
-
-      otbAppLogDEBUG( << "Shrink starts..." );
-
-      shrinkFilter->SetShrinkFactor(shrinkFactor);
-      shrinkFilter->GetStreamer()->SetAutomaticAdaptativeStreaming(GetParameterInt("ram"));
-      AddProcess(shrinkFilter->GetStreamer(), "Computing shrink Image for min/max estimation...");
-
-      if ( rescaleType == "log2")
-        {
-	  // define lambda function that applies a log to all bands of the input pixel
-	  auto logFunction = [](FloatVectorImageType::PixelType & vectorOut, const FloatVectorImageType::PixelType & vectorIn) {
-	    assert(vectorOut.Size() == vectorIn.Size() && "Input vector types don't have the same size");
-
-	    for (unsigned int i = 0; i < vectorIn.Size() ; i++) {
-	      vectorOut[i] = std::log(vectorIn[i]);
-	    }
-	    
-	  };
-	  // creates functor filter
-	  auto transferLogFilter = NewFunctorFilter(logFunction,tempImage->GetNumberOfComponentsPerPixel(),{{0,0}});
-
-	  // save a reference to the functor
-	  m_Filters.push_back(transferLogFilter.GetPointer());
-	  
-	  transferLogFilter->SetVariadicInputs(tempImage);
-	  transferLogFilter->UpdateOutputInformation();
-	
-	  shrinkFilter->SetInput(transferLogFilter->GetOutput());
-	  rescaler->SetInput(transferLogFilter->GetOutput());
-	  shrinkFilter->Update();
-        }
-      else
-        {
-	  shrinkFilter->SetInput(tempImage);
-	  rescaler->SetInput(tempImage);
-	  shrinkFilter->Update();
-        }
-      
-      ShrinkFilterType::Pointer maskShrinkFilter = ShrinkFilterType::New();
-
-      otbAppLogDEBUG( << "Evaluating input Min/Max..." );
-      itk::ImageRegionConstIterator<FloatVectorImageType>
-        it(shrinkFilter->GetOutput(), shrinkFilter->GetOutput()->GetLargestPossibleRegion());
-      itk::ImageRegionConstIterator<FloatVectorImageType> itMask;
-
-      typename ListSampleType::Pointer listSample = ListSampleType::New();
-      listSample->SetMeasurementVectorSize(tempImage->GetNumberOfComponentsPerPixel());
-
-      // Now we generate the list of samples
-      if (IsParameterEnabled("mask"))
-        {
-        maskShrinkFilter->SetShrinkFactor(shrinkFactor);
-        maskShrinkFilter->SetInput(mask);
-        maskShrinkFilter->GetStreamer()->SetAutomaticAdaptativeStreaming(GetParameterInt("ram"));
-        maskShrinkFilter->Update();
-
-        itMask = itk::ImageRegionConstIterator<FloatVectorImageType>(
-          maskShrinkFilter->GetOutput(),maskShrinkFilter->GetOutput()->GetLargestPossibleRegion());
-
-        // Remove masked pixels
-        it.GoToBegin();
-        itMask.GoToBegin();
-        while (!it.IsAtEnd())
-          {
-          // float values, so the threshold is set to 0.5
-          if (itMask.Get()[0] < 0.5)
-            {
-            listSample->PushBack(it.Get());
-            }
-          ++it;
-          ++itMask;
-          }
-        if (listSample->Size() == 0)
-          {
-          otbAppLogINFO( << "All pixels were masked, the application assume a wrong mask "
-            "and include all the image");
-          }
-        }
-
-      // if mask is disable and all pixels were masked
-      if ((!IsParameterEnabled("mask")) || (listSample->Size() == 0))
-        {
-        for(it.GoToBegin(); !it.IsAtEnd(); ++it)
-          {
-          listSample->PushBack(it.Get());
-          }
-        }
-
-      // And then the histogram
-      typename HistogramsGeneratorType::Pointer histogramsGenerator = HistogramsGeneratorType::New();
-      histogramsGenerator->SetListSample(listSample);
-      histogramsGenerator->SetNumberOfBins(255);
-      histogramsGenerator->NoDataFlagOn();
-      histogramsGenerator->Update();
-
-      // And extract the lower and upper quantile
-      typename FloatVectorImageType::PixelType inputMin(nbComp), inputMax(nbComp);
-
-      auto histOutput = histogramsGenerator->GetOutput();
-      assert(histOutput);
-
-      for(unsigned int i = 0; i < nbComp; ++i)
-        {
-        auto && elm = histOutput->GetNthElement(i);
-        assert(elm);
-        inputMin[i] = elm->Quantile(0, 0.01 * GetParameterFloat("hcp.low"));
-        inputMax[i] = elm->Quantile(0, 1.0 - 0.01 * GetParameterFloat("hcp.high"));
-        }
-
-      otbAppLogDEBUG( << std::setprecision(5) << "Min/Max computation done : min=" << inputMin
-                      << " max=" << inputMax );
-
-      rescaler->AutomaticInputMinMaxComputationOff();
-      rescaler->SetInputMinimum(inputMin);
-      rescaler->SetInputMaximum(inputMax);
-
-      if ( rescaleType == "linear")
-        {
-        rescaler->SetGamma(GetParameterFloat("type.linear.gamma"));
-        }
-
-      m_Filters.push_back(rescaler.GetPointer());
-
-      SetParameterOutputImage<TImageType>("out", rescaler->GetOutput());
-      }
-  }
-
-  // Get the bands order
-  std::vector<int> GetChannels()
-  {
-    std::vector<int> channels;
-
-    int nbChan = GetParameterImage("in")->GetNumberOfComponentsPerPixel();
-    std::string channelMode = GetParameterString("channels");
-
-    if(channelMode == "grayscale")
-    {
-      if (GetParameterInt("channels.grayscale.channel") <= nbChan)
-      {
-        channels = {GetParameterInt("channels.grayscale.channel"),
-                    GetParameterInt("channels.grayscale.channel"),
-                    GetParameterInt("channels.grayscale.channel")};
-      }
-      else
-      {
-        itkExceptionMacro(<< "The channel has an invalid index");
-      }
-    }
-    else if (channelMode == "rgb")
-    {
-      if ((GetParameterInt("channels.rgb.red") <= nbChan)
-      && ( GetParameterInt("channels.rgb.green") <= nbChan)
-      && ( GetParameterInt("channels.rgb.blue")   <= nbChan))
-      {
-        channels = {GetParameterInt("channels.rgb.red"),
-                    GetParameterInt("channels.rgb.green"),
-                    GetParameterInt("channels.rgb.blue")};
-      }
-      else
-      {
-        itkExceptionMacro(<< "At least one needed channel has an invalid index");
-      }
-    }
-    else if (channelMode == "all")
-    {
-      // take all bands
-      channels.resize(nbChan);
-      std::iota(channels.begin(), channels.end(), 1);
-    }
-    return channels;
-  }
-
-  // return an image with the bands order modified of the input image
-  template<class TImageType>
-  typename TImageType::Pointer GetSelectedChannels()
-  {
-    typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,
-                                         typename TImageType::InternalPixelType>  ExtractROIFilterType;
-    typedef otb::ImageList<otb::Image<typename TImageType::InternalPixelType> >   ImageListType;
-    typedef ImageListToVectorImageFilter<ImageListType,
-                                         TImageType >                             ListConcatenerFilterType;
-
-    typename ImageListType::Pointer             imageList;
-    typename ListConcatenerFilterType::Pointer  concatener;
-
-    imageList = ImageListType::New();
-    concatener = ListConcatenerFilterType::New();
-
-    //m_Filters.push_back(imageList.GetPointer());
-    m_Filters.push_back(concatener.GetPointer());
-    
-    const bool monoChannel = IsParameterEnabled("channels.grayscale");
-
-    // get band order
-    std::vector<int> channels = GetChannels();
-
-    for (auto && channel : channels)
-    {
-      typename ExtractROIFilterType::Pointer extractROIFilter = ExtractROIFilterType::New();
-      m_Filters.push_back(extractROIFilter.GetPointer());
-      extractROIFilter->SetInput(GetParameterImage("in"));
-      if (!monoChannel) extractROIFilter->SetChannel(channel);
-      extractROIFilter->UpdateOutputInformation();
-      imageList->PushBack(extractROIFilter->GetOutput());
-    }
-
-    concatener->SetInput(imageList);
-    concatener->UpdateOutputInformation();
-
-    return concatener->GetOutput();
-  }
-
-
-  void DoExecute() override
-  {
-    switch ( this->GetParameterOutputImagePixelType("out") )
-      {
-      case ImagePixelType_uint8:
-        GenericDoExecute<UInt8VectorImageType>();
-        break;
-      case ImagePixelType_int16:
-        GenericDoExecute<Int16VectorImageType>();
-        break;
-      case ImagePixelType_uint16:
-        GenericDoExecute<UInt16VectorImageType>();
-        break;
-      case ImagePixelType_int32:
-        GenericDoExecute<Int32VectorImageType>();
-        break;
-      case ImagePixelType_uint32:
-        GenericDoExecute<UInt32VectorImageType>();
-        break;
-      case ImagePixelType_float:
-        GenericDoExecute<FloatVectorImageType>();
-        break;
-      case ImagePixelType_double:
-        GenericDoExecute<DoubleVectorImageType>();
-        break;
-      default:
-        itkExceptionMacro("Unknown pixel type " << this->GetParameterOutputImagePixelType("out") <<"." << std::endl
-                          << "The Convert application does not support complex pixel type as output." << std::endl
-                          << "You can use instead the ExtractROI application to perform complex image conversion.");
-        break;
-      }
-  }
-
-  std::vector<itk::LightObject::Pointer> m_Filters;
-};
-
-}
-}
-
-OTB_APPLICATION_EXPORT(otb::Wrapper::Convert)
-
diff --git a/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx b/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx
index 3092ddde38f238c8d43ab8662fa7911cd2c80c82..6c857b942211bb4bae9a4cc1910b5a7e285469e5 100644
--- a/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx
@@ -230,7 +230,7 @@ private:
       "check which tiles are already downloaded.");
 
     // UserDefined values
-    AddParameter(ParameterType_Choice, "mode", "Download/List corresponding SRTM tiles.");
+    AddParameter(ParameterType_Choice, "mode", "Download/List corresponding SRTM tiles");
 
     AddChoice("mode.download", "Download");
     SetParameterDescription("mode.download","Download corresponding tiles on USGE server.");
diff --git a/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
index aba074743be5622bbd43df85ee42c2e02516b86f..ebfeacb421326446d547ed12b03ac2c3a5927f17 100644
--- a/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
@@ -74,21 +74,25 @@ private:
     SetDescription("Change the pixel type and rescale the image's dynamic");
 
     SetDocName("Dynamic Conversion");
-    SetDocLongDescription("This application performs an image pixel type "
+    SetDocLongDescription(
+      "This application performs an image pixel type "
       "conversion (short, ushort, uchar, int, uint, float and double types are "
       "handled). The output image is written in the specified format (ie. "
-      "that corresponds to the given extension).\n The conversion can include "
-      "a rescale of the data range, by default it's set between the 2nd to "
-      "the 98th percentile. The rescale can be linear or log2. \n The choice "
-      "of the output channels can be done with the extended filename, but "
+      "that corresponds to the given extension).\n"
+      "The conversion can include a rescale of the data range, by default it's set between the 2nd to "
+      "the 98th percentile. The rescale can be linear or log2. \n"
+      "The choice of the output channels can be done with the extended filename, but "
       "less easy to handle. To do this, a 'channels' parameter allows you to "
       "select the desired bands at the output. There are 3 modes, the "
-      "available choices are: \n * grayscale :  to display mono image as "
-      "standard color image \n * rgb : select 3 bands in the input image "
-      "(multi-bands) \n * all : keep all bands.");
+      "available choices are: \n\n"
+
+      "* **All**: keep all bands.\n"
+      "* **Grayscale**: to display mono image as standard color image \n"
+      "* **RGB**: select 3 bands in the input image (multi-bands)\n"
+    );
     SetDocLimitations("The application does not support complex pixel types as output.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("Convert, Rescale");
+    SetDocSeeAlso("Rescale");
 
     AddDocTag(Tags::Manip);
     AddDocTag("Conversion");
diff --git a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
index 521b0aec1ac2c962f9a4c6ed7091e1dd99739128..d77519943028f5347d62367d1a4091bd2b563f76 100644
--- a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
@@ -81,7 +81,7 @@ private:
       "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 "
+      "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. "
@@ -103,14 +103,14 @@ private:
     AddParameter(ParameterType_Choice,"mode","Extraction mode");
     AddChoice("mode.standard","Standard");
     SetParameterDescription("mode.standard",
-      "In standard mode extraction is done with 2 parameters : the "
+      "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 
+    // 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.");
+      "In fit mode, extract is made from a reference: image or vector dataset.");
 
     AddParameter( ParameterType_InputImage , "mode.fit.im" , 
       "Reference image" );
@@ -122,28 +122,25 @@ private:
       "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)
+    // 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 : "
+      "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." );
+
+    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" );
@@ -160,7 +157,7 @@ private:
       "the latitude.");
 
 
-    // Radius mode : ROI is computed through a point and a radius
+    // 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 "
diff --git a/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx b/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx
index f31b64075bec5a3d90dcb6e8c04d2685a555ecde..e285d8c96a8b5d8228740db66ebd6b09eb43469a 100644
--- a/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbQuicklook.cxx
@@ -58,9 +58,9 @@ private:
     SetName("Quicklook");
     SetDescription("Generates a subsampled version of an image extract");
     SetDocName("Quick Look");
-    SetDocLongDescription("Generates a subsampled version of an extract of an image defined by ROIStart and ROISize.\n "
+    SetDocLongDescription("Generates a subsampled version of an extract of an image defined by ROIStart and ROISize.\n"
                           "This extract is subsampled using the ratio OR the output image Size.");
-    SetDocLimitations(" This application does not provide yet the optimal way to decode coarser level of resolution from JPEG2000 images (like in Monteverdi).\n"
+    SetDocLimitations("This application does not provide yet the optimal way to decode coarser level of resolution from JPEG2000 images (like in Monteverdi).\n"
                       "Trying to subsampled huge JPEG200 image with the application will lead to poor performances for now.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
@@ -100,12 +100,12 @@ private:
     MandatoryOff("sr");
 
     AddParameter(ParameterType_Int, "sx",  "Size X");
-    SetParameterDescription( "sx" , "quicklook size in x-direction (used if no sampling ration is given)" );
+    SetParameterDescription( "sx" , "quicklook size in x-direction (used if no sampling ratio is given)" );
     MandatoryOff("sx");
     DisableParameter("sx");
 
     AddParameter(ParameterType_Int, "sy",  "Size Y");
-    SetParameterDescription( "sy" , "quicklook size in y-direction (used if no sampling ration is given)" );
+    SetParameterDescription( "sy" , "quicklook size in y-direction (used if no sampling ratio is given)" );
     MandatoryOff("sy");
     DisableParameter("sy");
 
diff --git a/Modules/Applications/AppImageUtils/test/CMakeLists.txt b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
index 4e099298e98ab6930a22e531b09108b24c9fa3ec..187ad31a80de51fb145bb4dbb3e33b5c2f64181e 100644
--- a/Modules/Applications/AppImageUtils/test/CMakeLists.txt
+++ b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
@@ -27,66 +27,6 @@ otb_test_application(NAME apTuUtDownloadSRTMTiles
                              -tiledir ${INPUTDATA}/DEM/srtm_directory
                      )
 
-
-
-
-#----------- Convert TESTS ----------------
-otb_test_application(NAME apTvUtConvertBasic
-                     APP Convert
-                     OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
-                             -out ${TEMP}/apTvUtConvertBasicOutput.tif float
-                     VALID   --compare-image ${NOTOL}
-                             ${OTBAPP_BASELINE}/apTvUtConvertBasicOutput.tif
-                	     ${TEMP}/apTvUtConvertBasicOutput.tif
-)
-
-otb_test_application(NAME apTuUtConvertExtendedFilename_writer
-                     APP  Convert
-                     OPTIONS -in ${INPUTDATA}/ToulouseExtract_WithGeom.tif
-                             -out ${TEMP}/apTvUtGeomExtendedFilename.tif?&gdal:co:TILED=YES&writegeom=false
-                     )
-
-otb_test_application(NAME apTvUtConvertWithScaling
-                     APP Convert
-                     OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
-                             -out ${TEMP}/apTvUtConvertWithScalingOutput.tif
-                             -type linear
-                     VALID   --compare-image ${NOTOL}
-                             ${OTBAPP_BASELINE}/apTvUtConvertWithScalingOutput.tif
-                             ${TEMP}/apTvUtConvertWithScalingOutput.tif
-)
-
-otb_test_application(NAME apTvUtConvertExtendedFilename_readerGEOM
-                     APP  Convert
-                     OPTIONS -in ${INPUTDATA}/ToulouseExtract_WithGeom.tif?&geom=${INPUTDATA}/ToulouseExtract_ModifiedGeom.geom
-                             -out ${TEMP}/apTvUtGeomExtendedFilename.tif
-                     VALID   --compare-ascii ${EPSILON_7}
-                             ${INPUTDATA}/ToulouseExtract_ModifiedGeom.geom
-                             ${TEMP}/apTvUtGeomExtendedFilename.geom)
-
-otb_test_application(NAME apTvUtConvertSelectChannels
-                     APP Convert
-                     OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
-                             -out ${TEMP}/apTvUtConvertSelectChannelsRgbOutput.tif
-                             -channels rgb
-                             -channels.rgb.red 2
-                             -channels.rgb.green 3
-                             -channels.rgb.blue 1
-                             -type linear
-                     VALID   --compare-image ${NOTOL}
-                             ${OTBAPP_BASELINE}/apTvUtConvertSelectChannelsRgbOutput.tif
-                             ${TEMP}/apTvUtConvertSelectChannelsRgbOutput.tif)
-
-otb_test_application(NAME apTvUtConvertMonoChannel
-                     APP Convert
-                     OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
-                             -out ${TEMP}/apTvUtConvertMonoChannelOutput.tif
-                             -channels grayscale
-                             -type linear
-                     VALID   --compare-image ${NOTOL}
-                             ${OTBAPP_BASELINE}/apTvUtConvertMonoChannelOutput.tif
-                             ${TEMP}/apTvUtConvertMonoChannelOutput.tif)
-
 #----------- DynamicConvert TESTS ------------
 otb_test_application(NAME apTvUtDynamicConvertBasic
                      APP DynamicConvert
@@ -101,6 +41,20 @@ otb_test_application(NAME apTvUtDynamicConvertBasic
                              ${OTBAPP_BASELINE}/apTvUtConvertSelectChannelsRgbOutput.tif
                              ${TEMP}/apTvUtDynamicConvertOutput.tif)
 
+otb_test_application(NAME apTuUtDynamicConvertExtendedFilename_writer
+                     APP  DynamicConvert
+                     OPTIONS -in ${INPUTDATA}/ToulouseExtract_WithGeom.tif
+                             -out ${TEMP}/apTvUtGeomExtendedFilename.tif?&gdal:co:TILED=YES&writegeom=false
+                     )
+
+otb_test_application(NAME apTvUtDynamicConvertExtendedFilename_readerGEOM
+                     APP  DynamicConvert
+                     OPTIONS -in ${INPUTDATA}/ToulouseExtract_WithGeom.tif?&geom=${INPUTDATA}/ToulouseExtract_ModifiedGeom.geom
+                             -out ${TEMP}/apTvUtGeomExtendedFilename.tif
+                     VALID   --compare-ascii ${EPSILON_7}
+                             ${INPUTDATA}/ToulouseExtract_ModifiedGeom.geom
+                             ${TEMP}/apTvUtGeomExtendedFilename.geom)
+
 otb_test_application(NAME apTvUtDynamicConvertLog2
                      APP DynamicConvert
                      OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
diff --git a/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx b/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx
index c9e5bdcb563de7a4d496a69e1d9a7a9af1ebff13..4b6bdffed57a5e9624c606371fa3ef63b78d932c 100644
--- a/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx
+++ b/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx
@@ -178,27 +178,26 @@ private:
     //SetDefaultParameterInt("channels.rho1240", 1);
 
     AddParameter(ParameterType_ListView,  "list", "Available Radiometric Indices");
-    SetParameterDescription("list","List of available radiometric indices with their relevant channels in brackets:\n\
-        Vegetation:NDVI - Normalized difference vegetation index (Red, NIR)\n\
-        Vegetation:TNDVI - Transformed normalized difference vegetation index (Red, NIR)\n\
-        Vegetation:RVI - Ratio vegetation index (Red, NIR)\n\
-        Vegetation:SAVI - Soil adjusted vegetation index (Red, NIR)\n\
-        Vegetation:TSAVI - Transformed soil adjusted vegetation index (Red, NIR)\n\
-        Vegetation:MSAVI - Modified soil adjusted vegetation index (Red, NIR)\n\
-        Vegetation:MSAVI2 - Modified soil adjusted vegetation index 2 (Red, NIR)\n\
-        Vegetation:GEMI - Global environment monitoring index (Red, NIR)\n\
-        Vegetation:IPVI - Infrared percentage vegetation index (Red, NIR)\n\
-        \n\
-        Water:NDWI - Normalized difference water index (Gao 1996) (NIR, MIR)\n\
-        Water:NDWI2 - Normalized difference water index (Mc Feeters 1996) (Green, NIR)\n\
-        Water:MNDWI - Modified normalized difference water index (Xu 2006) (Green, MIR)\n\
-        Water:NDPI - Normalized difference pond index (Lacaux et al.) (MIR, Green)\n\
-        Water:NDTI - Normalized difference turbidity index (Lacaux et al.) (Red, Green)\n\
-        \n\
-        Soil:RI - Redness index (Red, Green)\n\
-        Soil:CI - Color index (Red, Green)\n\
-        Soil:BI - Brightness index (Red, Green)\n\
-        Soil:BI2 - Brightness index 2 (NIR, Red, Green)");
+    SetParameterDescription("list",
+        "List of available radiometric indices with their relevant channels in brackets:\n\n"
+        "* Vegetation:NDVI - Normalized difference vegetation index (Red, NIR)\n"
+        "* Vegetation:TNDVI - Transformed normalized difference vegetation index (Red, NIR)\n"
+        "* Vegetation:RVI - Ratio vegetation index (Red, NIR)\n"
+        "* Vegetation:SAVI - Soil adjusted vegetation index (Red, NIR)\n"
+        "* Vegetation:TSAVI - Transformed soil adjusted vegetation index (Red, NIR)\n"
+        "* Vegetation:MSAVI - Modified soil adjusted vegetation index (Red, NIR)\n"
+        "* Vegetation:MSAVI2 - Modified soil adjusted vegetation index 2 (Red, NIR)\n"
+        "* Vegetation:GEMI - Global environment monitoring index (Red, NIR)\n"
+        "* Vegetation:IPVI - Infrared percentage vegetation index (Red, NIR)\n"
+        "* Water:NDWI - Normalized difference water index (Gao 1996) (NIR, MIR)\n"
+        "* Water:NDWI2 - Normalized difference water index (Mc Feeters 1996) (Green, NIR)\n"
+        "* Water:MNDWI - Modified normalized difference water index (Xu 2006) (Green, MIR)\n"
+        "* Water:NDPI - Normalized difference pond index (Lacaux et al.) (MIR, Green)\n"
+        "* Water:NDTI - Normalized difference turbidity index (Lacaux et al.) (Red, Green)\n"
+        "* Soil:RI - Redness index (Red, Green)\n"
+        "* Soil:CI - Color index (Red, Green)\n"
+        "* Soil:BI - Brightness index (Red, Green)\n"
+        "* Soil:BI2 - Brightness index 2 (NIR, Red, Green)");
 
     // Doc example parameter settings
     SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
diff --git a/Modules/Applications/AppMathParser/app/otbBandMath.cxx b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
index 50fd803aa2ba80cf2302d8e376f115824fc09a32..b738cdfa4f3646185004c2d520c4691af76570f2 100644
--- a/Modules/Applications/AppMathParser/app/otbBandMath.cxx
+++ b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
@@ -68,25 +68,26 @@ private:
       "This application performs a mathematical operation on several multi-band "
       "images and outputs the result into a monoband image. The given expression"
       " is computed at each pixel position. Evaluation of the "
-      "mathematical formula is done by the muParser libraries.\n\n"
+      "mathematical formula is done by the muParser library.\n\n"
 
       "The formula can be written using:\n\n"
-      "  * numerical values ( 2.3, -5, 3.1e4, ...)\n"
-      "  * variables containing pixel values (e.g. : 'im2b3' is the pixel value"
+      "* numerical values ( 2.3, -5, 3.1e4, ...)\n"
+      "* variables containing pixel values (e.g. ``im2b3`` is the pixel value"
       " in 2nd image, 3rd band)\n"
-      "  * binary operators:\n\n"
-      "    * '+' addition, '-' subtraction, '*' multiplication, '/' division\n"
-      "    * '^' raise x to the power of y\n"
-      "    * '<' less than, '>' greater than, '<=' less or equal, '>=' greater or equal\n"
-      "    * '==' equal, '!=' not equal\n"
+      "* binary operators:\n\n"
+
+      "  * ``+`` addition, ``-`` subtraction, ``*`` multiplication, ``/`` division\n"
+      "  * ``^`` raise x to the power of y\n"
+      "  * ``<`` less than, ``>`` greater than, ``<=`` less or equal, ``>=`` greater or equal\n"
+      "  * ``==`` equal, ``!=`` not equal\n"
 #ifdef OTB_MUPARSER_HAS_CXX_LOGICAL_OPERATORS
-      "    * '||' logical or, '&&' logical and\n"
-      "  * if-then-else operator: '(condition ? value_true : value_false)'\n"
+      "  * ``||`` logical or, ``&&`` logical and\n"
+      "  * if-then-else operator: ``(condition ? value_true : value_false)``\n"
 #else
-      "    * 'or' logical or, 'and' logical and\n"
-      "  * if-then-else operator: 'if(condition;value_true;value_false)'\n"
+      "  * ``or`` logical or, ``and`` logical and\n"
+      "* if-then-else operator: ``if(condition;value_true;value_false)``\n"
 #endif
-      "  * functions : exp(), log(), sin(), cos(), min(), max(), ...\n\n"
+      "* functions: ``exp()``, ``log()``, ``sin()``, ``cos()``, ``min()``, ``max()``, ...\n\n"
 
       "The full list of features and operators is available on the muParser website [1]."
       );
@@ -96,17 +97,17 @@ private:
     SetDocSeeAlso("[1] http://beltoforion.de/article.php?a=muparser");
     AddDocTag(Tags::Manip);
 
-    AddParameter( ParameterType_InputImageList, "il", "Input image-list" );
+    AddParameter( ParameterType_InputImageList, "il", "Input image list" );
     SetParameterDescription(
       "il",
-      "Image-list of operands to the mathematical expression."
+      "Image list of operands to the mathematical expression."
     );
 
     AddParameter( ParameterType_OutputImage, "out", "Output Image" );
     SetParameterDescription(
       "out",
       "Output image which is the result of the mathematical expressions on input"
-      " image-list operands.");
+      " image list operands.");
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
index 7352a2d73c7707cca23ff44e87d0d6dc4d89176a..70f8a6874dba5fc3d11f9bbb190a7e429e7edda9 100644
--- a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
+++ b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
@@ -67,7 +67,7 @@ private:
       "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"
+      "done by the muParserX library.\n\n"
 
       "The list of features and the syntax of muParserX is available at [1].\n\n"
 
@@ -81,29 +81,28 @@ private:
       "------------\n\n"
 
       "The formula can be written using:\n\n"
-      "  * numerical values ( 2.3, -5, 3.1e4, ...)\n"
-      "  * variables containing pixel values (please, note the indexing of "
+      "* numerical values ( 2.3, -5, 3.1e4, ...)\n"
+      "* variables containing pixel values (please, note the indexing of "
       "inputs from 1 to N). Examples for the first input image:\n\n"
-      "    * 'im1' a pixel from 1st input, made of n components (n bands)\n"
-      "    * 'im1b2' the 2nd component of a pixel from 1st input (band index is 1-based)\n"
-      "    * 'im1b2N3x4' a 3x4 pixels 'N'eighbourhood of a pixel the 2nd "
-      "component of a pixel from the 1st input\n"
-      "    * 'im1PhyX' horizontal (X-axis) spacing of the 1st input.\n"
-      "    * 'im1PhyY' vertical spacing of the 1st input input.\n"
-      "    * 'im1b2Mean' mean of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Mini' minimum of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Maxi' maximum of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Sum' sum of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'im1b2Var' variance of the 2nd component of the 1st input (global statistics)\n"
-      "    * 'idxX' and 'idxY' are the indices of the current pixel (generic variables)\n"
-      "  * binary operators:\n\n"
-      "    * '+' addition, '-' subtraction, '*' multiplication, '/' division\n"
-      "    * '^' raise x to the power of y\n"
-      "    * '<' less than, '>' greater than, '<=' less or equal, '>=' greater or equal\n"
-      "    * '==' equal, '!=' not equal\n"
-      "    * logical operators: 'or', 'and', 'xor'\n"
-      "  * if-then-else operator: '(condition ? value_true : value_false)'\n"
-      "  * functions : abs(), exp(), log(), sin(), cos(), min(), max(), ...\n\n"
+      "  * ``im1`` a pixel from 1st input, made of n components (n bands)\n"
+      "  * ``im1b2`` the 2nd component of a pixel from 1st input (band index is 1-based)\n"
+      "  * ``im1b2N3x4`` a 3x4 pixels Neighbourhood of a pixel the 2nd component of a pixel from the 1st input\n"
+      "  * ``im1PhyX`` horizontal (X-axis) spacing of the 1st input.\n"
+      "  * ``im1PhyY`` vertical spacing of the 1st input input.\n"
+      "  * ``im1b2Mean`` mean of the 2nd component of the 1st input (global statistics)\n"
+      "  * ``im1b2Mini`` minimum of the 2nd component of the 1st input (global statistics)\n"
+      "  * ``im1b2Maxi`` maximum of the 2nd component of the 1st input (global statistics)\n"
+      "  * ``im1b2Sum`` sum of the 2nd component of the 1st input (global statistics)\n"
+      "  * ``im1b2Var`` variance of the 2nd component of the 1st input (global statistics)\n"
+      "  * ``idxX`` and ``idxY`` are the indices of the current pixel (generic variables)\n"
+      "* binary operators:\n\n"
+      "  * ``+`` addition, ``-`` subtraction, ``*`` multiplication, ``/`` division\n"
+      "  * ``^`` raise x to the power of y\n"
+      "  * ``<`` less than, ``>`` greater than, ``<=`` less or equal, ``>=`` greater or equal\n"
+      "  * ``==`` equal, ``!=`` not equal\n"
+      "  * logical operators: ``or``, ``and``, ``xor``\n"
+      "* if-then-else operator: ``(condition ? value_true : value_false)``\n"
+      "* functions: abs(), exp(), log(), sin(), cos(), min(), max(), ...\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"
@@ -114,15 +113,15 @@ private:
       "represented as a row vector.\n\n"
 
       "Example:\n"
-      "  im1 + im2\n"
+      "  ``im1 + im2``\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"
+      "Please note that it is also possible to use the following expressions"
       " to obtain the same result:\n\n"
-      "  * im1b1 + im2b1\n"
-      "  * im1b2 + im2b2\n"
+      "  * ``im1b1 + im2b1``\n"
+      "  * ``im1b2 + im2b2``\n"
       "  * ...\n\n"
 
       "Nevertheless, the first expression is by far much pleaseant. We call "
@@ -134,15 +133,14 @@ private:
 
       "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\n"
-      "  - I is an number identifying the image input (remember, input #0 = im1, "
+      "are always defined following the ``imIbJNKxP`` pattern, where:\n\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 "
+      "  - ``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"
+      "NB: All neighborhood are centered, thus ``K`` and ``P`` must be odd numbers.\n\n"
 
       "Many operators come with this new functionality:\n\n"
       "  - dotpr\n"
@@ -153,7 +151,7 @@ private:
       "  - max\n"
       "  - etc.\n\n"
 
-      "For instance, if im1 represents the pixel of 3 bands image::\n\n"
+      "For instance, if ``im1`` represents the pixel of a 3 bands image::\n\n"
       "  im1 - mean( im1b1N5x5, im1b2N5x5, im1b3N5x5 )\n\n"
       "could represent a high pass filter (note that by implying three "
       "neighborhoods, the operator mean returns a row vector of three components"
@@ -163,14 +161,14 @@ private:
       "  - 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 "
+      "``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, 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"
@@ -178,7 +176,7 @@ private:
       "The application itself\n"
       "----------------------\n\n"
 
-      "The application can use an expression supplied with the 'exp' parameter."
+      "The application can use an expression supplied with the ``-exp`` parameter."
       " It can also use an input context file, that defines variables and "
       "expressions. An example of context file is given below::\n\n"
       "  #F expo 1.1\n"
@@ -190,25 +188,22 @@ private:
       "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. It is also possible to define expressions within the same"
-      " txt file, with #E <expr> (see limitations, below).\n"
-
-      "Finally, we strongly recommend to read the OTB Cookbook which can be "
-      "found at: http://www.orfeo-toolbox.org/packages/OTBCookBook.pdf"
+      " txt file, with #E <expr> (see limitations, below)."
     );
 
     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 "
+      "expression, contrary to otbBandMathXImageFilter. "
+      "Separating expressions by semicolons ``;`` will concatenate their results "
       "into a unique multiband output image."
     );
     SetDocAuthors( "OTB-Team" );
-    SetDocSeeAlso("[1] http://articles.beltoforion.de/article.php?a=muparserx\n"
+    SetDocSeeAlso("[1] http://articles.beltoforion.de/article.php?a=muparserx\n\n"
       "[2] BandMath");
     AddDocTag(Tags::Manip);
 
-    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 to perform computation on." );
 
     AddParameter( ParameterType_OutputImage, "out", "Output Image" );
     SetParameterDescription( "out", "Output image." );
@@ -381,12 +376,12 @@ private:
     std::string expStr = GetParameterString("exp");
     if (useContext)
       {
-      otbAppLogINFO("Using input context : " << expStr );
+      otbAppLogINFO("Using input context: " << expStr );
       m_Filter->ImportContext(GetParameterString("incontext"));
       }
     else
       {
-      otbAppLogINFO("Using expression : " << expStr );
+      otbAppLogINFO("Using expression: " << expStr );
       m_Filter->SetExpression(expStr);
       }
 
diff --git a/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx b/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx
index cd1ccdb53f1eb3a01d7ffeef030e3dba0981749a..788cb5e191f94e0b0b8e62a525f292d273c69561 100644
--- a/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx
+++ b/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx
@@ -179,7 +179,7 @@ SetOfficialDocLink();
 
 void DoUpdateParameters() override
 {
-  // Nothing to do here : all parameters are independent
+  // Nothing to do here: all parameters are independent
 }
 
 void DoExecute() override
diff --git a/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx b/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx
index 42b7f57d05fe3daaddec0e3edccf8a99d65fd2ac..6c041b03d070038b7a9444c441f18f8f594d1d22 100644
--- a/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx
+++ b/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx
@@ -65,11 +65,11 @@ private:
     SetName("VectorDataReprojection");
     SetDescription("Reproject a vector data using support image projection reference, or a user specified map projection");
     SetDocName("Vector Data reprojection");
-    std::ostringstream oss;
-    oss <<" This application allows reprojecting a vector data using support image projection reference"
-        ", or a user given map projection." << std::endl;
-    oss <<" If given, image keywordlist can be added to reprojected vectordata.";
-    SetDocLongDescription(oss.str());
+
+    SetDocLongDescription(
+        "Reproject vector data using a support image as projection reference or to a user given map projection. "
+        " If given an image keywordlist can be added to the reprojected vectordata.");
+
     SetDocLimitations(" ");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
diff --git a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
index 14698cce48a7f7c1da85cda338ecf977e0befe07..49e8d7ffd92eacd6a82626739cd0972748259be9 100644
--- a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
+++ b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
@@ -71,7 +71,7 @@ private:
     AddParameter(ParameterType_Bool, "noise", "Disable Noise");
     SetParameterDescription("noise", "Flag to disable noise. For 5.2.0 release, the noise values are only read by TerraSARX product.");
 
-    AddParameter(ParameterType_Choice, "lut", "Lookup table sigma /gamma/ beta/ DN.");
+    AddParameter(ParameterType_Choice, "lut", "Lookup table");
     SetParameterDescription("lut", "Lookup table values are not available with all SAR products. Products that provide lookup table with metadata are: Sentinel1, Radarsat2.");
     AddChoice("lut.sigma", "Use sigma nought lookup");
     SetParameterDescription("lut.sigma","Use Sigma nought lookup value from product metadata");
diff --git a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
index 2a6ccbcf089a62151541d4a69b242edd943003af..10f7d79fb6a5df18a045dfccf4311aefb283d854 100644
--- a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
+++ b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
@@ -93,9 +93,9 @@ private:
     SetDocName("SARDecompositions");
     SetDocLongDescription("From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
                           "All the decompositions implemented are intended for the mono-static case (transmitter and receiver are co-located).\n"
-                          "There are two kinds of decomposition : coherent ones and incoherent ones.\n"
+                          "There are two kinds of decomposition: coherent ones and incoherent ones.\n"
                           "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"   
+                          "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."
 						  );
@@ -139,7 +139,7 @@ private:
     AddParameter(ParameterType_Group,"inco","Incoherent decompositions");
     SetParameterDescription("inco","This group allows setting parameters related to the incoherent decompositions.");
     
-    AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging.");
+    AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging");
     SetParameterDescription("inco.kernelsize", "Minute (0-59)");
     SetMinimumParameterIntValue("inco.kernelsize", 1);
     SetDefaultParameterInt("inco.kernelsize", 3);
@@ -162,7 +162,7 @@ private:
 
   void DoUpdateParameters() override
   {
-    // Nothing to do here : all parameters are independent
+    // Nothing to do here: all parameters are independent
   }
 
   void DoExecute() override
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
index f11d6384eb813df4ddfb224e675f5f7e8948b3eb..104630ca5b62fde63931083a6c57d2641448542c 100644
--- a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
@@ -197,32 +197,32 @@ private:
     "For instance, it is possible to get the coherency matrix from the Sinclar one, or the Mueller matrix from the coherency one.\n"
     "The filters used in this application never handle matrices, but images where each band is related to their elements.\n"
     "As most of the time SAR polarimetry handles symmetric/hermitian matrices, only the relevant elements are stored, so that the images representing them have a minimal number of bands.\n"
-    "For instance, the coherency matrix size is 3x3 in the monostatic case, and 4x4 in the bistatic case : it will thus be stored in a 6-band or a 10-band complex image (the diagonal and the upper elements of the matrix).\n"
+    "For instance, the coherency matrix size is 3x3 in the monostatic case, and 4x4 in the bistatic case: it will thus be stored in a 6-band or a 10-band complex image (the diagonal and the upper elements of the matrix).\n"
     "\n"
-    "The Sinclair matrix is a special case : it is always represented as 3 or 4 one-band complex images (for mono- or bistatic case).\n"
+    "The Sinclair matrix is a special case: it is always represented as 3 or 4 one-band complex images (for mono- or bistatic case).\n"
     "The available conversions are listed below:\n"
     
 	"\n--- Monostatic case ---\n" 
     
-    "1 msinclairtocoherency --> Sinclair matrix to coherency matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
-    "2 msinclairtocovariance --> Sinclair matrix to covariance matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
-    "3 msinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input : 3 x 1 complex channel (HH, HV or VH, VV) | output :  6 complex channels)\n"
-    "4 mcoherencytomueller --> Coherency matrix to Mueller matrix (input : 6 complex channels | 16 real channels)\n"
-    "5 mcovariancetocoherencydegree --> Covariance matrix to coherency degree (input : 6 complex channels | 3 complex channels)\n"
-    "6 mcovariancetocoherency --> Covariance matrix to coherency matrix (input : 6 complex channels | 6 complex channels)\n"
-    "7 mlinearcovariancetocircularcovariance --> Covariance matrix to circular covariance matrix (input : 6 complex channels | output : 6 complex channels)\n"
+    "1 msinclairtocoherency --> Sinclair matrix to coherency matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+    "2 msinclairtocovariance --> Sinclair matrix to covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+    "3 msinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+    "4 mcoherencytomueller --> Coherency matrix to Mueller matrix (input: 6 complex channels | 16 real channels)\n"
+    "5 mcovariancetocoherencydegree --> Covariance matrix to coherency degree (input: 6 complex channels | 3 complex channels)\n"
+    "6 mcovariancetocoherency --> Covariance matrix to coherency matrix (input: 6 complex channels | 6 complex channels)\n"
+    "7 mlinearcovariancetocircularcovariance --> Covariance matrix to circular covariance matrix (input: 6 complex channels | output: 6 complex channels)\n"
     
     "\n--- Bistatic case ---\n"
     
-    "8 bsinclairtocoherency --> Sinclair matrix to coherency matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | 10 complex channels)\n"
-    "9 bsinclairtocovariance --> Sinclair matrix to covariance matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 10 complex channels)\n"
-    "10 bsinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input : 4 x 1 complex channel (HH, HV, VH, VV) | output : 10 complex channels)\n"
+    "8 bsinclairtocoherency --> Sinclair matrix to coherency matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | 10 complex channels)\n"
+    "9 bsinclairtocovariance --> Sinclair matrix to covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex channels)\n"
+    "10 bsinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex channels)\n"
     
     "\n--- Both cases ---\n"
     
-    "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)"
+    "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)"
 
  );
 						  
@@ -232,29 +232,29 @@ private:
 
     AddDocTag(Tags::SAR);
 
-    AddParameter(ParameterType_InputImage, "inc", "Input: multi-band complex image");
-    SetParameterDescription("inc", "Input : multi-band complex image");
+    AddParameter(ParameterType_InputImage, "inc", "Input multi-band complex image");
+    SetParameterDescription("inc", "Input: multi-band complex image");
     MandatoryOff("inc");
 
-    AddParameter(ParameterType_InputImage, "inf", "Input: multi-band real image");
-    SetParameterDescription("inf", "Input : multi-band real image");
+    AddParameter(ParameterType_InputImage, "inf", "Input multi-band real image");
+    SetParameterDescription("inf", "Input: multi-band real image");
     MandatoryOff("inf");
 
 
-    AddParameter(ParameterType_InputImage, "inhh", "Input: one-band complex image (HH)");
-    SetParameterDescription("inhh", "Input : one-band complex image (HH)");
+    AddParameter(ParameterType_InputImage, "inhh", "Input one-band complex image (HH)");
+    SetParameterDescription("inhh", "Input: one-band complex image (HH)");
     MandatoryOff("inhh");
 
-    AddParameter(ParameterType_InputImage, "inhv", "Input: one-band complex image (HV)");
-    SetParameterDescription("inhv", "Input : one-band complex image (HV)");
+    AddParameter(ParameterType_InputImage, "inhv", "Input one-band complex image (HV)");
+    SetParameterDescription("inhv", "Input: one-band complex image (HV)");
     MandatoryOff("inhv");
 
-    AddParameter(ParameterType_InputImage, "invh", "Input: one-band complex image (VH)");
-    SetParameterDescription("invh", "Input : one-band complex image (VH)");
+    AddParameter(ParameterType_InputImage, "invh", "Input one-band complex image (VH)");
+    SetParameterDescription("invh", "Input: one-band complex image (VH)");
     MandatoryOff("invh");
 
-    AddParameter(ParameterType_InputImage, "invv", "Input: one-band complex image (VV)");
-    SetParameterDescription("invv", "Input : one-band complex image (VV)");
+    AddParameter(ParameterType_InputImage, "invv", "Input one-band complex image (VV)");
+    SetParameterDescription("invv", "Input: one-band complex image (VV)");
     MandatoryOff("invv");
     
     AddParameter(ParameterType_OutputImage, "outc",  "Output Complex Image");
@@ -273,73 +273,73 @@ private:
     
     // #1
     // SinclairToReciprocalCoherency
-    AddChoice("conv.msinclairtocoherency","1 Monostatic : Sinclair matrix to coherency matrix (complex output)");
-    SetParameterDescription("conv.msinclairtocoherency","1 Monostatic :Sinclair matrix to coherency matrix (complex output)");
+    AddChoice("conv.msinclairtocoherency","1 Monostatic: Sinclair matrix to coherency matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocoherency","1 Monostatic: Sinclair matrix to coherency matrix (complex output)");
     
     // #2
     // SinclairToReciprocalCovariance
-    AddChoice("conv.msinclairtocovariance","2 Monostatic : Sinclair matrix to covariance matrix (complex output)");
-    SetParameterDescription("conv.msinclairtocovariance","2 Monostatic : Sinclair matrix to covariance matrix (complex output)");
+    AddChoice("conv.msinclairtocovariance","2 Monostatic: Sinclair matrix to covariance matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocovariance","2 Monostatic: Sinclair matrix to covariance matrix (complex output)");
     
     // #3 
     // SinclairToReciprocalCircularCovariance
-    AddChoice("conv.msinclairtocircovariance","3 Monostatic : Sinclair matrix to circular covariance matrix (complex output)");
-    SetParameterDescription("conv.msinclairtocircovariance","3 Monostatic : Sinclair matrix to circular covariance matrix (complex output)");
+    AddChoice("conv.msinclairtocircovariance","3 Monostatic: Sinclair matrix to circular covariance matrix (complex output)");
+    SetParameterDescription("conv.msinclairtocircovariance","3 Monostatic: Sinclair matrix to circular covariance matrix (complex output)");
     
     // #4 
     // ReciprocalCoherencyToReciprocalMuellerImageFilter
-    AddChoice("conv.mcoherencytomueller","4 Monostatic : Coherency matrix to Mueller matrix"); 
-    SetParameterDescription("conv.mcoherencytomueller","4 Monostatic : Coherency matrix to Mueller matrix"); 
+    AddChoice("conv.mcoherencytomueller","4 Monostatic: Coherency matrix to Mueller matrix"); 
+    SetParameterDescription("conv.mcoherencytomueller","4 Monostatic: Coherency matrix to Mueller matrix"); 
     
     // #5
     // ReciprocalCovarianceToCoherencyDegreeImageFilter 
-    AddChoice("conv.mcovariancetocoherencydegree","5 Monostatic : Covariance matrix to coherency degree "); 
-    SetParameterDescription("conv.mcovariancetocoherencydegree","5 Monostatic : Covariance matrix to coherency degree "); 
+    AddChoice("conv.mcovariancetocoherencydegree","5 Monostatic: Covariance matrix to coherency degree"); 
+    SetParameterDescription("conv.mcovariancetocoherencydegree","5 Monostatic: Covariance matrix to coherency degree "); 
     
     // #6
     // ReciprocalCovarianceToReciprocalCoherencyImageFilter
-    AddChoice("conv.mcovariancetocoherency","6 Monostatic : Covariance matrix to coherency matrix (complex output)"); 
-    SetParameterDescription("conv.mcovariancetocoherency","6 Monostatic : Covariance matrix to coherency matrix (complex output)");  
+    AddChoice("conv.mcovariancetocoherency","6 Monostatic: Covariance matrix to coherency matrix (complex output)"); 
+    SetParameterDescription("conv.mcovariancetocoherency","6 Monostatic: Covariance matrix to coherency matrix (complex output)");  
     
     // #7
     // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
-    AddChoice("conv.mlinearcovariancetocircularcovariance","7 Monostatic : Covariance matrix to circular covariance matrix (complex output)"); 
-    SetParameterDescription("conv.mlinearcovariancetocircularcovariance","7 Monostatic : Covariance matrix to circular covariance matrix (complex output)");  
+    AddChoice("conv.mlinearcovariancetocircularcovariance","7 Monostatic: Covariance matrix to circular covariance matrix (complex output)"); 
+    SetParameterDescription("conv.mlinearcovariancetocircularcovariance","7 Monostatic: Covariance matrix to circular covariance matrix (complex output)");  
     
     // #8
     // MuellerToReciprocalCovarianceImageFilter 
-    AddChoice("conv.muellertomcovariance","8 Bi/mono : Mueller matrix to monostatic covariance matrix");
-    SetParameterDescription("conv.muellertomcovariance","8 Bi/mono : Mueller matrix to monostatic covariance matrix");
+    AddChoice("conv.muellertomcovariance","8 Bi/mono: Mueller matrix to monostatic covariance matrix");
+    SetParameterDescription("conv.muellertomcovariance","8 Bi/mono: Mueller matrix to monostatic covariance matrix");
     
     //Bistatic case
     
     // #9
     // SinclairToCoherency
-    AddChoice("conv.bsinclairtocoherency","9 Bistatic : Sinclair matrix to coherency matrix (complex output)");
-    SetParameterDescription("conv.bsinclairtocoherency","9 Bistatic : Sinclair matrix to coherency matrix (complex output)");
+    AddChoice("conv.bsinclairtocoherency","9 Bistatic: Sinclair matrix to coherency matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocoherency","9 Bistatic: Sinclair matrix to coherency matrix (complex output)");
     
     // #10
     // SinclairToCovariance  
-    AddChoice("conv.bsinclairtocovariance","10 Bistatic : Sinclair matrix to covariance matrix (complex output)");
-    SetParameterDescription("conv.bsinclairtocovariance","10 Bistatic : Sinclair matrix to covariance matrix (complex output)");
+    AddChoice("conv.bsinclairtocovariance","10 Bistatic: Sinclair matrix to covariance matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocovariance","10 Bistatic: Sinclair matrix to covariance matrix (complex output)");
     
     // #11
     // SinclairToCircularCovariance 
-    AddChoice("conv.bsinclairtocircovariance","11 Bistatic : Sinclair matrix to circular covariance matrix (complex output)");
-    SetParameterDescription("conv.bsinclairtocircovariance","11 Bistatic : Sinclair matrix to circular covariance matrix (complex output)");
+    AddChoice("conv.bsinclairtocircovariance","11 Bistatic: Sinclair matrix to circular covariance matrix (complex output)");
+    SetParameterDescription("conv.bsinclairtocircovariance","11 Bistatic: Sinclair matrix to circular covariance matrix (complex output)");
     
     //Both case
     
     // #12
     // SinclairToMueller
-    AddChoice("conv.sinclairtomueller","12 Bi/mono : Sinclair matrix to Mueller matrix");
-    SetParameterDescription("conv.sinclairtomueller","12 Bi/mono : Sinclair matrix to Mueller matrix");
+    AddChoice("conv.sinclairtomueller","12 Bi/mono: Sinclair matrix to Mueller matrix");
+    SetParameterDescription("conv.sinclairtomueller","12 Bi/mono: Sinclair matrix to Mueller matrix");
     
     
     // #13
     // MuellerToPolarisationDegreeAndPowerImageFilter
-    AddChoice("conv.muellertopoldegandpower","13 Bi/mono : Mueller matrix to polarisation degree and power");
-    SetParameterDescription("conv.muellertopoldegandpower","13 Bi/mono : Mueller matrix to polarisation degree and power");
+    AddChoice("conv.muellertopoldegandpower","13 Bi/mono: Mueller matrix to polarisation degree and power");
+    SetParameterDescription("conv.muellertopoldegandpower","13 Bi/mono: Mueller matrix to polarisation degree and power");
 
     AddRAMParameter();
 
@@ -509,7 +509,7 @@ private:
 		m_RCohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
 		
 		break;
 
@@ -526,7 +526,7 @@ private:
 		m_RCovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
 		
 		break;
 		
@@ -544,7 +544,7 @@ private:
 		m_RCCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
 		
 		break;
 		
@@ -554,7 +554,7 @@ private:
 		m_RCRMFilter = RCRMFilterType::New();
 		m_RCRMFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outf", m_RCRMFilter->GetOutput() ); // input : 6 complex channels | 16 real channels
+		SetParameterOutputImage("outf", m_RCRMFilter->GetOutput() ); // input: 6 complex channels | 16 real channels
 		
 		break;
 		
@@ -565,7 +565,7 @@ private:
 		m_RCCDFilter = RCCDFilterType::New();
 		m_RCCDFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outc", m_RCCDFilter->GetOutput() ); // input : 6 complex channels | 3 complex channels
+		SetParameterOutputImage("outc", m_RCCDFilter->GetOutput() ); // input: 6 complex channels | 3 complex channels
 		
 		break;
 
@@ -575,7 +575,7 @@ private:
 		m_RCRCFilter = RCRCFilterType::New();
 		m_RCRCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outc", m_RCRCFilter->GetOutput() ); // input : 6 complex channels | 6 complex channels
+		SetParameterOutputImage("outc", m_RCRCFilter->GetOutput() ); // input: 6 complex channels | 6 complex channels
 		
 		break;
 		
@@ -586,7 +586,7 @@ private:
 		m_RLCRCCFilter = RLCRCCFilterType::New();
 		m_RLCRCCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input : 6 complex channels | output : 6 complex channels
+		SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input: 6 complex channels | output: 6 complex channels
 		
 		break;
 		
@@ -597,7 +597,7 @@ private:
 		
 		m_MRCFilter->SetInput(GetParameterDoubleVectorImage("inf"));
 		
-		SetParameterOutputImage("outc", m_MRCFilter->GetOutput() ); // input : 16 real channels | output : 6 complex channels
+		SetParameterOutputImage("outc", m_MRCFilter->GetOutput() ); // input: 16 real channels | output: 6 complex channels
 		
 		break;
 		
@@ -615,7 +615,7 @@ private:
 		m_CohSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_CohSRFilter->GetOutput() ); // input : 4 x 1 complex channel | 10 complex channels
+		SetParameterOutputImage("outc", m_CohSRFilter->GetOutput() ); // input: 4 x 1 complex channel | 10 complex channels
 		
 		break;
 		
@@ -630,7 +630,7 @@ private:
 		m_CovSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_CovSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		SetParameterOutputImage("outc", m_CovSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 10 complex channels
 		
 		break;
 		
@@ -644,7 +644,7 @@ private:
 		m_CCSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outc", m_CCSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		SetParameterOutputImage("outc", m_CCSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 10 complex channels
 		
 		break;
 		
@@ -662,7 +662,7 @@ private:
 		m_MSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_MSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterOutputImage("outf", m_MSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 16 real channels
+		SetParameterOutputImage("outf", m_MSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 16 real channels
 		
 		break;
 		
@@ -672,7 +672,7 @@ private:
 		
 		m_MPDPFilter->SetInput(GetParameterDoubleVectorImage("inf"));
 		
-		SetParameterOutputImage("outf", m_MPDPFilter->GetOutput() ); //  input : 16 real channels | output : 4 real channels
+		SetParameterOutputImage("outf", m_MPDPFilter->GetOutput() ); //  input: 16 real channels | output: 4 real channels
 		
 		break;
 		
diff --git a/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
index 8fb514d814f055b415f186d8b86e88dcc8fd195c..88a03df79f3f4d1b61f2be65fdc4f398a0d67ae0 100644
--- a/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
+++ b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
@@ -56,11 +56,11 @@ private:
 						  "These parameters are namely psii, khii, psir and khir. The suffixes (i) and (r) refer to the transmitting antenna and the receiving antenna respectively.\n"
 						  "Orientations and ellipticities are given in degrees, and are between -90/90 degrees and -45/45 degrees respectively.\n " 
 						  "\n"
-						  "Four polarization architectures can be processed : \n\n"
-						  "1. HH_HV_VH_VV : full polarization, general bistatic case.\n"
-						  "2. HH_HV_VV or HH_VH_VV : full polarization, monostatic case (transmitter and receiver are co-located).\n"
-						  "3. HH_HV : dual polarization.\n"
-						  "4. VH_VV : dual polarization.\n\n"
+						  "Four polarization architectures can be processed: \n\n"
+						  "1. HH_HV_VH_VV: full polarization, general bistatic case.\n"
+						  "2. HH_HV_VV or HH_VH_VV: full polarization, monostatic case (transmitter and receiver are co-located).\n"
+						  "3. HH_HV: dual polarization.\n"
+						  "4. VH_VV: dual polarization.\n\n"
 						  "The application takes a complex vector image as input, where each band correspond to a particular emission/reception polarization scheme.\n"
 						  "User must comply with the band order given above, since the bands are used to build the Sinclair matrix.\n"
 						  "\n"
@@ -68,8 +68,8 @@ private:
 						  "1. Architecture HH_HV_VH_VV is the only one with four bands, there is no possible confusion.\n"
 						  "2. Concerning HH_HV_VV and HH_VH_VV architectures, both correspond to a three channels image. But they are processed in the same way, as the Sinclair matrix is symmetric in the monostatic case.\n"
 						  "3. Finally, the two last architectures (dual polarizations), can't be distinguished only by the number of bands of the input image."
-						  " User must then use the parameters emissionh and emissionv to indicate the architecture of the system : emissionh=1 and emissionv=0 --> HH_HV,  emissionh=0 and emissionv=1 --> VH_VV.\n"
-						  "\nNote : if the architecture is HH_HV, khii and psii are automatically both set to 0 degree; if the architecture is VH_VV, khii and psii are automatically set to 0 degree and 90 degrees respectively.\n"
+						  " User must then use the parameters emissionh and emissionv to indicate the architecture of the system: emissionh=1 and emissionv=0 --> HH_HV,  emissionh=0 and emissionv=1 --> VH_VV.\n"
+						  "\nNote: if the architecture is HH_HV, khii and psii are automatically both set to 0 degree; if the architecture is VH_VV, khii and psii are automatically set to 0 degree and 90 degrees respectively.\n"
 						  "\n"
 						  "It is also possible to force the calculation to co-polar or cross-polar modes.\n"
 						  "In the co-polar case, values for psir and khir will be ignored and forced to psii and khii; same as the cross-polar mode, where khir and psir will be forced to (psii + 90 degrees) and -khii.\n"
@@ -156,7 +156,7 @@ private:
 
   void DoUpdateParameters() override
   {
-    // Nothing to do here : all parameters are independent
+    // Nothing to do here: all parameters are independent
   }
 
   void DoExecute() override
diff --git a/Modules/Applications/AppSARUtils/app/otbDespeckle.cxx b/Modules/Applications/AppSARUtils/app/otbDespeckle.cxx
index e1fd6c833371edd93aebf563691e3494aac945fe..ed17af2e2cee6689e39ec4fb73c55b193bc42fbf 100644
--- a/Modules/Applications/AppSARUtils/app/otbDespeckle.cxx
+++ b/Modules/Applications/AppSARUtils/app/otbDespeckle.cxx
@@ -69,11 +69,11 @@ private:
      "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."
+     "We sum up below the basic principle of this four methods:\n\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.");
@@ -169,7 +169,7 @@ private:
 
   void DoUpdateParameters() override
   {
-    // Nothing to do here : all parameters are independent
+    // Nothing to do here: all parameters are independent
   }
 
   void DoExecute() override
diff --git a/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx
index 34d62c2ecbeba6d40f0cca68a49d017553c3ccf4..637110043ea7e2a03670e03cca92f8bda9c494d2 100644
--- a/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbHooverCompareSegmentation.cxx
@@ -140,11 +140,11 @@ private:
     SetDocLongDescription("This application compares a machine segmentation (MS) with a partial "
                           "ground truth segmentation (GT). The Hoover metrics are used to estimate "
                           "scores for correct detection, over-segmentation, under-segmentation and "
-                          "missed detection."
-                          "\n The application can output the overall Hoover scores along with colored"
+                          "missed detection.\n\n"
+                          "The application can output the overall Hoover scores along with colored"
                           "images of the MS and GT segmentation showing the state of each region "
-                          "(correct detection, over-segmentation, under-segmentation, missed)"
-                          "\n The Hoover metrics are described in : Hoover et al., \"An experimental"
+                          "(correct detection, over-segmentation, under-segmentation, missed).\n\n"
+                          "The Hoover metrics are described in : Hoover et al., \"An experimental"
                           " comparison of range image segmentation algorithms\", IEEE PAMI vol. 18, no. 7, July 1996.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
diff --git a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
index 0103fee6b29d5602b478ff2d448231d09c2bd048..ab2ea6779d2ac2f078ac11d3c15b72926a406cb7 100644
--- a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
@@ -144,18 +144,24 @@ private:
 
     // Documentation
     SetDocName("Segmentation");
-    SetDocLongDescription("This application allows one to perform various segmentation algorithms on a multispectral image."
-                          "Available segmentation algorithms are two different versions of Mean-Shift segmentation algorithm (one being multi-threaded),"
-                          " simple pixel based connected components according to a user-defined criterion, and watershed from the gradient of the intensity"
-                          " (norm of spectral bands vector). The application has two different modes that affects the nature of its output.\n\nIn raster mode,"
-                          " the output of the application is a classical image of unique labels identifying the segmented regions. The labeled output can be passed to the"
-                          " ColorMapping application to render regions with contrasted colours. Please note that this mode loads the whole input image into memory, and as such"
-                          " can not handle large images. \n\n To segment large data, one can use the vector mode. In this case, the output of the application is a"
-                          " vector file or database. The input image is split into tiles (whose size can be set using the tilesize parameter), and each tile is loaded, segmented"
-                          " with the chosen algorithm, vectorized, and written into the output file or database. This piece-wise behavior ensure that memory will never get overloaded,"
-                          " and that images of any size can be processed. There are few more options in the vector mode. The simplify option allows simplifying the geometry"
-                          " (i.e. remove nodes in polygons) according to a user-defined tolerance. The stitch option tries to stitch together the polygons corresponding"
-                          " to segmented region that may have been split by the tiling scheme. ");
+    SetDocLongDescription(
+        "This application allows one to perform various segmentation algorithms on a multispectral image."
+        " Available segmentation algorithms are two different versions of Mean-Shift segmentation algorithm (one being multi-threaded),"
+        " simple pixel based connected components according to a user-defined criterion, and watershed from the gradient of the intensity"
+        " (norm of spectral bands vector). The application has two different modes that affects the nature of its output.\n\n"
+
+        "In raster mode, the output of the application is a classical image of unique labels identifying the segmented regions. The labeled output can be "
+        "passed to the"
+        " ColorMapping application to render regions with contrasted colours. Please note that this mode loads the whole input image into memory, and as such"
+        " can not handle large images.\n\n"
+
+        "To segment large data, one can use the vector mode. In this case, the output of the application is a"
+        " vector file or database. The input image is split into tiles (whose size can be set using the tilesize parameter), and each tile is loaded, segmented"
+        " with the chosen algorithm, vectorized, and written into the output file or database. This piece-wise behavior ensure that memory will never get"
+        " overloaded, and that images of any size can be processed. There are few more options in the vector mode. The simplify option allows simplifying the "
+        "geometry"
+        " (i.e. remove nodes in polygons) according to a user-defined tolerance. The stitch option tries to stitch together the polygons corresponding"
+        " to segmented region that may have been split by the tiling scheme. ");
 
     SetDocLimitations("In raster mode, the application can not handle large input images. Stitching step of vector mode might become slow with very large input images."
                      " \nMeanShift filter results depends on the number of threads used. \nWatershed and multiscale geodesic morphology segmentation will be performed on the amplitude "
@@ -189,10 +195,6 @@ private:
     SetParameterDescription("filter.meanshift.minsize", "Minimum size of a region (in pixel unit) in segmentation. Smaller clusters will be merged to the neighboring cluster with the closest radiometry."
       " If set to 0 no pruning is done.");
 
-    //AddParameter(ParameterType_Empty, "filter.meanshift.useoptim", "use optimization");
-    //SetParameterDescription("filter.meanshift.useoptim", "Use mode optimization.");
-    //MandatoryOff("filter.meanshift.useoptim");
-
     SetDefaultParameterInt("filter.meanshift.spatialr", 5);
     SetDefaultParameterFloat("filter.meanshift.ranger", 15.0);
     SetDefaultParameterFloat("filter.meanshift.thres", 0.1);
diff --git a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
index 138da7fef51fbf90a67e9fc92d4115dad34b68a2..eaaf47d580086238a5a27cb8e7b89e6d162d8635 100644
--- a/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
+++ b/Modules/Applications/AppStereo/app/otbBlockMatching.cxx
@@ -131,25 +131,28 @@ private:
       " between two images.");
 
     SetDocName("Pixel-wise Block-Matching");
-    SetDocLongDescription("This application allows one to performs "
+    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 correspondence is evaluated for each "
+
+      "The application searches locally for the displacement between a reference "
+      "image and a secondary image. The correspondence is evaluated for each "
       "pixel, based on a pair of local neighborhood windows. The displacement "
       "evaluated can be 1D (along lines) or 2D. Parameters allow setting 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"                    
+      "match between two local windows:\n\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)."
@@ -162,7 +165,7 @@ private:
       " 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 "
+      "have three bands: horizontal disparity, vertical disparity and metric "
       "value). One can split these images afterward.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
diff --git a/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx b/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx
index 551ad0f1e4b267f87d2b57659ee9e27df61c88c5..2807f2d408699a6c55cbd95a3b37b1e56decb031 100644
--- a/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx
+++ b/Modules/Applications/AppStereo/app/otbDisparityMapToElevationMap.cxx
@@ -68,27 +68,29 @@ private:
     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 "
+    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"
+      "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 "
+      " map). The algorithm for each disparity is the following:\n\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 "
+      "* 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 "
+      "* 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"
+      "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"
@@ -200,8 +202,8 @@ private:
     m_DispToElev->UpdateOutputInformation();
     FloatVectorImageType::RegionType outputRegion = m_DispToElev->GetOutput()->GetLargestPossibleRegion();
 
-    otbAppLogINFO(<<"Elevation map origin : [" << m_DispToElev->GetOutput()->GetOrigin()[0] << "," << m_DispToElev->GetOutput()->GetOrigin()[1] <<  "]" << std::endl);
-    otbAppLogINFO(<<"Elevation map size : [" << outputRegion.GetSize()[0] << "," << outputRegion.GetSize()[1] << "]" << std::endl);
+    otbAppLogINFO(<<"Elevation map origin: [" << m_DispToElev->GetOutput()->GetOrigin()[0] << "," << m_DispToElev->GetOutput()->GetOrigin()[1] <<  "]" << std::endl);
+    otbAppLogINFO(<<"Elevation map size: [" << outputRegion.GetSize()[0] << "," << outputRegion.GetSize()[1] << "]" << std::endl);
 
     this->SetParameterOutputImage("io.out",m_DispToElev->GetOutput());
   }
diff --git a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
index 791d5a223eeb9711a849b37569922f311f21a418..840b158b55c394e65ce2901e351361d9d7018f9d 100644
--- a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
+++ b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
@@ -323,23 +323,25 @@ private:
       "between one or multiple stereo pair in sensor geometry. The output is "
       "projected in desired geographic or cartographic map projection (WGS84 by"
       " default).\n\n"
+
       "This application is chaining different processing steps. Some of them "
       "are also performed by other applications in the stereo-reconstruction "
-      "framework:\n"
-      "  * StereoRectificationGridGenerator [1] : for the generation of deformation grids\n"
-      "  * GridBasedImageResampling [2] : resampling into epipolar geometry\n"
-      "  * BlockMatching [3] : estimation of dense disparity maps\n\n"
-      "The pipeline executes the following steps on each stereo pair:\n"
-      "  - compute the epipolar displacement grids from the stereo pair (direct and inverse)\n"
-      "  - resample the stereo pair into epipolar geometry using BCO interpolation\n"
-      "  - create masks for each epipolar image : remove black borders and resample"
-      " input masks\n"
-      "  - compute horizontal disparities with a block matching algorithm\n"
-      "  - refine disparities to sub-pixel precision with a dichotomy algorithm\n"
-      "  - apply an optional median filter\n"
-      "  - filter disparities based on the correlation score and exploration bounds\n"
-      "  - translate disparities in sensor geometry\n"
-      "  - convert disparity to 3D Map.\n\n"
+      "framework:\n\n"
+      "* StereoRectificationGridGenerator [1] : for the generation of deformation grids\n"
+      "* GridBasedImageResampling [2] : resampling into epipolar geometry\n"
+      "* BlockMatching [3] : estimation of dense disparity maps\n\n"
+
+      "The pipeline executes the following steps on each stereo pair:\n\n"
+      "* compute the epipolar displacement grids from the stereo pair (direct and inverse)\n"
+      "* resample the stereo pair into epipolar geometry using BCO interpolation\n"
+      "* create masks for each epipolar image : remove black borders and resample input masks\n"
+      "* compute horizontal disparities with a block matching algorithm\n"
+      "* refine disparities to sub-pixel precision with a dichotomy algorithm\n"
+      "* apply an optional median filter\n"
+      "* filter disparities based on the correlation score and exploration bounds\n"
+      "* translate disparities in sensor geometry\n"
+      "* convert disparity to 3D Map.\n\n"
+
       "Then all 3D maps are fused to produce DSM. The fusion method in each "
       "DEM cell can be chosen between maximum, minimum and average.");
     SetDocLimitations(" ");
@@ -422,32 +424,32 @@ private:
     AddChoice("output.mode.user", "User Defined");
     SetParameterDescription("output.mode.user","This mode allows you to fully modify default values.");
     // Upper left point coordinates
-    AddParameter(ParameterType_Float, "output.mode.user.ulx", "Upper Left X ");
+    AddParameter(ParameterType_Float, "output.mode.user.ulx", "Upper Left X");
     SetParameterDescription("output.mode.user.ulx","Cartographic X coordinate "
       "of upper-left corner (meters for cartographic projections, degrees for"
       " geographic ones)");
 
-    AddParameter(ParameterType_Float, "output.mode.user.uly", "Upper Left Y ");
+    AddParameter(ParameterType_Float, "output.mode.user.uly", "Upper Left Y");
     SetParameterDescription("output.mode.user.uly","Cartographic Y coordinate "
       "of the upper-left corner (meters for cartographic projections, degrees "
       "for geographic ones)");
 
     // Size of the output image
-    AddParameter(ParameterType_Int, "output.mode.user.sizex", "Size X ");
+    AddParameter(ParameterType_Int, "output.mode.user.sizex", "Size X");
     SetParameterDescription("output.mode.user.sizex","Size of projected image"
       " along X (in pixels)");
 
-    AddParameter(ParameterType_Int, "output.mode.user.sizey", "Size Y ");
+    AddParameter(ParameterType_Int, "output.mode.user.sizey", "Size Y");
     SetParameterDescription("output.mode.user.sizey","Size of projected image"
       " along Y (in pixels)");
 
     // Spacing of the output image
-    AddParameter(ParameterType_Float, "output.mode.user.spacingx", "Pixel Size X ");
+    AddParameter(ParameterType_Float, "output.mode.user.spacingx", "Pixel Size X");
     SetParameterDescription("output.mode.user.spacingx","Size of each pixel "
       "along X axis (meters for cartographic projections, degrees for geographic ones)");
 
 
-    AddParameter(ParameterType_Float, "output.mode.user.spacingy", "Pixel Size Y ");
+    AddParameter(ParameterType_Float, "output.mode.user.spacingy", "Pixel Size Y");
     SetParameterDescription("output.mode.user.spacingy","Size of each pixel "
       "along Y axis (meters for cartographic projections, degrees for geographic ones)");
 
diff --git a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
index c95a08e1d4e0dd52eca5480dac962ea8f2e598e4..b2ac4174e3538e02724a5a6ceacfb292a7c882e3 100644
--- a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
+++ b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
@@ -106,17 +106,21 @@ private:
       "geometry, a pair of stereo images up to the sensor model precision");
 
     SetDocName("Stereo-rectification deformation grid generator");
-    SetDocLongDescription("This application generates a pair of deformation "
+    SetDocLongDescription(
+      "This application generates a pair of deformation "
       "grid to stereo-rectify a pair of stereo images according to sensor "
       "modelling and a mean elevation hypothesis.\n\n"
+
       "This application is the first part of the stereo reconstruction "
       "framework. The output deformation grids can be passed to the "
       "GridBasedImageResampling application for actual resampling into epipolar"
       " geometry.\n\n"
-      "There are several ways to set the elevation source:\n"
-      "  * An arbitrary constant elevation\n"
-      "  * A DEM directory\n"
-      "  * Compute an average elevation from a DEM\n\n"
+
+      "There are several ways to set the elevation source:\n\n"
+      "* An arbitrary constant elevation\n"
+      "* A DEM directory\n"
+      "* Compute an average elevation from a DEM\n\n"
+
       "If needed, the application can compute inverse resampling grids (from "
       "epipolar to original sensor geometry). Don't forget to check the other "
       "outputs from the application. For instance, the application gives the "
diff --git a/Modules/Applications/AppTest/app/otbTestApplication.cxx b/Modules/Applications/AppTest/app/otbTestApplication.cxx
index 42f11fb32742a8f606a53f762b72516e3acde470..0aed3c6682ca765e35db0d7ddee1cafbc6241eda 100644
--- a/Modules/Applications/AppTest/app/otbTestApplication.cxx
+++ b/Modules/Applications/AppTest/app/otbTestApplication.cxx
@@ -56,7 +56,6 @@ private:
     AddDocTag("Test");
 
     //std::cout << "TestApplication::DoInit" << std::endl;
-    AddParameter(ParameterType_Empty, "empty", "Boolean (old impl.)");
     AddParameter(ParameterType_Bool, "boolean", "Boolean");
     AddParameter(ParameterType_Int, "int", "Integer");
     MandatoryOff("int");
diff --git a/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx b/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
index 636b3808081b19a9c69c740b4f0f7954be5db90f..eef180fbb1febea4ececa14913b6bbee88f6b688 100644
--- a/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
+++ b/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
@@ -62,33 +62,6 @@ bool CheckNoNewline(const DocElement & elem)
   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)
@@ -149,16 +122,9 @@ int otbWrapperApplicationDocTest(int argc, char* argv[])
 
     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;
@@ -170,7 +136,7 @@ int otbWrapperApplicationDocTest(int argc, char* argv[])
     otb::Wrapper::DocExampleStructure::Pointer doc = app->GetDocExample();
     if( doc->GetApplicationName() == "" )
       {
-      std::cout<<"Error in doc example: no aaplication name found."<<std::endl;
+      std::cout<<"Error in doc example: no application name found."<<std::endl;
       isOK = false;
       }
     if( doc->GetParameterList().size() == 0 )
diff --git a/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx b/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx
index fdf5f44e7c3f5c48e362711a2162c578878fa083..0f0373fb21adeb4afd1d9cb743af604d23f13d8d 100644
--- a/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx
+++ b/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx
@@ -74,21 +74,24 @@ SetDescription("Computes Haralick textural features on the selected channel of t
 
 // Documentation
 SetDocName("Haralick Texture Extraction");
-SetDocLongDescription("This application computes three sets of Haralick features [1][2].\n"
-    "  * simple: a set of 8 local Haralick features: Energy (texture uniformity) , "
+SetDocLongDescription(
+    "This application computes three sets of Haralick features [1][2].\n\n"
+
+    "* simple: a set of 8 local Haralick features: Energy (texture uniformity) , "
     "Entropy (measure of randomness of intensity image), Correlation (how "
     "correlated a pixel is to its neighborhood), Inverse Difference Moment (measures "
     "the texture homogeneity), Inertia (intensity contrast between a pixel and its "
     "neighborhood), Cluster Shade, Cluster Prominence, Haralick Correlation;\n"
-    "  * advanced: a set of 10 advanced Haralick features : Mean, Variance (measures the "
+    "* advanced: a set of 10 advanced Haralick features: Mean, Variance (measures the "
     "texture heterogeneity), Dissimilarity, Sum Average, Sum Variance, Sum Entropy, "
     "Difference of Entropies, Difference of Variances, IC1, IC2;\n"
-    "  * higher: a set of 11 higher Haralick features : Short Run Emphasis (measures the "
+    "* higher: a set of 11 higher Haralick features: Short Run Emphasis (measures the "
     "texture sharpness), Long Run Emphasis (measures the texture roughness), Grey-Level "
     "Nonuniformity, Run Length Nonuniformity, Run Percentage (measures the texture "
     "sharpness homogeneity), Low Grey-Level Run Emphasis, High Grey-Level Run Emphasis, "
     "Short Run Low Grey-Level Emphasis, Short Run High Grey-Level Emphasis, Long Run Low "
     "Grey-Level Emphasis and Long Run High Grey-Level Emphasis.");
+
 SetDocLimitations("The computation of the features is based on a Gray Level Co-occurrence "
     "matrix (GLCM) from the quantized input image. Consequently the quantization "
     "parameters (min, max, nbbin) must be appropriate to the range of the pixel values.");
diff --git a/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx b/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx
index ce741c94d66b71df0c327b0c3e9fccead967c67f..250c79a05d228fccbd6d4977e80392998f6e2b7a 100644
--- a/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx
+++ b/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx
@@ -63,10 +63,18 @@ private:
   void DoInit() override
     {
     SetName("Rasterization");
-    SetDescription("Rasterize a vector dataset.");
+    SetDescription("Reproject and rasterize a vector dataset");
 
     SetDocName("Rasterization");
-    SetDocLongDescription("This application allows reprojecting and rasterize a vector dataset. The grid of the rasterized output can be set by using a reference image, or by setting all parmeters (origin, size, spacing) by hand. In the latter case, at least the spacing (ground sampling distance) is needed (other parameters are computed automatically). The rasterized output can also be in a different projection reference system than the input dataset.\n There are two rasterize mode available in the application. The first is the binary mode: it allows rendering all pixels belonging to a geometry of the input dataset in the foreground color, while rendering the other in background color. The second one allows rendering pixels belonging to a geometry with respect to an attribute of this geometry. The field of the attribute to render can be set by the user. In the second mode, the background value is still used for unassociated pixels.");
+    SetDocLongDescription(
+        "Reproject and rasterize a vector dataset. The grid of the rasterized output can be set by using a reference image, or by "
+        "setting all parmeters (origin, size, spacing) by hand. In the latter case, at least the spacing (ground sampling distance) is needed (other "
+        "parameters are computed automatically). The rasterized output can also be in a different projection reference system than the input dataset.\n\n"
+
+        "There are two rasterize mode available in the application. The first is the binary mode: it allows rendering all pixels belonging to a geometry of the "
+        "input dataset in the foreground color, while rendering the other in background color. The second one allows rendering pixels belonging to a geometry "
+        "with respect to an attribute of this geometry. The field of the attribute to render can be set by the user. In the second mode, the background value "
+        "is still used for unassociated pixels.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("For now, support of input dataset with multiple layers having different projection reference system is limited.");
diff --git a/Modules/Core/Functor/include/otbFunctorImageFilter.h b/Modules/Core/Functor/include/otbFunctorImageFilter.h
index b5fb4a2ff9ed8ab67baff13db10ca676e2dddd1a..047a1e6ca84200c16079f491c07f39d95198ba48 100644
--- a/Modules/Core/Functor/include/otbFunctorImageFilter.h
+++ b/Modules/Core/Functor/include/otbFunctorImageFilter.h
@@ -298,6 +298,29 @@ public:
   
   /** Run-time type information (and related methods). */
   itkTypeMacro(FunctorImageFilter, VariadicInputsImageFilter);
+
+  /** New() macro defined only if TFunction is default constructible */
+  template <typename F = TFunction> static std::enable_if_t<std::is_default_constructible<F>::value, Pointer> New()
+  {
+    // Explicit default construct
+    FunctorType f;
+
+    // Create a filter out of it
+    Pointer  p = new Self(f, {{0,0}});
+    p->UnRegister();
+    return p;
+  }
+
+    /** New() macro defined only if TFunction is NOT default constructible
+     * This will yield an error message since New() can not be implemented in this case. */
+  template <typename F = TFunction> static std::enable_if_t<!std::is_default_constructible<F>::value, Pointer> New()
+  {
+    static_assert(std::is_default_constructible<F>::value,"Cannot call New() "
+      "function as the functor used for the filter creation is not default "
+      "constructible");
+
+    return nullptr;
+  }
   
   /** Get the functor object.
    * 
@@ -417,7 +440,6 @@ template <typename Functor, typename TNameMap = void> auto NewFunctorFilter(Func
   return  NewFunctorFilter<FunctorType,TNameMap>(decoratedF,radius);
 }
 
-
 }// namespace otb
 
 #ifndef OTB_MANUAL_INSTANTIATION
diff --git a/Modules/Core/Functor/test/otbFunctorImageFilter.cxx b/Modules/Core/Functor/test/otbFunctorImageFilter.cxx
index bc3c5f624f848c90a5e4b25950477c0e38cac9e3..d2c803c252c9b53f0074aa3d689bc699050b6768 100644
--- a/Modules/Core/Functor/test/otbFunctorImageFilter.cxx
+++ b/Modules/Core/Functor/test/otbFunctorImageFilter.cxx
@@ -162,6 +162,11 @@ template <typename TOut,typename TIn> struct TestOperatorVoidReturn
   res = filter1->GetVariadicNamedInput(tag{});
   filter1->Update();
 
+  // Test static New() operator
+  auto oldStyleNewFilter = FunctorImageFilter<decltype(functor)>::New();
+  oldStyleNewFilter->SetVariadicInputs(in);
+  oldStyleNewFilter->Update();
+
   // Hack to silent -Wunused-but-set-variable
   std::cout<<res<<std::endl;
 
diff --git a/Modules/Feature/Descriptors/test/otbFourierMellinImageFilter.cxx b/Modules/Feature/Descriptors/test/otbFourierMellinImageFilter.cxx
index 38534ca1fb08d4645c4495f0a93aaa91ef9aaa01..742edb5289d253579c664b149fc867dc4f85d791 100644
--- a/Modules/Feature/Descriptors/test/otbFourierMellinImageFilter.cxx
+++ b/Modules/Feature/Descriptors/test/otbFourierMellinImageFilter.cxx
@@ -90,6 +90,8 @@ int otbFourierMellinImageFilter(int itkNotUsed(argc), char* argv[])
   imaginaryWriter->SetInput(imaginaryRescaler->GetOutput());
   imaginaryWriter->Update();
   // Hugly hack for cleaning fftw threads
+  #if defined( ITK_USE_FFTWF ) || defined( ITK_USE_FFTWD )
   fftw_cleanup_threads();
+  #endif
   return EXIT_SUCCESS;
 }
diff --git a/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.hxx
index cfe1cac226458bbc256102423e2888aa29e638a2..5588ccbe7aa87ea58510da4a4dcbd423a1fd1f77 100644
--- a/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbLibSVMMachineLearningModel.hxx
@@ -66,7 +66,7 @@ LibSVMMachineLearningModel<TInputValue,TOutputValue>
   this->m_Problem.l = 0;
   this->m_Problem.y = nullptr;
   this->m_Problem.x = nullptr;
-#ifndef NDEBUG
+#ifdef NDEBUG
   svm_set_print_string_function(&otb::Utils::PrintNothing);
 #endif
 }
diff --git a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
index fce0459c83ff12661b6194bcf07f8a594f6dcd98..7bbc7f2df4e4939f9b66d123886abce9bef52da8 100644
--- a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
@@ -157,6 +157,8 @@ public:
       unsigned long startLine;
       TimeType      azimuthStopTime;
       unsigned long endLine;
+      unsigned long startSample;
+      unsigned long endSample;
       friend std::ostream & operator<<(std::ostream & os, const BurstRecordType & v)
       {
          return os << "{ azimuthStartTime: " << v.azimuthStartTime
@@ -454,6 +456,7 @@ protected:
    static const double C;
 
    static const unsigned int thePluginVersion; // version of the SarSensorModel plugin
+   static const unsigned int thePluginVersionMin; // minimal version required of the SarSensorModel plugin
 
 private:
    /** Disabled assignment operator.  */
diff --git a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModelPathsAndKeys.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModelPathsAndKeys.h
index 49a874addb352d887b0b056b1eaf80a7ea1ddf51..97c5d81de3b376565f2cdefc03b1d8785906fbf3 100644
--- a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModelPathsAndKeys.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModelPathsAndKeys.h
@@ -61,6 +61,8 @@ namespace ossimplugins {
    extern const std::string keyVelZ             ;
    extern const std::string keyStartLine        ;
    extern const std::string keyEndLine          ;
+   extern const std::string keyStartSample      ;
+   extern const std::string keyEndSample        ;
    extern const std::string keyAzimuthStartTime ;
    extern const std::string keyAzimuthStopTime  ;
 } // ossimplugins namespace
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
index 61e85f63c090b292f148b0019ddef1ac3ec59689..31c046fe6baed47cf66876f07021e43d2c7a5fd5 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
@@ -107,7 +107,8 @@ namespace ossimplugins
 
    const double ossimSarSensorModel::C = 299792458;
 
-   const unsigned int ossimSarSensorModel::thePluginVersion = 2;
+   const unsigned int ossimSarSensorModel::thePluginVersion = 3;
+  const unsigned int ossimSarSensorModel::thePluginVersionMin = 2;
 
    ossimSarSensorModel::ProductType::ProductType(string_view const& s)
    {
@@ -1166,7 +1167,22 @@ bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeT
          ossimSarSensorModel::BurstRecordType burstRecord;
          get(kwl, burstPrefix + keyStartLine,        burstRecord.startLine);
          get(kwl, burstPrefix + keyEndLine,          burstRecord.endLine);
-         get(kwl, burstPrefix + keyAzimuthStartTime, burstRecord.azimuthStartTime);
+	 
+	 try {
+            unsigned int version;
+            get(kwl, HEADER_PREFIX, "version", version);
+	    // startSample and endSample since version 3
+            if (version >= 3) 
+	      {
+                get(kwl, burstPrefix + keyStartSample,        burstRecord.startSample);
+		get(kwl, burstPrefix + keyEndSample,          burstRecord.endSample);
+	      }
+         } 
+	 catch (...) {
+            throw std::runtime_error("Geom file generated with previous version of ossim plugins");
+         }
+        
+	 get(kwl, burstPrefix + keyAzimuthStartTime, burstRecord.azimuthStartTime);
          get(kwl, burstPrefix + keyAzimuthStopTime,  burstRecord.azimuthStopTime);
          burstRecords.push_back(burstRecord);
       }
@@ -1185,6 +1201,8 @@ bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeT
 
      add(kwl, burstPrefix + keyStartLine, (ossim_uint32) burstRecords[burstId].startLine);
      add(kwl, burstPrefix + keyEndLine, (ossim_uint32) burstRecords[burstId].endLine);
+     add(kwl, burstPrefix + keyStartSample, (ossim_uint32) burstRecords[burstId].startSample);
+     add(kwl, burstPrefix + keyEndSample, (ossim_uint32) burstRecords[burstId].endSample);
      add(kwl, burstPrefix + keyAzimuthStartTime, burstRecords[burstId].azimuthStartTime);
      add(kwl, burstPrefix + keyAzimuthStopTime,  burstRecords[burstId].azimuthStopTime);
      }
@@ -1389,7 +1407,7 @@ bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeT
          try {
             unsigned int version;
             get(kwl, HEADER_PREFIX, "version", version);
-            if (version < thePluginVersion) {
+            if (version < thePluginVersionMin) {
                throw std::runtime_error("Geom file generated with previous version of ossim plugins");
             }
          } catch (...) {
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp
index ad5bcf1efe5d86296a8e1f650e3fff400904059c..efc607357c5fbb608e023f4f56aa40d3a423f14b 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp
@@ -26,39 +26,41 @@
 #include "ossim/ossimSarSensorModelPathsAndKeys.h"
 
 namespace ossimplugins {
-   const std::string HEADER_PREFIX       = "header.";
-   const std::string SUPPORT_DATA_PREFIX = "support_data.";
-   const std::string GEOM_PREFIX         = "support_data.geom";
-   const std::string SRD_PREFIX          = "support_data.geom.srd";
-   const std::string SR_PREFIX           = "support_data.geom.srd.coords.sr";
-   const std::string GR_PREFIX           = "support_data.geom.srd.coords.gr";
-   const std::string BURST_PREFIX        = "support_data.geom.bursts.burst";
-   const std::string BURST_NUMBER_KEY    = "support_data.geom.bursts.number";
-   const std::string ORBIT_PREFIX        = "orbitList.orbit";
-   const std::string ORBIT_NUMBER_KEY    = "orbitList.nb_orbits";
-   const std::string GCP_PREFIX          = "support_data.geom.gcp";
-   const std::string GCP_NUMBER_KEY      = "support_data.geom.gcp.number";
-   const std::string NUMBER_KEY          = "number";
+  const std::string HEADER_PREFIX       = "header.";
+  const std::string SUPPORT_DATA_PREFIX = "support_data.";
+  const std::string GEOM_PREFIX         = "support_data.geom";
+  const std::string SRD_PREFIX          = "support_data.geom.srd";
+  const std::string SR_PREFIX           = "support_data.geom.srd.coords.sr";
+  const std::string GR_PREFIX           = "support_data.geom.srd.coords.gr";
+  const std::string BURST_PREFIX        = "support_data.geom.bursts.burst";
+  const std::string BURST_NUMBER_KEY    = "support_data.geom.bursts.number";
+  const std::string ORBIT_PREFIX        = "orbitList.orbit";
+  const std::string ORBIT_NUMBER_KEY    = "orbitList.nb_orbits";
+  const std::string GCP_PREFIX          = "support_data.geom.gcp";
+  const std::string GCP_NUMBER_KEY      = "support_data.geom.gcp.number";
+  const std::string NUMBER_KEY          = "number";
 
-   const std::string keySr0              = "sr0";
-   const std::string keyGr0              = "gr0";
-   const std::string keyAzimuthTime      = "azimuthTime";
-   const std::string keySlantRangeTime   = "slant_range_time";
-   const std::string keyImPtX            = "im_pt.x";
-   const std::string keyImPtY            = "im_pt.y";
-   const std::string keyWorldPtLat       = "world_pt.lat";
-   const std::string keyWorldPtLon       = "world_pt.lon";
-   const std::string keyWorldPtHgt       = "world_pt.hgt";
-   const std::string keyTime             = "time";
-   const std::string keyPosX             = "x_pos";
-   const std::string keyPosY             = "y_pos";
-   const std::string keyPosZ             = "z_pos";
-   const std::string keyVelX             = "x_vel";
-   const std::string keyVelY             = "y_vel";
-   const std::string keyVelZ             = "z_vel";
-   const std::string keyStartLine        = "start_line";
-   const std::string keyEndLine          = "end_line";
-   const std::string keyAzimuthStartTime = "azimuth_start_time";
-   const std::string keyAzimuthStopTime  = "azimuth_stop_time";
+  const std::string keySr0              = "sr0";
+  const std::string keyGr0              = "gr0";
+  const std::string keyAzimuthTime      = "azimuthTime";
+  const std::string keySlantRangeTime   = "slant_range_time";
+  const std::string keyImPtX            = "im_pt.x";
+  const std::string keyImPtY            = "im_pt.y";
+  const std::string keyWorldPtLat       = "world_pt.lat";
+  const std::string keyWorldPtLon       = "world_pt.lon";
+  const std::string keyWorldPtHgt       = "world_pt.hgt";
+  const std::string keyTime             = "time";
+  const std::string keyPosX             = "x_pos";
+  const std::string keyPosY             = "y_pos";
+  const std::string keyPosZ             = "z_pos";
+  const std::string keyVelX             = "x_vel";
+  const std::string keyVelY             = "y_vel";
+  const std::string keyVelZ             = "z_vel";
+  const std::string keyStartLine        = "start_line";
+  const std::string keyEndLine          = "end_line";
+  const std::string keyStartSample      = "start_sample";
+  const std::string keyEndSample        = "end_sample";
+  const std::string keyAzimuthStartTime = "azimuth_start_time";
+  const std::string keyAzimuthStopTime  = "azimuth_stop_time";
 } // ossimplugins namespace
 
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
index e7eda14a36e168a8be44e143f3b944ecc74df482..7133a856fd0f68458191f3e2492d6b0828cad63e 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
@@ -51,6 +51,7 @@ namespace {// Anonymous namespace
    const ossimString attAdsHeader        = "adsHeader";
    const ossimString attAzimuthTime      = "azimuthTime";
    const ossimString attFirstValidSample = "firstValidSample";
+   const ossimString attLastValidSample   = "lastValidSample";
    const ossimString attGr0              = "gr0";
    const ossimString attGrsrCoefficients = "grsrCoefficients";
    const ossimString attHeight           = "height";
@@ -354,10 +355,15 @@ namespace ossimplugins
       const bool ret2 = safePlatform->getChildTextValue(instrumentId, "safe:number");
 
       if (ret1 && ret2) {
-         theManifestKwl.add("support_data.",
+         // theManifestKwl.add("support_data.",
+         //       "instrument",
+         //       "S1" + instrumentId,
+         //       true);
+	theManifestKwl.add("manifest_data.",
                "instrument",
-               "S1" + instrumentId,
-               true);
+                "S1" + instrumentId,
+                true);
+
          return familyName + instrumentId;
       }
       throw std::runtime_error("Cannot obtain Sensor ID");
@@ -401,7 +407,8 @@ namespace ossimplugins
    {
       static const char MODULE[] = "ossimSentinel1ProductDoc::parseSafe";
 
-      const ossimString prefix = "support_data.";
+      //const ossimString prefix = "support_data.";
+      const ossimString prefix = "manifest_data.";
 
       const ossimRefPtr<ossimXmlNode> safeProcessing = manifestDoc.getRoot()->findFirstNode("metadataSection/metadataObject/metadataWrap/xmlData/safe:processing");
       const ossimRefPtr<ossimXmlNode> facility       = safeProcessing->findFirstNode("safe:facility");
@@ -686,6 +693,8 @@ namespace ossimplugins
       add(theProductKwl, HEADER_PREFIX, "version", thePluginVersion);
 
       //RK maybe use this->getManifestPrefix()
+      add(theProductKwl, SUPPORT_DATA_PREFIX, "first_line_time", getTextFromFirstNode(adsHeader, "startTime").string());
+      add(theProductKwl, SUPPORT_DATA_PREFIX, "last_line_time", getTextFromFirstNode(adsHeader, "stopTime").string());
 
       add(theProductKwl, SUPPORT_DATA_PREFIX, "mds1_tx_rx_polar", polarisation);
 
@@ -741,7 +750,10 @@ namespace ossimplugins
       const ossimXmlNode & downlinkInformation =
          getExpectedFirstNode(*productRoot, "generalAnnotation/downlinkInformationList/downlinkInformation");
 
-      addOptional(theProductKwl, SUPPORT_DATA_PREFIX, "pulse_repetition_frequency", downlinkInformation, "prf");
+      //addOptional(theProductKwl, SUPPORT_DATA_PREFIX, "pulse_repetition_frequency", downlinkInformation, "prf");
+      const double azimuthFrequency = getDoubleFromFirstNode(imageInformation, "azimuthFrequency");
+      add(theProductKwl, SUPPORT_DATA_PREFIX, "pulse_repetition_frequency", azimuthFrequency);
+
 
       ossimXmlNode const& swathProcParams =
          getExpectedFirstNode(*productRoot, "imageAnnotation/processingInformation/swathProcParamsList/swathProcParams");
@@ -753,6 +765,12 @@ namespace ossimplugins
       addOptional(theProductKwl, SUPPORT_DATA_PREFIX, "range_looks",       rangeProcessingNode,   "numberOfLooks");
       addOptional(theProductKwl, SUPPORT_DATA_PREFIX, "azimuth_looks",     azimuthProcessingNode, "numberOfLooks");
 
+      // azimuth steering rate for tops_sar only
+      if (theTOPSAR)
+	{
+	  addOptional(theProductKwl, SUPPORT_DATA_PREFIX, "azimuth_steering_rate",  productInformation,   "azimuthSteeringRate");
+	}
+
       if(!theTOPSAR || !theSLC)
       {
          addOptional(theProductKwl, SUPPORT_DATA_PREFIX, ossimKeywordNames::NUMBER_SAMPLES_KW, imageInformation, "numberOfSamples");
@@ -782,6 +800,16 @@ namespace ossimplugins
          addDopplerCentroidCoefficients(*dcEstimateList);
       }
 
+      ossimXmlNodePtr const& aziFmRateList = productRoot->findFirstNode("generalAnnotation/azimuthFmRateList");
+      if (!aziFmRateList)
+	{
+	  ossimNotify(ossimNotifyLevel_DEBUG) << "No azimuth fm rate coefficients available in metadata!!\n";
+	}
+      else
+	{
+	  addAzimuthFmRateCoefficients(*aziFmRateList);
+	}
+
       readBurstRecords(*productRoot, imageInformation);
 
       readGeoLocationGrid(*productRoot);
@@ -935,6 +963,10 @@ namespace ossimplugins
          burstRecord.azimuthStartTime = add(theProductKwl, BURST_PREFIX, "[0].azimuth_start_time", getTimeFromFirstNode(imageInformation,  "productFirstLineUtcTime"));
          burstRecord.azimuthStopTime  = add(theProductKwl, BURST_PREFIX, "[0].azimuth_stop_time",  getTimeFromFirstNode(imageInformation,  "productLastLineUtcTime"));
          burstRecord.endLine          = add(theProductKwl, BURST_PREFIX, "[0].end_line",           getFromFirstNode<unsigned int>(imageInformation, "numberOfLines")-1);
+
+	 burstRecord.startSample = add(theProductKwl, BURST_PREFIX, "[0].start_sample", 0);
+	 burstRecord.endSample   = add(theProductKwl, BURST_PREFIX, "[0].end_sample",  getFromFirstNode<unsigned int>(imageInformation, "numberOfSamples")-1);
+
          theBurstRecords.push_back(burstRecord);
       }
       else
@@ -942,17 +974,22 @@ namespace ossimplugins
          char burstPrefix[1024];
 
          const unsigned int linesPerBurst = getFromFirstNode<unsigned int>(productRoot, "swathTiming/linesPerBurst");
+	 const unsigned int samplesPerBurst = getFromFirstNode<unsigned int>(productRoot, "swathTiming/samplesPerBurst");
+	 
          unsigned int burstId(0);
 
          for(std::vector<ossimRefPtr<ossimXmlNode> >::iterator itNode = xnodes.begin(); itNode!=xnodes.end();++itNode,++burstId)
          {
             BurstRecordType burstRecord;
-            const TimeType azTime = getTimeFromFirstNode(**itNode, attAzimuthTime);
-            ossimString const& s = getTextFromFirstNode(**itNode, attFirstValidSample);
 
-            ossim_int64 first_valid(0), last_valid(0);
+	    ossim_int64 first_valid(0), last_valid(0);
             bool begin_found(false), end_found(false);
+	    ossim_int64 first_sample_valid(0), last_sample_valid(samplesPerBurst-1);
 
+            const TimeType azTime = getTimeFromFirstNode(**itNode, attAzimuthTime);
+
+	    // Scan firstValidSample to define the first valid sample and valid lines
+            ossimString const& s = getTextFromFirstNode(**itNode, attFirstValidSample);
             std::vector<ossimString> ssp = s.split(" ");
 
             for (std::vector<ossimString>::const_iterator sIt = ssp.begin(), e = ssp.end()
@@ -960,6 +997,7 @@ namespace ossimplugins
                   ; ++sIt
                 )
             {
+	      // Find valid lines
                if(!begin_found)
                {
                   if(*sIt!="-1")
@@ -983,11 +1021,62 @@ namespace ossimplugins
                      ++last_valid;
                   }
                }
+
+	       // Find first valid samples
+	       if(*sIt!="-1")
+                  {
+		    int Fvs = samplesPerBurst;
+		    try
+		      {
+			Fvs = std::stoi(*sIt);
+		      }
+		    catch( ... )
+		      {
+			// Throw an execption
+			throw std::runtime_error("Failed to convert firstValidSample value.");
+		      }
+
+		    if (Fvs > first_sample_valid && Fvs < samplesPerBurst)
+		      {
+			first_sample_valid = Fvs; 
+		      }
+		  }
             }
 
+	    // Scan lastValidSample to define the last valid sample
+	    ossimString const& sLast = getTextFromFirstNode(**itNode, attLastValidSample);
+	    std::vector<ossimString> sspLast = sLast.split(" ");
+
+            for (std::vector<ossimString>::const_iterator sIt = sspLast.begin(), e = sspLast.end()
+		   ; sIt != e ; ++sIt)
+	      {
+		// Last first valid samples
+		if(*sIt!="-1")
+                  {
+		    int Lvs = 0;
+		    try
+		      {
+			Lvs = std::stoi(*sIt);
+		      }
+		    catch( ... )
+		      {
+			// Throw an execption
+			throw std::runtime_error("Failed to convert lastValidSample value.");
+		      }
+		    if (Lvs < last_sample_valid && Lvs > 0)
+		      {
+			last_sample_valid = Lvs;
+		      }
+		  }
+	      }
+
             s_printf(burstPrefix, "%s[%d].", BURST_PREFIX.c_str(), burstId);
             burstRecord.startLine = add(theProductKwl,burstPrefix + keyStartLine,         burstId*linesPerBurst + first_valid);
             burstRecord.endLine   = add(theProductKwl,burstPrefix + keyEndLine,           burstId*linesPerBurst + last_valid);
+ 
+	    burstRecord.startSample = add(theProductKwl,burstPrefix + keyStartSample, first_sample_valid);
+            burstRecord.endSample   = add(theProductKwl,burstPrefix + keyEndSample,  last_sample_valid);
+	  
             // TODO: check units.
             burstRecord.azimuthStartTime = add(theProductKwl,burstPrefix + keyAzimuthStartTime, azTime + (first_valid*theAzimuthTimeInterval));
             burstRecord.azimuthStopTime  = add(theProductKwl,burstPrefix + keyAzimuthStopTime,  azTime + (last_valid*theAzimuthTimeInterval));
@@ -995,6 +1084,12 @@ namespace ossimplugins
             theBurstRecords.push_back(burstRecord);
          }
          add(theProductKwl, BURST_NUMBER_KEY, burstId);
+	 
+	 const std::string BURST_NUMBER_LINES_KEY    = "support_data.geom.bursts.number_lines_per_burst";
+	 add(theProductKwl, BURST_NUMBER_LINES_KEY, linesPerBurst);
+
+	 const std::string BURST_NUMBER_SAMPLES_KEY    = "support_data.geom.bursts.number_samples_per_burst";
+	 add(theProductKwl, BURST_NUMBER_SAMPLES_KEY, samplesPerBurst);
       }
    }
 
@@ -1184,6 +1279,11 @@ namespace ossimplugins
       ossimString count_str;
       dcEstimateList.getAttributeValue(count_str, "count");
       const int count  = count_str.toInt();
+
+      char prefix_main[256];
+      s_printf(prefix_main, "dopplerCentroid.dop_coef_nb_list");
+      add(theProductKwl, prefix_main, "", count);
+
       if( count < 1)
       {
          ossimNotify(ossimNotifyLevel_DEBUG) << "No doppler centroid coefficients available in metadata!!\n";
@@ -1206,7 +1306,10 @@ namespace ossimplugins
             assert(dcEstimate.get());
             addOptional(theProductKwl, prefix, "dop_coef_time",  *dcEstimate, "azimuthTime");
             //RK
-            const double ref_time = getOptionalTextFromFirstNode(*dcEstimate, "t0").toFloat64() * 1e9; // s to ns
+            //const double ref_time = getOptionalTextFromFirstNode(*dcEstimate, "t0").toFloat64() * 1e9; // s to ns
+
+	    const double ref_time = getOptionalTextFromFirstNode(*dcEstimate, "t0").toFloat64(); // remain in s
+
             add(theProductKwl, prefix, keySlantRangeTime, ref_time);
 
             ossimString const& ns = getOptionalTextFromFirstNode(*dcEstimate, "ns");
@@ -1228,18 +1331,104 @@ namespace ossimplugins
                for (int count = 1 ; coeff != result.end() ; ++count, ++coeff)
                {
                   char coeff_prefix[256];
-                  s_printf(coeff_prefix, "%s%d.dop_coef", prefix, count);
+                  s_printf(coeff_prefix, "%s%d.geo_dop_coef", prefix, count);
 
                   add(theProductKwl, coeff_prefix, coeff->string());
                }
 
             } //if (!coeffStr.empty())
 
+	    ossimString const& coeffDopStr = getOptionalTextFromFirstNode(*dcEstimate, "dataDcPolynomial");
+
+            if (!coeffDopStr.empty())
+            {
+               const ossimString separatorList = " ";
+               std::vector<ossimString> result;
+
+               coeffDopStr.split(result, separatorList, true);
+
+               std::vector<ossimString>::const_iterator coeff = result.begin();
+
+               for (int count = 1 ; coeff != result.end() ; ++count, ++coeff)
+               {
+                  char coeff_prefix[256];
+                  s_printf(coeff_prefix, "%s%d.dop_coef", prefix, count);
+
+                  add(theProductKwl, coeff_prefix, coeff->string());
+               }
+
+            } //if (!coeffDopStr.empty())
+
          } // for each dcEstimate
 
       } // else count < 1
    }
 
+  void ossimSentinel1Model::addAzimuthFmRateCoefficients(ossimXmlNode const& aziFmRateList)
+  {
+    ossimString count_str;
+    aziFmRateList.getAttributeValue(count_str, "count");
+    const int count  = count_str.toInt();
+
+    char prefix_main[256];
+    s_printf(prefix_main, "azimuthFmRate.azi_fm_rate_coef_nb_list");
+    add(theProductKwl, prefix_main, "", count);
+
+    if( count < 1)
+      {
+	ossimNotify(ossimNotifyLevel_DEBUG) << "No azimuth fm rate coefficients available in metadata!!\n";
+	return;
+      }
+    else
+      {
+	ossimXmlNode::ChildListType azimuthFmRates;
+	aziFmRateList.findChildNodes("azimuthFmRate", azimuthFmRates);
+
+	ossimXmlNode::ChildListType::const_iterator it = azimuthFmRates.begin();
+
+	for (int index = 1 ; it != azimuthFmRates.end() ; ++it, ++index)
+	  {
+	    char prefix[256];
+	    //azimuthFmRate.azi_fm_rate_coef_list;
+            s_printf(prefix, "azimuthFmRate.azi_fm_rate_coef_list%d.", index);
+	    
+	    const ossimXmlNodePtr & azimuthFmRate = *it;
+            assert(azimuthFmRate.get());
+
+	    // AzimuthTime
+            addOptional(theProductKwl, prefix, "azi_fm_rate_coef_time",  *azimuthFmRate, "azimuthTime");
+           
+	    // Slant range time
+	    const double ref_time = getOptionalTextFromFirstNode(*azimuthFmRate, "t0").toFloat64(); // remain in s
+
+            add(theProductKwl, prefix, keySlantRangeTime, ref_time);
+	    
+	    // Coefficients
+	    ossimString const& coeffAziFmRateStr = getOptionalTextFromFirstNode(*azimuthFmRate, "azimuthFmRatePolynomial");
+
+            if (!coeffAziFmRateStr.empty())
+            {
+               const ossimString separatorList = " ";
+               std::vector<ossimString> result;
+
+               coeffAziFmRateStr.split(result, separatorList, true);
+
+               std::vector<ossimString>::const_iterator coeff = result.begin();
+
+               for (int count = 1 ; coeff != result.end() ; ++count, ++coeff)
+               {
+                  char coeff_prefix[256];
+                  s_printf(coeff_prefix, "%s%d.azi_fm_rate_coef", prefix, count);
+
+                  add(theProductKwl, coeff_prefix, coeff->string());
+               }
+
+            } //if (!coeffAziFmRateStr.empty())
+	    
+	  } // for each azimuthFmRate
+      }
+  }
+
    bool ossimSentinel1Model::openMetadataFile(ossimXmlDocument& doc, ossimString const& file) const
    {
       if ( !doc.openFile( file ) )
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h
index 973fe55696450b49894a8e04817172458bf828fb..4eafcbd9367a175d6357fede1a065d2d86fe2a2f 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h
@@ -163,6 +163,7 @@ namespace ossimplugins
       void readGeoLocationGrid(ossimXmlNode const& productRoot);
       void addOrbitStateVectors(ossimXmlNode const& orbitList);
       void addDopplerCentroidCoefficients(ossimXmlNode const& dcEstimateList);
+      void addAzimuthFmRateCoefficients(ossimXmlNode const& aziFmRateList);
       bool openMetadataFile(ossimXmlDocument& doc, ossimString const& file) const;
 
       ossimFilename      theManifestDirectory;
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp
index 99cdf4b094bd76835696df84bf64452c87f03acd..3919efb03c8f35e59b8576d3d939955a48b1e22b 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp
@@ -30,6 +30,7 @@
 namespace {// Anonymous namespace
     const ossimString attAzimuthTime      = "azimuthTime";
     const ossimString attFirstValidSample = "firstValidSample";
+    const ossimString attLastValidSample   = "lastValidSample";
     const ossimString attGr0              = "gr0";
     const ossimString attGrsrCoefficients = "grsrCoefficients";
     const ossimString attHeight           = "height";
@@ -175,11 +176,16 @@ void ossimSentinel1SarSensorModel::readAnnotationFile(const std::string & annota
         burstRecord.azimuthStopTime = getTimeFromFirstNode(xmlRoot,"imageAnnotation/imageInformation/productLastLineUtcTime");
         burstRecord.endLine = getTextFromFirstNode(xmlRoot, "imageAnnotation/imageInformation/numberOfLines").toUInt16()-1;
 
+	burstRecord.startSample = 0;
+	burstRecord.endSample   = getTextFromFirstNode(xmlRoot, "imageAnnotation/imageInformation/numberOfSamples").toUInt16()-1;;
+
         theBurstRecords.push_back(burstRecord);
     }
     else
     {
         const unsigned int linesPerBurst = xmlRoot.findFirstNode("swathTiming/linesPerBurst")->getText().toUInt16();
+	const unsigned int samplesPerBurst = xmlRoot.findFirstNode("swathTiming/samplesPerBurst")->getText().toUInt16();
+
         unsigned int burstId(0);
 
         for(std::vector<ossimRefPtr<ossimXmlNode> >::iterator itNode = xnodes.begin(); itNode!=xnodes.end();++itNode,++burstId)
@@ -188,10 +194,12 @@ void ossimSentinel1SarSensorModel::readAnnotationFile(const std::string & annota
 
             const ossimSarSensorModel::TimeType azTime = getTimeFromFirstNode(**itNode, attAzimuthTime);
 
+	    // Scan firstValidSample to define the first valid sample and valid lines
             ossimString const& s = getTextFromFirstNode(**itNode, attFirstValidSample);
 
             long first_valid(0), last_valid(0);
             bool begin_found(false), end_found(false);
+	    long first_sample_valid(0), last_sample_valid(samplesPerBurst-1);
 
             std::vector<ossimString> ssp = s.split(" ");
 
@@ -200,6 +208,7 @@ void ossimSentinel1SarSensorModel::readAnnotationFile(const std::string & annota
                     ; ++sIt
                 )
             {
+	      // Find valid lines
                 if(!begin_found)
                 {
                     if(*sIt!="-1")
@@ -224,14 +233,63 @@ void ossimSentinel1SarSensorModel::readAnnotationFile(const std::string & annota
                         ++last_valid;
                     }
                 }
+
+		// Find first valid samples
+		if(*sIt!="-1")
+                  {
+		    int Fvs = samplesPerBurst;
+		    try
+		      {
+			Fvs = std::stoi(*sIt);
+		      }
+		    catch( ... )
+		      {
+			// Throw an execption
+			throw std::runtime_error("Failed to convert firstValidSample value.");
+		      }
+		    if (Fvs > first_sample_valid && Fvs < samplesPerBurst)
+		      {
+			first_sample_valid = Fvs; 
+		      }
+		  }
             }
 
+	    // Scan lastValidSample to define the last valid sample
+	    ossimString const& sLast = getTextFromFirstNode(**itNode, attLastValidSample);
+	    std::vector<ossimString> sspLast = sLast.split(" ");
+
+            for (auto const& token : sspLast) 
+	      {
+		// Last first valid samples
+		if(token != "-1")
+                  {
+		    int Lvs = 0;
+		    try
+		      {
+			Lvs = std::stoi(token);
+		      }
+		    catch( ... )
+		      {
+			// Throw an execption
+			throw std::runtime_error("Failed to convert lastValidSample value.");
+		      }
+
+		    if (Lvs < last_sample_valid && Lvs > 0)
+		      {
+			last_sample_valid = Lvs;
+		      }
+		  }
+	      }
+
             burstRecord.startLine = burstId*linesPerBurst + first_valid;
             burstRecord.endLine = burstId*linesPerBurst + last_valid;
 
             burstRecord.azimuthStartTime = azTime + (first_valid*theAzimuthTimeInterval);
             burstRecord.azimuthStopTime = azTime  + (last_valid*theAzimuthTimeInterval);
 
+	    burstRecord.startSample = first_sample_valid;
+            burstRecord.endSample   = last_sample_valid;
+
             theBurstRecords.push_back(burstRecord);
         }
     }
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
index da8aef6b51bf9319c3761f171a328b19fc9386df..debf5cf508d4efff369affcc9efddc5741d64812 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
@@ -190,10 +190,6 @@ public:
    * or a value set externally by user */
   bool HasValue(std::string paramKey) const;
 
-  /* Get active flag of parameter with key paramKey
-   */
-  bool GetParameterEmpty(std::string paramKey);
-
   /** Set HasUserValue flag of parameter with key paramKey
    *  Note that when this function is called from DoInit, DoUpdateParameters
    *  or DoExecute, it will always set this flag to false, because this is
@@ -226,6 +222,7 @@ public:
    *
    * Can be called for types :
    * \li ParameterType_Int
+   * \li ParameterType_Bool
    * \li ParameterType_Float
    * \li ParameterType_Radius
    * \li ParameterType_Choice
@@ -246,6 +243,7 @@ public:
    * \li ParameterType_InputVectorDataListParameter
    * \li ParameterType_InputFilenameListParameter
    * \li ParameterType_StringList
+   * \li ParameterType_ListView
    */
   void SetParameterString(std::string parameter, std::string value, bool hasUserValueFlag = true);
 
@@ -253,6 +251,8 @@ public:
    *
    * Can be called for types :
    * \li ParameterType_String
+   * \li ParameterType_StringList
+   * \li ParameterType_ListView
    * \li ParameterType_InputFilename
    * \li ParameterType_OutputFilename
    * \li ParameterType_Directory
@@ -268,8 +268,6 @@ public:
    */
   void SetParameterStringList(std::string parameter, std::vector<std::string> values, bool hasUserValueFlag = true);
 
-  void SetParameterEmpty(std::string parameter, bool value, bool hasUserValueFlag = true);
-
   /** Checks if the application is ready to be executed. It checks that there
    *  is no missing parameter
    */
@@ -431,6 +429,7 @@ public:
    *
    * Can be called for types :
    * \li ParameterType_Int
+   * \li ParameterType_Bool
    * \li ParameterType_Float
    * \li ParameterType_Radius
    * \li ParameterType_Choice
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperBoolParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperBoolParameter.h
index 28ac6bf66862edada93834697d0895ee79da7529..dae2fb7edaa348830367a0cfc2b931203099e190 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperBoolParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperBoolParameter.h
@@ -33,8 +33,6 @@ namespace Wrapper
 /** \class BoolParameter
  *  \brief This class represent a boolean parameter for the wrapper framework
  *
- *  It is intended to replace the deprecated EmptyParameter
- * 
  * \ingroup OTBApplicationEngine
  */
 class OTBApplicationEngine_EXPORT BoolParameter
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperEmptyParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperEmptyParameter.h
deleted file mode 100644
index a71cad06ba3c2bc0ba1fcd45294a48a6f4340bd0..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperEmptyParameter.h
+++ /dev/null
@@ -1,86 +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.
- */
-
-#ifndef otbWrapperEmptyParameter_h
-#define otbWrapperEmptyParameter_h
-
-#include "otbWrapperParameter.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-
-/** \class EmptyParameter
- *  \brief This class represent an empty parameter for the wrapper framework (boolean value)
- *
- * \deprecated in OTB 6.6, use BoolParameter instead
- *
- * \ingroup OTBApplicationEngine
- */
-class OTBApplicationEngine_EXPORT EmptyParameter
-  : public Parameter
-{
-public:
-  /** Standard class typedef */
-  typedef EmptyParameter                Self;
-  typedef Parameter                     Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Defining ::New() static method */
-  itkNewMacro(Self);
-
-  /** RTTI support */
-  itkTypeMacro(EmptyParameter, Parameter);
-
-  /** HasValue */
-  bool HasValue() const override
-  {
-    return false;
-  }
-
-  bool HasUserValue() const override
-  {
-    return this->m_UserValue;
-  }
-
-protected:
-  /** Constructor */
-  EmptyParameter()
-  {
-  // It does not make sense for an empty parameter to be mandatory
-  this->MandatoryOff();
-  }
-
-  /** Destructor */
-  ~EmptyParameter() override
-  {}
-
-private:
-  EmptyParameter(const EmptyParameter &) = delete;
-  void operator =(const EmptyParameter&) = delete;
-
-}; // End class Parameter
-
-} // End namespace Wrapper
-} // End namespace otb
-
-#endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
index bf51898aa92afed9ebad8929ba74ae403655e929..6f99abe774bdb5f86f4de1f0fa0fa5cd4e15d088 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
@@ -35,7 +35,6 @@ namespace Wrapper
 
 typedef enum
 {
-  ParameterType_Empty,
   ParameterType_Int,
   ParameterType_Float,
   ParameterType_String,
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
index 9f820a3e8f6382dc267c72f1d1b52e85ab911e9c..dbeac1e3aa3f65f2dfa68c8af67691c7f8026624 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
@@ -22,7 +22,6 @@
 #include "otbWrapperChoiceParameter.h"
 #include "otbWrapperListViewParameter.h"
 #include "otbWrapperDirectoryParameter.h"
-#include "otbWrapperEmptyParameter.h"
 #include "otbWrapperInputFilenameParameter.h"
 #include "otbWrapperInputFilenameListParameter.h"
 #include "otbWrapperOutputFilenameParameter.h"
@@ -280,9 +279,7 @@ const std::string& Application::GetDocLink() const
 
 void Application::SetOfficialDocLink()
 {
-  std::string link = "http://www.orfeo-toolbox.org/Applications/";
-  link.append(this->GetName());
-  link.append(".html");
+  const std::string link = std::string("https://www.orfeo-toolbox.org/CookBook/Applications/app_") + this->GetName() + ".html";
   this->SetDocLink(link);
 }
 
@@ -380,6 +377,10 @@ void Application::SetParameterInt(std::string parameter, int value, bool hasUser
     BoolParameter* paramBool = dynamic_cast<BoolParameter*>(param);
     paramBool->SetValue(static_cast<bool>(value));
     }
+  else
+    {
+    otbAppLogWARNING(<< "SetParameterInt on parameter " + parameter);
+    }
 
   this->SetParameterUserValue(parameter, hasUserValueFlag);
 }
@@ -538,12 +539,6 @@ void Application::SetParameterStringList(std::string parameter, std::vector<std:
   this->SetParameterUserValue(parameter, hasUserValueFlag);
 }
 
-void Application::SetParameterEmpty(std::string parameter, bool value, bool hasUserValueFlag)
-{
-  this->SetParameterUserValue(parameter, hasUserValueFlag);
-  GetParameterByKey(parameter)->SetActive(value);
-}
-
 void Application::SetParameterUserValue(std::string paramKey, bool value)
 {
   /** UserValue is set/unset parameter must be active.
@@ -1086,11 +1081,6 @@ Role Application::GetParameterRole(std::string paramKey) const
   return GetParameterByKey(paramKey)->GetRole();
 }
 
-bool Application::GetParameterEmpty(std::string paramKey)
-{
-  return GetParameterByKey(paramKey)->GetActive();
-}
-
 /* Return the role (input/output) of a parameter */
 void Application::SetParameterRole(std::string paramKey, Role role)
 {
@@ -1116,10 +1106,6 @@ ParameterType Application::GetParameterType(std::string paramKey) const
     {
     type = ParameterType_Radius;
     }
-  else if (dynamic_cast<const EmptyParameter*>(param))
-    {
-    type = ParameterType_Empty;
-    }
  else if (dynamic_cast<const IntParameter*>(param))
     {
     type = ParameterType_Int;
@@ -1550,11 +1536,6 @@ int Application::GetParameterInt(std::string parameter)
     BoolParameter* paramBool = dynamic_cast<BoolParameter*>(param);
     ret = static_cast<int>(paramBool->GetValue());
     }
-  else if (dynamic_cast<EmptyParameter*>(param))
-    {
-    // This case is here for compatibility purpose with deprecated EmptyParameter
-    ret = static_cast<int>(this->IsParameterEnabled(parameter));
-    }
   else
     {
      itkExceptionMacro(<<parameter << " parameter can't be casted to int");
@@ -2014,9 +1995,15 @@ std::string Application::GetParameterAsString(std::string paramKey)
     {
       std::ostringstream oss;
       oss << std::setprecision(10);
-      const std::vector<std::string> strList = this->GetParameterStringList( paramKey );
-      for (unsigned int i=0; i<strList.size(); i++)
-        oss << strList[i] << std::endl;
+      const std::vector<std::string> strList = this->GetParameterStringList(paramKey);
+      for (size_t i = 0; i < strList.size(); i++)
+      {
+        if (i != 0)
+        {
+          oss << " ";
+        }
+        oss << strList[i];
+      }
       ret = oss.str();
     }
   else
@@ -2097,11 +2084,9 @@ void Application::AddRAMParameter(std::string paramKey, std::string paramName, u
 void Application::AddRAMParameter(std::string paramKey)
 {
   // Get the  RAM Parameter from the configuration manager
-  AddRAMParameter(paramKey,
-                    "Available RAM (Mb)",
-                  otb::ConfigurationManager::GetMaxRAMHint());
+  AddRAMParameter(paramKey, "Available RAM (MB)", otb::ConfigurationManager::GetMaxRAMHint());
   MandatoryOff(paramKey);
-  SetParameterDescription(paramKey, "Available memory for processing (in MB)");
+  SetParameterDescription(paramKey, "Available memory for processing (in MB).");
 }
 
 void Application::AddRANDParameter(std::string paramKey, std::string paramName, unsigned int defaultValue)
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
index 11f0e6b482a69896a0d132edb64bcc808c49576f..2ff2458f37c4310f3b37d725e21cc5c603dea35f 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
@@ -23,7 +23,6 @@
 #include "otbWrapperChoiceParameter.h"
 #include "otbWrapperListViewParameter.h"
 #include "otbWrapperDirectoryParameter.h"
-#include "otbWrapperEmptyParameter.h"
 #include "otbWrapperInputFilenameParameter.h"
 #include "otbWrapperInputFilenameListParameter.h"
 #include "otbWrapperOutputFilenameParameter.h"
@@ -48,8 +47,8 @@ namespace Wrapper
 InputProcessXMLParameter::InputProcessXMLParameter()
 {
   this->SetKey("inxml");
-  this->SetName("Load otb application from xml file");
-  this->SetDescription("Load otb application from xml file");
+  this->SetName("Load parameters from XML");
+  this->SetDescription("Load application parameters from an XML file.");
   this->SetMandatory(false);
   this->SetActive(false);
   this->SetRole(Role_Input);
@@ -419,15 +418,6 @@ InputProcessXMLParameter::Read(Application::Pointer this_)
       std::stringstream(value) >> floatValue;
       this_->SetParameterFloat(key, floatValue);
       }
-    else if (type == ParameterType_Empty)
-      {
-      bool emptyValue = false;
-      if( value == "true")
-	{
-	emptyValue = true;
-	}
-      this_->SetParameterEmpty(key, emptyValue);
-      }
     else if (type == ParameterType_StringList || type == ParameterType_ListView)
       {
       if(values.empty())
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx
index 22791595c01061f957b2d64d9f7d17c52a7e58a2..d3505f33ae7fd33da5509ca263f6b70c37483692 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputProcessXMLParameter.cxx
@@ -23,7 +23,6 @@
 #include "otbWrapperChoiceParameter.h"
 #include "otbWrapperListViewParameter.h"
 #include "otbWrapperDirectoryParameter.h"
-#include "otbWrapperEmptyParameter.h"
 #include "otbWrapperInputFilenameParameter.h"
 #include "otbWrapperInputFilenameListParameter.h"
 #include "otbWrapperOutputFilenameParameter.h"
@@ -49,8 +48,8 @@ OutputProcessXMLParameter::OutputProcessXMLParameter()
   , m_Appli()
 {
   this->SetKey("outxml");
-  this->SetName("Save otb application to xml file");
-  this->SetDescription("Save otb application to xml file");
+  this->SetName("Save parameters to XML");
+  this->SetDescription("Save application parameters to an XML file.");
   this->SetMandatory(false);
   this->SetActive(false);
   this->SetRole(Role_Output);
@@ -243,26 +242,6 @@ OutputProcessXMLParameter::ParseGroup(const std::string& group)
            paramExists = false;
          }
 
-       std::string emptyValue;
-       if (type == ParameterType_Empty)
-         {
-           EmptyParameter* eParam = dynamic_cast<EmptyParameter *> (param);
-
-           if(eParam!=nullptr)
-             {
-             //Don't use m_Appli->HasUserValue which returns false always because of
-             //EmptyParameter::HasValue() is false for EmptyParameter
-             if(eParam->HasUserValue())
-               {
-               paramExists = true;
-               emptyValue = "false";
-               if( eParam->GetActive() )
-                 {
-                 emptyValue = "true";
-                 }
-               }
-             }
-         }
         if(type  == ParameterType_RAM)
         {
           paramExists = true;
@@ -317,11 +296,6 @@ OutputProcessXMLParameter::ParseGroup(const std::string& group)
            strm << m_Appli->GetParameterInt("rand");
            value = strm.str();
            }
-         else if (typeAsString == "Empty")
-           {
-           //Nothing to do. copy emptyValue
-           value = emptyValue;
-           }
          else if (type == ParameterType_InputProcessXML)
            {
              continue;
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx
index 55095184e530bdf6d69d63f5c3f414f5e5b962bb..160c92b2d3e26f34d4e41510d8572a0943bf5682 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterGroup.cxx
@@ -21,7 +21,6 @@
 #include "otbWrapperChoiceParameter.h"
 #include "otbWrapperListViewParameter.h"
 #include "otbWrapperDirectoryParameter.h"
-#include "otbWrapperEmptyParameter.h"
 #include "otbWrapperInputFilenameParameter.h"
 #include "otbWrapperInputFilenameListParameter.h"
 #include "otbWrapperOutputFilenameParameter.h"
@@ -249,10 +248,6 @@ ParameterGroup::GetSelectedItems(std::string paramKey)
      {
      return ParameterType_Radius;
      }
-   else if (type == "Empty")
-     {
-     return ParameterType_Empty;
-     }
    else if (type == "Int")
      {
      return ParameterType_Int;
@@ -339,8 +334,8 @@ ParameterGroup::GetSelectedItems(std::string paramKey)
      }
    else
      {
-     std::cerr << "Cannot find parameter type code for type: " << type <<  std::endl;
-     return ParameterType_Empty;
+         otbLogMacro(Error, << "Cannot find parameter type code for type: " << type);
+         throw std::invalid_argument("Cannot find parameter type code for type: " + type);
      }
 }
 
@@ -351,11 +346,6 @@ std::string ParameterGroup::GetParameterTypeAsString(ParameterType type)
 
   switch (type)
     {
-    case ParameterType_Empty:
-    {
-    paramType = "Empty";
-    }
-    break;
     case ParameterType_Int:
     {
     paramType = "Int";
@@ -515,11 +505,6 @@ ParameterGroup::AddParameter(ParameterType type, std::string paramKey, std::stri
     Parameter::Pointer newParam;
     switch (type)
       {
-      case ParameterType_Empty:
-        {
-        newParam = EmptyParameter::New();
-        }
-        break;
       case ParameterType_Int:
         {
         newParam = IntParameter::New();
diff --git a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
index f3c7c4d5deaf754f2b734b0d625198a5dfcc7bbb..08a53d004f1d1e6f2f238fd16dc15d1ad1dcc57f 100644
--- a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
+++ b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
@@ -23,7 +23,6 @@
 // Single value parameter
 #include "otbWrapperChoiceParameter.h"
 #include "otbWrapperDirectoryParameter.h"
-#include "otbWrapperEmptyParameter.h"
 #include "otbWrapperInputFilenameParameter.h"
 #include "otbWrapperOutputFilenameParameter.h"
 #include "otbWrapperInputImageParameter.h"
@@ -496,26 +495,6 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters()
               }
             }
           }
-        else if (type == ParameterType_Empty)
-          {
-          // Set UserValue flag specific for EmptyParameter, beware that it
-          // should be done before Enable/Disable because SetParameterUserValue()
-          // may enable it by default
-          m_Application->SetParameterUserValue(paramKey,true);
-          if (values[0] == "1" || values[0] == "true")
-            {
-            m_Application->EnableParameter(paramKey);
-            }
-          else if (values[0] == "0" || values[0] == "false")
-            {
-            m_Application->DisableParameter(paramKey);
-            }
-          else
-            {
-            std::cerr << "ERROR: Wrong value for parameter -" << paramKey << "." << std::endl;
-            return WRONGPARAMETERVALUE;
-            }
-          }
         // Call the DoUpdateParameter to update dependent params
         m_Application->UpdateParameters();
         }
@@ -755,7 +734,7 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer &
     {
     oss << "<int32>         ";
     }
-  else if (type == ParameterType_Empty || type == ParameterType_Bool)
+  else if (type == ParameterType_Bool)
     {
     oss << "<boolean>       ";
     }
diff --git a/Modules/Wrappers/QGIS/src/otbQgisDescriptor.cxx b/Modules/Wrappers/QGIS/src/otbQgisDescriptor.cxx
index 40c6906ebd573869bff5b03878d9c96c3d2a934f..84d226b382b8990fc5575f8022c6fcccf45683ff 100644
--- a/Modules/Wrappers/QGIS/src/otbQgisDescriptor.cxx
+++ b/Modules/Wrappers/QGIS/src/otbQgisDescriptor.cxx
@@ -54,7 +54,6 @@ int main(int argc, char* argv[])
   assert(!group.empty());
 
   std::map<ParameterType, std::string> parameterTypeToString;
-  parameterTypeToString[ParameterType_Empty] = "QgsProcessingParameterBoolean";
   parameterTypeToString[ParameterType_Bool] = "QgsProcessingParameterBoolean";
   parameterTypeToString[ParameterType_Int] = "QgsProcessingParameterNumber";
   parameterTypeToString[ParameterType_Float] = "QgsProcessingParameterNumber";
@@ -272,10 +271,6 @@ int main(int argc, char* argv[])
       {
       default_value = appli->GetParameterAsString(name);
       }
-    else if(type == ParameterType_Empty)
-      {
-      default_value = appli->IsParameterEnabled(name)?"true":"false";
-      }
     else if(type == ParameterType_Choice)
       {
       std::vector<std::string>  key_list  = appli->GetChoiceKeys(name);
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetEmptyParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetEmptyParameter.h
deleted file mode 100644
index 283caa397e60a11cd6827eb5201e59eae7425c2b..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetEmptyParameter.h
+++ /dev/null
@@ -1,59 +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.
- */
-
-#ifndef otbWrapperQtWidgetEmptyParameter_h
-#define otbWrapperQtWidgetEmptyParameter_h
-
-#include <QtWidgets>
-#include "otbWrapperEmptyParameter.h"
-#include "otbWrapperQtWidgetParameterBase.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-
-/** \class QtWidgetEmptyParameter
- * \brief
- *
- * \ingroup OTBQtWidget
- */
-class OTBQtWidget_EXPORT QtWidgetEmptyParameter : public QtWidgetParameterBase
-{
-  Q_OBJECT
-
-public:
-  QtWidgetEmptyParameter(EmptyParameter*, QtWidgetModel*, QWidget*);
-  ~QtWidgetEmptyParameter() override;
-
-private:
-  QtWidgetEmptyParameter(const QtWidgetEmptyParameter&) = delete;
-  void operator=(const QtWidgetEmptyParameter&) = delete;
-
-  void DoCreateWidget() override;
-
-  void DoUpdateGUI() override;
-};
-
-
-}
-}
-
-#endif
diff --git a/Modules/Wrappers/QtWidget/src/CMakeLists.txt b/Modules/Wrappers/QtWidget/src/CMakeLists.txt
index ac5497170b64200fa3034a00b6456cfe695f39a0..e8bab3c0869e2764e5318c32e4fb93091ee56c7a 100644
--- a/Modules/Wrappers/QtWidget/src/CMakeLists.txt
+++ b/Modules/Wrappers/QtWidget/src/CMakeLists.txt
@@ -50,7 +50,6 @@ set(OTBQtWidget_SRC
   otbWrapperQtWidgetParameterBase.cxx
   otbWrapperQtWidgetInputImageParameter.cxx
   otbWrapperQtWidgetStringListParameter.cxx
-  otbWrapperQtWidgetEmptyParameter.cxx
   otbWrapperQtWidgetOutputVectorDataParameter.cxx
   otbWrapperQtWidgetInputFilenameParameter.cxx
   otbWrapperQtWidgetInputImageListParameter.cxx
@@ -62,7 +61,6 @@ set(OTBQtWidget_SRC
   )
 
 set(OTBQtWidget_MOC_HDR
-  ../include/otbWrapperQtWidgetEmptyParameter.h
   ../include/otbWrapperQtWidgetFloatParameter.h
   ../include/otbWrapperQtWidgetIntParameter.h
   ../include/otbWrapperQtWidgetStringParameter.h
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetEmptyParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetEmptyParameter.cxx
deleted file mode 100644
index fc64f91581e550efc1ac1d7ce6a94a2bac1f736b..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetEmptyParameter.cxx
+++ /dev/null
@@ -1,60 +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 "otbWrapperQtWidgetEmptyParameter.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-
-QtWidgetEmptyParameter::QtWidgetEmptyParameter(EmptyParameter* emptyParam, QtWidgetModel* m, QWidget * parent)
-  : QtWidgetParameterBase(emptyParam, m, parent)
-{
-}
-
-QtWidgetEmptyParameter::~QtWidgetEmptyParameter()
-{
-}
-
-void QtWidgetEmptyParameter::DoUpdateGUI()
-{
-
-}
-
-void QtWidgetEmptyParameter::DoCreateWidget()
-{
-  // Set up input text edit
-  QHBoxLayout *hLayout = new QHBoxLayout;
-  hLayout->setSpacing(0);
-  hLayout->setContentsMargins(0, 0, 0, 0);
-
-  //QCheckBox* checkbox = new QCheckBox(this);
-  //checkbox->setToolTip(emptyParam->GetDescription());
-
-  //QString optionID(emptyParam->GetName());
-  //hLayout->addWidget(checkbox);
-  hLayout->addStretch();
-
-  this->setLayout(hLayout);
-}
-
-}
-}
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx
index 4454532169996dc23e68da7389847107e5fbc2ac..2d16d8e249c06605cd6a6ba14cd6d6ed4b480cf9 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx
@@ -83,18 +83,9 @@ QtWidgetModel* QtWidgetParameterBase::GetModel()
 // current widget
 void QtWidgetParameterBase::SetActivationState( bool value )
 {
-  //filter out EmptyParameter
-  if(strcmp(m_Param->GetNameOfClass(), "EmptyParameter") == 0)
-    {
-    //only set user value if there is a change
-    if(value != m_Param->GetActive())
-      m_Param->SetUserValue(true);
-    }
-
   this->setEnabled(value);
   this->SetChecked(value);
   m_Param->SetActive(value);
-
 }
 
 const Parameter *
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx
index ea8f07d950305d34f3747f9fcceb3b25f4a5e3bd..a19a6cfa2341f8fd2c1de5565c6d5b3659c8621f 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx
@@ -29,7 +29,6 @@
 #include "otbWrapperQtWidgetComplexInputImageParameter.h"
 #include "otbWrapperQtWidgetComplexOutputImageParameter.h"
 #include "otbWrapperQtWidgetDirectoryParameter.h"
-#include "otbWrapperQtWidgetEmptyParameter.h"
 #include "otbWrapperQtWidgetFloatParameter.h"
 #include "otbWrapperQtWidgetIntParameter.h"
 #include "otbWrapperQtWidgetInputFilenameParameter.h"
@@ -105,7 +104,6 @@ QtWidgetParameterFactory::CreateQtWidget( Parameter* param, QtWidgetModel* model
     }
 
   if (0) {}
-  CREATEWIDGET(EmptyParameter,          QtWidgetEmptyParameter)
   CREATEWIDGET(IntParameter,            QtWidgetIntParameter)
   CREATEWIDGET(FloatParameter,          QtWidgetFloatParameter)
   CREATEWIDGET(InputFilenameParameter,       QtWidgetInputFilenameParameter)
diff --git a/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetParameterFactory.cxx b/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetParameterFactory.cxx
index 98ba334c35844289666556ef439575eaa8b72137..1394cf5c0d304bb9a05dc720cd6c09576e76a5b2 100644
--- a/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetParameterFactory.cxx
+++ b/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetParameterFactory.cxx
@@ -24,7 +24,6 @@
 
 #include "otbWrapperQtWidgetParameterFactory.h"
 #include "otbWrapperStringParameter.h"
-#include "otbWrapperEmptyParameter.h"
 #include "otbWrapperChoiceParameter.h"
 #include "otbWrapperQtWidgetModel.h"
 
@@ -84,7 +83,6 @@ int otbWrapperQtWidgetParameterFactory(int argc, char* argv[])
 
   otb::Wrapper::IntParameter::Pointer   intParam = otb::Wrapper::IntParameter::New();
   otb::Wrapper::FloatParameter::Pointer floatParam = otb::Wrapper::FloatParameter::New();
-  otb::Wrapper::EmptyParameter::Pointer emptyParam = otb::Wrapper::EmptyParameter::New();
   otb::Wrapper::ChoiceParameter::Pointer choiceParam = otb::Wrapper::ChoiceParameter::New();
 
   intParam->SetName("Int parameter");
@@ -103,10 +101,6 @@ int otbWrapperQtWidgetParameterFactory(int argc, char* argv[])
   floatParam->SetMinimumValue(-3.75);
   floatParam->SetMaximumValue(4.97);
 
-  emptyParam->SetName("Empty parameter");
-  emptyParam->SetDescription("This is an empty parameter");
-  emptyParam->SetKey("empty");
-
   choiceParam->SetName("Choice parameter");
   choiceParam->SetDescription("This is a choice parameter");
   choiceParam->SetKey("choice");
@@ -116,14 +110,12 @@ int otbWrapperQtWidgetParameterFactory(int argc, char* argv[])
 
   QWidget * intWidget   = factory->CreateQtWidget(intParam, model, nullptr);
   QWidget * floatWidget = factory->CreateQtWidget(floatParam, model, nullptr);
-  QWidget * emptyWidget = factory->CreateQtWidget(emptyParam, model, nullptr);
   QWidget * choiceWidget = factory->CreateQtWidget(choiceParam, model, nullptr);
 
   if(intWidget)
     {
     intWidget->show();
     floatWidget->show();
-    emptyWidget->show();
     choiceWidget->show();
 
     //return app.exec();
@@ -146,7 +138,6 @@ int otbWrapperQtWidgetParameterGroup(int argc, char* argv[])
 
   otb::Wrapper::IntParameter::Pointer   intParam = otb::Wrapper::IntParameter::New();
   otb::Wrapper::FloatParameter::Pointer floatParam = otb::Wrapper::FloatParameter::New();
-  otb::Wrapper::EmptyParameter::Pointer emptyParam = otb::Wrapper::EmptyParameter::New();
   otb::Wrapper::ChoiceParameter::Pointer choiceParam = otb::Wrapper::ChoiceParameter::New();
   otb::Wrapper::StringParameter::Pointer stringParam = otb::Wrapper::StringParameter::New();
 
@@ -166,10 +157,6 @@ int otbWrapperQtWidgetParameterGroup(int argc, char* argv[])
   floatParam->SetMinimumValue(-3.75);
   floatParam->SetMaximumValue(4.97);
 
-  emptyParam->SetName("Empty parameter");
-  emptyParam->SetDescription("This is an empty parameter");
-  emptyParam->SetKey("empty");
-
   choiceParam->SetName("Choice parameter");
   choiceParam->SetDescription("This is an choice parameter");
   choiceParam->SetKey("choice");
@@ -185,13 +172,11 @@ int otbWrapperQtWidgetParameterGroup(int argc, char* argv[])
   otb::Wrapper::ParameterGroup::Pointer list = otb::Wrapper::ParameterGroup::New();
   list->AddParameter(otb::Wrapper::Parameter::Pointer(intParam.GetPointer()));
   list->AddParameter(otb::Wrapper::Parameter::Pointer(floatParam.GetPointer()));
-  list->AddParameter(otb::Wrapper::Parameter::Pointer(emptyParam.GetPointer()));
   list->AddParameter(otb::Wrapper::Parameter::Pointer(choiceParam.GetPointer()));
   list->AddParameter(otb::Wrapper::Parameter::Pointer(stringParam.GetPointer()));
 
   otb::Wrapper::IntParameter::Pointer   intParam2 = otb::Wrapper::IntParameter::New();
   otb::Wrapper::FloatParameter::Pointer floatParam2 = otb::Wrapper::FloatParameter::New();
-  otb::Wrapper::EmptyParameter::Pointer emptyParam2 = otb::Wrapper::EmptyParameter::New();
   otb::Wrapper::ChoiceParameter::Pointer choiceParam2 = otb::Wrapper::ChoiceParameter::New();
   otb::Wrapper::StringParameter::Pointer stringParam2 = otb::Wrapper::StringParameter::New();
   intParam2->SetName("Int parameter");
@@ -210,10 +195,6 @@ int otbWrapperQtWidgetParameterGroup(int argc, char* argv[])
   floatParam2->SetMinimumValue(-3.75);
   floatParam2->SetMaximumValue(4.97);
 
-  emptyParam2->SetName("Empty parameter");
-  emptyParam2->SetDescription("This is an empty parameter");
-  emptyParam2->SetKey("empty2");
-
   choiceParam2->SetName("Choice parameter");
   choiceParam2->SetDescription("This is an choice parameter");
   choiceParam2->SetKey("choice2");
@@ -233,7 +214,6 @@ int otbWrapperQtWidgetParameterGroup(int argc, char* argv[])
 
   group2->AddParameter(otb::Wrapper::Parameter::Pointer(intParam2.GetPointer()));
   group2->AddParameter(otb::Wrapper::Parameter::Pointer(floatParam2.GetPointer()));
-  group2->AddParameter(otb::Wrapper::Parameter::Pointer(emptyParam2.GetPointer()));
   group2->AddParameter(otb::Wrapper::Parameter::Pointer(choiceParam2.GetPointer()));
   group2->AddParameter(otb::Wrapper::Parameter::Pointer(stringParam2.GetPointer()));
   group2->AddParameter(otb::Wrapper::Parameter::Pointer(list.GetPointer()));
diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i
index 50ab3e24aced3994827c4a508abe1065eaf0d1e2..2901fd8ed6f8f90b77d8b75a87efaeaa9175da2b 100644
--- a/Modules/Wrappers/SWIG/src/otbApplication.i
+++ b/Modules/Wrappers/SWIG/src/otbApplication.i
@@ -79,7 +79,6 @@ namespace Wrapper
 
   typedef enum
   {
-    ParameterType_Empty,
     ParameterType_Int,
     ParameterType_Float,
     ParameterType_String,
@@ -247,7 +246,6 @@ public:
   void SetParameterFloat(std::string parameter, float value, bool hasUserValueFlag = true);
   void SetParameterString(std::string parameter, std::string value, bool hasUserValueFlag = true);
   void SetParameterStringList(std::string parameter, std::vector<std::string> values, bool hasUserValueFlag = true);
-  void SetParameterEmpty(std::string parameter, bool value, bool hasUserValueFlag = true);
 
   void SetParameterOutputImagePixelType(std::string parameter, otb::Wrapper::ImagePixelType pixelType);
   void SetParameterComplexOutputImagePixelType(std::string parameter, otb::Wrapper::ComplexImagePixelType cpixelType);
@@ -581,7 +579,6 @@ class ApplicationProxy(object):
 				ParameterType_Radius : 'ParameterType_Radius',
 				ParameterType_RAM : 'ParameterType_RAM',
 				ParameterType_Float : 'ParameterType_Float',
-				ParameterType_Empty : 'ParameterType_Empty',
 				ParameterType_Choice : 'ParameterType_Choice',
 				ParameterType_Group : 'ParameterType_Group',
 				ParameterType_Bool : 'ParameterType_Bool'
@@ -614,8 +611,6 @@ class ApplicationProxy(object):
 			  return self.SetParameterInt(paramKey, value)
 			elif paramType in [ParameterType_Float]:
 			  return self.SetParameterFloat(paramKey, value)
-			elif paramType in [ParameterType_Empty]:
-			  return self.EnableParameter(paramKey)
 			elif paramType in [ParameterType_Bool]:
 			  return self.SetParameterString(paramKey, str(value) )
 			elif paramType in [ParameterType_Group]:
@@ -650,8 +645,6 @@ class ApplicationProxy(object):
 			  return self.GetParameterInt(paramKey)
 			elif paramType in [ParameterType_Float]:
 			  return self.GetParameterFloat(paramKey)
-			elif paramType in [ParameterType_Empty]:
-			  return self.IsParameterEnabled(paramKey)
 			elif paramType in [ParameterType_Bool]:
 			  return bool(self.GetParameterInt(paramKey))
 			elif paramType in [ParameterType_Group, ParameterType_Choice]:
diff --git a/Modules/Wrappers/SWIG/test/python/Bug440.py b/Modules/Wrappers/SWIG/test/python/Bug440.py
deleted file mode 100644
index 3631d406dcde410e606a570b7f8bfdd9ada9c9e4..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/SWIG/test/python/Bug440.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# 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.
-#
-
-# Import the otb applications package
-
-import sys
-def test(otbApplication, argv):
-	# The following line creates an instance of the Convert application
-	Convert = otbApplication.Registry.CreateApplication("Convert")
-
-	# The following lines set all the application parameters:
-	Convert.SetParameterString("in", argv[1])
-
-	Convert.SetParameterString("out", argv[2])
-
-	Convert.SetParameterString("type","linear")
-
-	# The following line execute the application
-	sys.exit(Convert.ExecuteAndWriteOutput())
diff --git a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
index edbef92fe8ac7a2267ec0c395a84809b3151c16f..b53d14e63fa8de65baad4efd15219dd4ddf3ed21 100644
--- a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
@@ -53,14 +53,6 @@ add_test( NAME pyTvHyperspectralUnmixingUCLS
   ucls
   )
 
-add_test( NAME pyTvBug440
-  COMMAND ${TEST_DRIVER} Execute
-  ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonTestDriver.py
-  Bug440
-  ${OTB_DATA_ROOT}/Input/scene.png
-  ${TEMP}/pyTvBug440Output.tif
-  )
-
 add_test( NAME pyTvBug804
   COMMAND ${TEST_DRIVER} Execute
   ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonTestDriver.py
diff --git a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
index c6cb4f3c4bad06845c8a3e9449f83174cbe35aca..3bf5def520515a7b64b6ab565ad1b6e89ef6eaa5 100644
--- a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
+++ b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
@@ -31,7 +31,6 @@ def test(otb, argv):
 	# test GetParameterTypeAsString() method in python.
 	print( app.GetParameterTypeAsString(otb.ParameterType_InputImage) )
 	print( app.GetParameterTypeAsString(otb.ParameterType_String) )
-	print( app.GetParameterTypeAsString(otb.ParameterType_Empty) )
 
 	# one test for each parameter type (string, float, int, ...)
 
diff --git a/Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py b/Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py
index fd0e1ad4b361bb314ef02e71757a9a4f6ca21a87..85814eef2a468d648352af4e89a452551f46586e 100644
--- a/Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py
+++ b/Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py
@@ -65,16 +65,16 @@ def test(otbApplication, argv):
 	RescaleOut = Rescale.GetVectorImageAsNumpyArray("out", 'float')
 	# misc.imsave('RescaleOut.jpg', RescaleOut)
 
-	Convert = otbApplication.Registry.CreateApplication("Convert")
-	# take numpy output from Rescale application and feed into Convert
-	Convert.SetVectorImageFromNumpyArray("in", RescaleOut)
-	Convert.SetParameterString("out", "ConvertOut.png")
-	Convert.ExecuteAndWriteOutput()
-	ConvertOut = Convert.GetVectorImageAsNumpyArray("out", 'float')
+	DynamicConvert = otbApplication.Registry.CreateApplication("DynamicConvert")
+	# take numpy output from Rescale application and feed into DynamicConvert
+	DynamicConvert.SetVectorImageFromNumpyArray("in", RescaleOut)
+	DynamicConvert.SetParameterString("out", "ConvertOut.png")
+	DynamicConvert.ExecuteAndWriteOutput()
+	DynamicConvertOut = DynamicConvert.GetVectorImageAsNumpyArray("out", 'float')
 
 	Smoothing = otbApplication.Registry.CreateApplication("Smoothing")
 	# take numpy output from Convert application and feed into Smoothing
-	Smoothing.SetVectorImageFromNumpyArray("in", ConvertOut)
+	Smoothing.SetVectorImageFromNumpyArray("in", DynamicConvertOut)
 	Smoothing.SetParameterString("type", 'anidif')
 	Smoothing.SetParameterString("out", outFile)
 	Smoothing.ExecuteAndWriteOutput()
diff --git a/Modules/Wrappers/SWIG/test/python/PythonRescaleTest.py b/Modules/Wrappers/SWIG/test/python/PythonRescaleTest.py
index 878d2e5113b329ab5749f7fed1b15a2330cd142e..812aec1fac05c6e9985a916dd4a5b457b4435288 100644
--- a/Modules/Wrappers/SWIG/test/python/PythonRescaleTest.py
+++ b/Modules/Wrappers/SWIG/test/python/PythonRescaleTest.py
@@ -23,6 +23,9 @@
 
 #
 #  Example on the use of the Rescale
+#  This test checks that the Python wrapping works correctly. For instance, it 
+#  ensures that Init() is called on the Swig/Python interface (see bug #440, 
+#  https://bugs.orfeo-toolbox.org//view.php?id=440)
 #
 def test(otb, argv):
 	app = otb.Registry.CreateApplication("Rescale")
diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt
index 5a3e78257680e4bd19f5b721154dd25f5387f0d5..9e72344d39c0c893f497dc02014010a538ba4b67 100644
--- a/SuperBuild/CMakeLists.txt
+++ b/SuperBuild/CMakeLists.txt
@@ -55,7 +55,7 @@ option(BUILD_STATIC_LIBS "Build with static libraries." OFF)
 option(BUILD_ALWAYS "Always build or install OTB." ON)
 option(WITH_REMOTE_MODULES "Build with specific list of remote modules." OFF)
 option(OTB_USE_OPENMP "use openmp" OFF)
-set(OTB_ADDITIONAL_CACHE "" CACHE STRING "Additional cmake option for OTB -DVAR:TYPE=VALUE ...")
+set(OTB_ADDITIONAL_CACHE "" CACHE STRING "Additional cmake options for OTB with the syntax (semi-colon used as a separator): -D<var>:<type>=<value>;-D<var>:<type>=<value>")
 
 if(APPLE)
   if(POLICY CMP0042)