diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b121e4705503288d49003e5c52809b16d5ab2aee..14447a38dc8eacbe4120bcdc5930ad6f491e124f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -22,6 +22,8 @@ stages:
   - precheck
   - prepare
   - build
+  - report
+  - deploy
 
 .general:
   retry:
@@ -30,55 +32,49 @@ stages:
       - runner_system_failure
       - stuck_or_timeout_failure
 
-fast-build:
+.common:
   extends: .general
-  only: [merge_requests, branches]
-  stage: precheck
-  image: $BUILD_IMAGE_REGISTRY/otb-ubuntu-native-develop:latest
   before_script:
-    - git checkout -f -q $CI_COMMIT_SHA
-    - python3 CI/check_twin_pipelines.py
-  after_script:
-    - python3 CI/cdash_handler.py
-  script:
-    - ctest -V -S CI/main_ci.cmake -DIMAGE_NAME:string=ubuntu-18.04-fast
-    - ccache -s
-
-
-.common-build:
-  extends: .general
-  only: [merge_requests]
-  stage: build
-  before_script:
-    - git lfs install --skip-repo
     # Provision efficiently the local LFS cache before checkout
     - git lfs fetch origin $CI_COMMIT_SHA
-    # Checkout the expected branch
     - git checkout -f -q $CI_COMMIT_SHA
   after_script:
-    - python3 CI/cdash_handler.py
-  # artifacts:
-    # when: on_failure
-    # expire_in: 24 hrs
-    # paths:
-      # - build/*/*.log #CMake log
-      # - log/*.txt # Others
+    - python3 -u CI/cdash_handler.py
 
-debian-build:
-  extends: .common-build
-  image: $BUILD_IMAGE_REGISTRY/otb-debian-native:unstable
-  script:
-    - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -V -S CI/main_ci.cmake -DIMAGE_NAME:string=debian-unstable-gcc
+.common-build:
+  extends: .common
+  only:
+    - merge_requests
+    - develop
+    - /^release-[0-9]+\.[0-9]+$/
+  stage: build
+  artifacts:
+    when: always
+    expire_in: 24 hrs
+    paths:
+      - build/*/*.log #CMake log
+      - log/*.txt # Others
+      - build/CookBook-*-html.tar.gz
+      - build/Documentation/Cookbook/latex/CookBook-*.pdf
+      - build/Documentation/Doxygen/OTB-Doxygen-*.tar.bz2
+      - build_packages/OTB-*.run
+      - build_packages/OTB-*.zip
+      - build/compile_commands.json
+      - build/ctest_report.xml
+      - build/cppcheck_report.xml
+      - build/coverage_report.xml
 
 .common-prepare:
   extends: .general
-  only: [merge_requests]
+  only:
+    - merge_requests
+    - develop
+    - /^release-[0-9]+\.[0-9]+$/
   stage: prepare
   before_script:
+    - export GIT_LFS_SKIP_SMUDGE=1
     - git checkout -f -q $CI_COMMIT_SHA
-    - git lfs install --skip-repo
-    - git config --global user.email "otbbot@orfeo-toolbox.org"
-    - git config --global user.name "otbbot"
+    - export GIT_LFS_SKIP_SMUDGE=0
   artifacts:
     expire_in: 24 hrs
     when: always
@@ -86,65 +82,247 @@ debian-build:
       - sb_branch.txt # Needed to checkout correct branch in build step
       - build/*/*/*/*.log # Superbuild log
 
+#-------------------------- precheck job ---------------------------------------
+fast-build:
+  extends: .common
+  only: [merge_requests, branches]
+  stage: precheck
+  image: $BUILD_IMAGE_REGISTRY/otb-ubuntu-native-develop:latest
+  before_script:
+    - export GIT_LFS_SKIP_SMUDGE=1
+    - git checkout -f -q $CI_COMMIT_SHA
+    - python3 CI/check_twin_pipelines.py
+  script:
+    - ctest -V -S CI/main_ci.cmake -DIMAGE_NAME:string=ubuntu-18.04-fast
+    - ccache -s
+
+#------------------------- prepare & build jobs --------------------------------
+debian-build:
+  extends: .common-build
+  image: $BUILD_IMAGE_REGISTRY/otb-debian-native:unstable
+  script:
+    - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -V -S CI/main_ci.cmake -DIMAGE_NAME:string=debian-unstable-gcc
+  dependencies: []
+
 ## Ubuntu superbuild
-ubuntu-superbuild-prepare:
+ubuntu-xdk-prepare:
   extends: .common-prepare
   image: $BUILD_IMAGE_REGISTRY/otb-ubuntu-superbuild-base:18.04
   script:
     - ctest -VV -S CI/prepare_superbuild.cmake -DIMAGE_NAME:string=otb-ubuntu-superbuild-base
 
-ubuntu-superbuild-build:
+ubuntu-xdk-build:
   extends: .common-build
   image: $BUILD_IMAGE_REGISTRY/otb-ubuntu-superbuild-base:18.04
   script:
     - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -V -S CI/main_superbuild.cmake -DIMAGE_NAME:string=ubuntu-18.04-llvm-xdk
-    - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -VV -S CI/main_packages.cmake -DIMAGE_NAME:string=otb-ubuntu-superbuild-base
+    - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -V -S CI/main_packages.cmake -DIMAGE_NAME:string=otb-ubuntu-superbuild-base -DNAME_SUFFIX:string=-glibc-2.27
   dependencies:
-    - ubuntu-superbuild-prepare
-  artifacts:
-    paths:
-      - build/CookBook-*-html.tar.gz
-      - build/Documentation/Cookbook/latex/CookBook-*.pdf
-      - build/Documentation/Doxygen/OTB-Doxygen-*.tar.bz2
-      - build/share/otb
+    - ubuntu-xdk-prepare
 
 ## CentOS superbuild
-centos-superbuild-prepare:
+centos-xdk-prepare:
   extends: .common-prepare
   image: $BUILD_IMAGE_REGISTRY/otb-centos-superbuild-base:6.6
   script:
     - ctest -VV -S CI/prepare_superbuild.cmake -DIMAGE_NAME:string=otb-centos-superbuild-base
 
-centos-superbuild-build:
+centos-xdk-build:
   extends: .common-build
   image: $BUILD_IMAGE_REGISTRY/otb-centos-superbuild-base:6.6
   script:
     - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -V -S CI/main_superbuild.cmake -DIMAGE_NAME:string=otb-centos-superbuild-base
-    - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -VV -S CI/main_packages.cmake -DIMAGE_NAME:string=otb-centos-superbuild-base
+    - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96" ctest -V -S CI/main_packages.cmake -DIMAGE_NAME:string=otb-centos-superbuild-base
   dependencies:
-    - centos-superbuild-prepare
+    - centos-xdk-prepare
 
 ## MacOS superbuild
-macos-superbuild-prepare:
+macos-xdk-prepare:
+  extends: .common-prepare
   tags:
     - macos
-  extends: .common-prepare
-  before_script:
-    # No need to install lfs as this machine is persistent
-    # No need to do git config
-    # Checkout the expected branch
-    - export GIT_LFS_SKIP_SMUDGE=1
-    - git checkout -f -q $CI_COMMIT_SHA
-    - export GIT_LFS_SKIP_SMUDGE=0
   script:
     - ctest -VV -S CI/prepare_superbuild.cmake -DIMAGE_NAME:string=otb-macos-superbuild
 
-macos-superbuild-build:
+macos-xdk-build:
   tags:
     - macos
   extends: .common-build
   script:
     - ctest -V -S CI/main_superbuild.cmake -DIMAGE_NAME:string=otb-macos-superbuild
-    - ctest -VV -S CI/main_packages.cmake -DIMAGE_NAME:string=otb-macos-superbuild
+    - ctest -V -S CI/main_packages.cmake -DIMAGE_NAME:string=otb-macos-superbuild
+  dependencies:
+    - macos-xdk-prepare
+
+## Windows
+.windows-prepare:
+  extends: .common-prepare
+  before_script:
+# This override the previous before_script
+    - set GIT_LFS_SKIP_SMUDGE=1
+    - git checkout -f -q %CI_COMMIT_SHA%
+    - set GIT_LFS_SKIP_SMUDGE=0
+
+.windows-build:
+  extends: .common-build
+  before_script:
+    - git lfs fetch origin %CI_COMMIT_SHA%
+    - git checkout -f -q %CI_COMMIT_SHA%
+
+# - Win10
+windows-10-prepare:
+  extends: .windows-prepare
+  tags:
+    - windows10
+  script:
+    - call ./CI/dev_env.bat x64 xdk 10
+    - clcache.exe -s
+    - ctest -C Release -V -S CI/prepare_superbuild.cmake
+    - clcache.exe -s
+
+windows-10-build:
+  extends: .windows-build
+  tags:
+    - windows10
+  script:
+    - call ./CI/dev_env.bat x64 otb 10
+    - clcache.exe -s
+    - ctest -V -S CI/main_superbuild.cmake
+    - clcache.exe -s
+    - ctest -V -S CI/main_packages.cmake
+  dependencies:
+    - windows-10-prepare
+
+# - Win8.1
+windows-8-prepare:
+  extends: .windows-prepare
+  tags:
+    - windows8
+  script:
+    - call ./CI/dev_env.bat x86 xdk 8.1
+    - clcache.exe -s
+    - ctest -C Release -V -S CI/prepare_superbuild.cmake
+    - clcache.exe -s
+
+windows-8-build:
+  extends: .windows-build
+  tags:
+    - windows8
+  script:
+    - call ./CI/dev_env.bat x86 otb 8.1
+    - clcache.exe -s
+    - ctest -V -S CI/main_superbuild.cmake
+    - clcache.exe -s
+    - ctest -V -S CI/main_packages.cmake
+  dependencies:
+    - windows-8-prepare
+
+#------------------------- QA related jobs -------------------------------------
+ubuntu-xdk-qa-code-coverage:
+  extends: .common-build
+  only:
+    refs:
+      - merge_requests
+      - develop
+      - /^release-[0-9]+\.[0-9]+$/
+    variables:
+      - $SONAR_OTB_TOKEN
+  image: $BUILD_IMAGE_REGISTRY/otb-ubuntu-superbuild-qa:18.04
+  script:
+    - xvfb-run -a -n 1 -s "-screen 0 1024x768x24 -dpi 96"
+               ctest -V -S CI/main_qa.cmake
+                     -DIMAGE_NAME:string=ubuntu-18.04-llvm-qa
+                     -DQA:BOOL=ON
+    - ./CI/otb_coverage.sh
+    - saxon-xslt -o build/ctest_report.xml
+                 build/Testing/`head -n 1 build/Testing/TAG`/Test.xml
+                 CI/ctest2junit.xsl
+  dependencies:
+    - ubuntu-xdk-prepare
+
+ubuntu-xdk-qa-static-analysis:
+  extends: .common-build
+  only:
+    refs:
+      - merge_requests
+      - develop
+      - /^release-[0-9]+\.[0-9]+$/
+    variables:
+      - $SONAR_OTB_TOKEN
+  image: $BUILD_IMAGE_REGISTRY/otb-ubuntu-superbuild-qa:18.04
+  script:
+    - find Modules -type f -regextype posix-extended -regex '.*\.(h|hxx)$' -exec dirname '{}' \; |
+          grep -vE '^Modules/ThirdParty/' |
+          sort -u > header_directories
+    - cppcheck -j 8 -q --xml --xml-version=2 --enable=all
+               --language=c++ --std=c++14 --platform=unix64
+               --includes-file=header_directories
+               -i Modules/ThirdParty Modules
+               2> build/cppcheck_report.xml
+  after_script: []
+  dependencies:
+    - ubuntu-xdk-prepare
+
+ubuntu-xdk-report:
+  extends: .common
+  variables:
+    GIT_DEPTH: ""
+  image: $BUILD_IMAGE_REGISTRY/otb-ubuntu-superbuild-qa:18.04
+  stage: report
+  only:
+    refs:
+      - merge_requests
+      - develop
+      - /^release-[0-9]+\.[0-9]+$/
+    variables:
+      - $SONAR_OTB_TOKEN
+  script:
+    - sonar-scanner -Dproject.settings=sonar-project.properties
+                    -Dsonar.host.url=https://sonar.orfeo-toolbox.org
+                    -Dsonar.login=$SONAR_OTB_TOKEN
+                    `test -z "$CI_COMMIT_TAG" || echo "-Dsonar.projectVersion=$CI_COMMIT_TAG"`
+                    -Dsonar.branch.name=$CI_COMMIT_REF_NAME
+
+  after_script: []
   dependencies:
-    - macos-superbuild-prepare
+    - ubuntu-xdk-qa-code-coverage
+    - ubuntu-xdk-qa-static-analysis
+
+#---------------------------- Deploy job ---------------------------------------
+deploy:
+  tags:
+    - deploy
+  image: $BUILD_IMAGE_REGISTRY/otb-alpine:3.7
+  stage: deploy
+  extends: .general
+  only:
+    - develop@orfeotoolbox/otb
+    - /^release-[0-9]+\.[0-9]+$/@orfeotoolbox/otb
+  before_script:
+    # Provision efficiently the local LFS cache before checkout
+    - git lfs fetch origin $CI_COMMIT_SHA
+    - git checkout -f -q $CI_COMMIT_SHA
+  script:
+    - ./CI/deploy.sh $CI_COMMIT_REF_NAME $RC_NUMBER
+  dependencies:
+    - ubuntu-xdk-build
+    - centos-xdk-build
+    - macos-xdk-build
+    - windows-8-build
+    - windows-10-build
+
+release-container:
+  image: $BUILD_IMAGE_REGISTRY/otb-alpine:3.7
+  stage: deploy
+  extends: .general
+  only:
+    refs:
+      - tags@orfeotoolbox/otb
+    variables:
+      - $CI_COMMIT_TAG =~ /^[0-9]+\.[0-9]+\.[0-9]+$/
+  script:
+    - curl --request POST
+           --form token=$K8S_SECRET_RELEASE
+           --form ref=master
+           --form variables[OTB_TAG]=$CI_COMMIT_TAG
+           https://gitlab.orfeo-toolbox.org/api/v4/projects/126/trigger/pipeline
diff --git a/.gitlab/issue_templates/release.md b/.gitlab/issue_templates/release.md
index 58be911541e49b451630324563cd718ccd8f87db..5f7441d580c7c1a808d98f3cfe5fb16f0d790f45 100644
--- a/.gitlab/issue_templates/release.md
+++ b/.gitlab/issue_templates/release.md
@@ -36,7 +36,6 @@ Once all blocking issues are closed, and the previous steps are done:
     * [ ] Software Guide
     * [ ] Cookbook
     * [ ] Doxygen
-    * [ ] Application online documentation
     * [ ] WordPress page "Home" and "Download" pages
 * [ ] Upload OTB source archive to [Zenodo](https://zenodo.org/) to create a unique Digital Object Identifier (DOI)
 * [ ] Send email to mailing list to announce the release
diff --git a/CI/cdash_handler.py b/CI/cdash_handler.py
index aeb1aa9989c23f36d4d5d78baafcc8b34d636f04..6ac3c9fa44ba1feacd98ade062ca8f48c5426a7a 100644
--- a/CI/cdash_handler.py
+++ b/CI/cdash_handler.py
@@ -28,6 +28,7 @@ import unittest
 import sys
 import json
 import time
+import xml.etree.ElementTree as ET
 
 
 trace = False
@@ -42,11 +43,10 @@ def CheckEnvParameters(params):
       return False
   return True
 
+"""
+Handler class to retrieve build informations
+"""
 class Handler:
-# project
-# site
-# stamp
-# name
   def __init__ (self):
     self.build_dir = ""
     self.configure_path = ""
@@ -75,91 +75,39 @@ class Handler:
     if os.path.exists( configure_xml ):
       if trace:
         print ( configure_xml )
-        configure_file = open( configure_xml, "r" )
-        content = configure_file.read()
-        configure_file.close()
-        print( content )
       self.configure_path = configure_xml
       return self.configure_path
     print("Could not find the Configure.xml produced by ctest")
-    return
-
-  def GetSite (self , build_dir="" ):
-    """
-    Site is corresponding to the Name field in the xml.
-    """
-    if ( build_dir == ""):
-      build_dir = self.build_dir
-    if self.configure_path == "" and not self.GetConfigureFile( build_dir ):
-      print ("Error in GetSite function, could not find Configure.xml")
-      return
-    configure_file = open( self.configure_path, "r" )
-    content = configure_file.read()
-    configure_file.close()
-    site_regex = re.compile( "\\bName\\b=\"([0-9,\\s,\(,\),\-,\.,_,A-Z,a-z]+)")
-    site = site_regex.search( content )
-    if trace:
-      print (site_regex)
-      print(site)
-    if site:
-      if trace:
-        print("site value \n" , site.group(1))
-      self.site = site.group(1)
-      return self.site
-    print("Could not retreive site value")
-    return
-    return 
-
-  def GetName (self , build_dir = ""):
-    """
-    This function is looking for the name information in the build tree: 
-    which is BuildName
-    """
-    if ( build_dir == ""):
-      build_dir = self.build_dir
-    if self.configure_path == "" and not self.GetConfigureFile( build_dir ):
-      print ("Error in GetName function, could not find Configure.xml")
-      return
-    configure_file = open( self.configure_path, "r" )
-    content = configure_file.read()
-    configure_file.close()
-    name_regex = re.compile( "\\bBuildName\\b=\"([0-9,\\s,\(,\),\-,\.,_,A-Z,a-z]+)\"")
-    name = name_regex.search( content )
-    if trace:
-      print (name_regex)
-      print( name)
-    if name:
-      if trace:
-        print("name value \n" , name.group(1))
-      self.name = name.group(1)
-      return self.name
-    print("Could not retreive name value")
-    return
+    sys.exit(1)
 
-  def GetStamp (self , build_dir = "" ):
+  def ParseConfigureFile(self):
     """
-    This function is looking for the stamp information in the build tree
+    Parse the configuration file to get Name, Site and BuildStamp
     """
-    if ( build_dir == ""):
-      build_dir = self.build_dir
-    if self.configure_path == "" and not self.GetConfigureFile( build_dir ):
-      print ("Error in GetStamp function, could not find Configure.xml")
-      return
     configure_file = open( self.configure_path, "r" )
     content = configure_file.read()
     configure_file.close()
-    stamp_regex = re.compile( "\\bBuildStamp\\b=\"([0-9,\\s,\(,\),\-,\.,_,A-Z,a-z]+)\"")
-    stamp = stamp_regex.search( content )
+    # strip the Log section as it can mess up the XML parser
+    startLog=content.find('<Log>')
+    endLog=content.rfind('</Log>')
+    if startLog > 0 and endLog > startLog:
+      content = content[:(startLog+5)]+content[endLog:]
+    # parse XML
+    root = ET.fromstring(content)
     if trace:
-      print( stamp_regex )
-      print( stamp )
-    if stamp:
-      if trace:
-        print("Stamp value \n" , stamp.group(1))
-      self.stamp = stamp.group(1)
-      return self.stamp
-    print("Could not retreive stamp value")
-    return
+      print( root.attrib )
+    if not 'Name' in root.keys():
+      print("Can't find site name in Configure.XML")
+      sys.exit(1)
+    if not 'BuildName' in root.keys():
+      print("Can't find build name in Configure.XML")
+      sys.exit(1)
+    if not 'BuildStamp' in root.keys():
+      print("Can't find build stamp in Configure.XML")
+      sys.exit(1)
+    self.site = root.get('Name')
+    self.name = root.get('BuildName')
+    self.stamp = root.get('BuildStamp')
 
   def GetBuildId (self, **kwargs):
     """
@@ -180,15 +128,17 @@ class Handler:
       if key == "project":
         project = value
     if ( site == "" or stamp == "" or name == "" or project == ""):
-      print( "Missing argument for buildid request \
-site:"+site+", stamp:"+stamp+", name:"+name+", project:"+project+".")
-      return
+      print( "Missing argument for buildid request site:"+site+", stamp:"+stamp+", name:"+name+", project:"+project+".")
+      sys.exit(1)
+    elif trace:
+      print( "Argument for buildid request site:"+site+", stamp:"+stamp+", name:"+name+", project:"+project+".")
     buildid_api = "/api/v1/getbuildid.php?"
     buildid_params = urllib.parse.urlencode({'project': project, 'site': site, 'stamp': stamp , 'name': name})
     full_url = self.url + buildid_api + buildid_params
     if trace:
       print("full_url: "+full_url)
-    nb_try = 6
+    max_retry = 11
+    nb_try = max_retry
     build_id_regex = re.compile( "<buildid>([0-9]+)</buildid>" )
     while nb_try:
       response = urllib.request.urlopen(full_url).read().decode()
@@ -198,8 +148,8 @@ site:"+site+", stamp:"+stamp+", name:"+name+", project:"+project+".")
       nb_try -= 1
       if buildid or (nb_try == 0):
         break
-      print("No build id, retry ...")
-      time.sleep(60)
+      print("No build id, retry "+str(max_retry-nb_try)+"/"+str(max_retry)+" ...")
+      time.sleep(30)
     if buildid:
       self.buildid = buildid.group(1)
       if trace:
@@ -207,7 +157,7 @@ site:"+site+", stamp:"+stamp+", name:"+name+", project:"+project+".")
       return buildid.group(1)
     else:
       print("Error in recovering buildid")
-      return
+      sys.exit(1)
 
   def GetBuildUrl (self , buildid = "" ):
     """
@@ -249,6 +199,34 @@ site:"+site+", stamp:"+stamp+", name:"+name+", project:"+project+".")
       errors = "Errors occur during tests"
     return ( state , errors)
 
+  def GetReturnValue(self, logfile):
+    fd = open(logfile)
+    content = fd.readlines()[0]
+    fd.close()
+    return int(content.strip("\n"))
+
+  def GetLogStatus(self, logdir):
+    """
+    This function returns the log status of a build as a pair 'state' + 'errors'
+    """
+    configure_rv = os.path.join(logdir, "configure_return_value_log.txt")
+    build_rv = os.path.join(logdir, "build_return_value_log.txt")
+    test_rv = os.path.join(logdir, "test_return_value_log.txt")
+    if os.path.exists( configure_rv ):
+      if (self.GetReturnValue(configure_rv) != 0):
+        return ( 'failed' , 'Configure failed')
+    else:
+      return ( 'failed' , 'Configure not run')
+    if os.path.exists( build_rv ):
+      if (self.GetReturnValue(build_rv) != 0):
+        return ( 'failed' , 'Build failed')
+    else:
+      return ( 'failed' , 'Build not run')
+    if os.path.exists( test_rv ):
+      if (self.GetReturnValue(test_rv) != 0):
+        return ( 'failed' , 'Tests failed')
+    return ('success', '')
+
 """
   This script aims only at recovering the build url
   It uses environment variables setup by Gitlab Runner as default:
@@ -262,11 +240,11 @@ site:"+site+", stamp:"+stamp+", name:"+name+", project:"+project+".")
     cdash_handler.py commit_sha1  project_id  project_directory  token  ref_name
 """
 if __name__ == "__main__":
+  if trace:
+    print(sys.argv)
   if ( len(sys.argv) < 6 and len(sys.argv) > 1 ):
     print("Usage : "+sys.argv[0]+" commit_sha1 project_id project_directory token ref_name")
     sys.exit(1)
-  if trace:
-    print (sys.argv)
   if ( len(sys.argv) >= 6):
     sha1 = sys.argv[1]
     proj = sys.argv[2]
@@ -274,33 +252,36 @@ if __name__ == "__main__":
     token = sys.argv[4]
     refn = sys.argv[5]
   else:
-    if not CheckEnvParameters(['CI_COMMIT_SHA', 'CI_PROJECT_ID', 'CI_PROJECT_DIR', 'K8S_SECRET_API_TOKEN', 'CI_COMMIT_REF_NAME']):
+    if not CheckEnvParameters(['CI_COMMIT_SHA', 'CI_PROJECT_ID', 'CI_PROJECT_DIR', 'CI_COMMIT_REF_NAME']):
       sys.exit(1)
     sha1 = os.environ['CI_COMMIT_SHA']
     proj = os.environ['CI_PROJECT_ID']
     pdir = os.environ['CI_PROJECT_DIR']
-    token = os.environ['K8S_SECRET_API_TOKEN']
     if 'CI_MERGE_REQUEST_REF_PATH' in os.environ.keys():
       refn = os.environ['CI_MERGE_REQUEST_REF_PATH']
     else:
       refn = os.environ['CI_COMMIT_REF_NAME']
+    if CheckEnvParameters(['K8S_SECRET_API_TOKEN']):
+      token = os.environ['K8S_SECRET_API_TOKEN']
+    else:
+      token = None
   handler = Handler()
   build_dir = os.path.join( pdir , "build/")
   if trace:
     print("build_dir is: " + build_dir)
   handler.build_dir = build_dir
-  handler.GetSite()
-  handler.GetName()
-  handler.GetStamp()
+  handler.GetConfigureFile()
+  handler.ParseConfigureFile()
   if handler.GetBuildId() is None:
     cdash_url = "https://cdash.orfeo-toolbox.org"
     state = 'failed'
     error = "Failed to get build id"
   else:
     cdash_url = handler.GetBuildUrl()
-    ( state , error ) = handler.GetBuildStatus()
-  if trace:
-    print ( "cdash_url is: " + cdash_url )
+    ( state , error ) = handler.GetLogStatus( os.path.join( pdir , "log") )
+  print("CDash build URL : "+cdash_url)
+  if token is None:
+    sys.exit(0)
   gitlab_url = "https://gitlab.orfeo-toolbox.org/api/v4/projects/"
   gitlab_url += proj + "/statuses/" + sha1
   params = urllib.parse.urlencode({'name':'cdash:' + handler.site , 'state': state ,\
diff --git a/CI/check_twin_pipelines.py b/CI/check_twin_pipelines.py
index 7f05c1809cf02ae3d37b8bfd984a4bbf24756906..76e21a9abc80099e1bd8ce22025e0f202b129029 100644
--- a/CI/check_twin_pipelines.py
+++ b/CI/check_twin_pipelines.py
@@ -24,6 +24,7 @@ import urllib.parse
 import json
 import re
 import time
+import sys
 
 """
 Send a request to Gitlab and return the answer
@@ -65,9 +66,10 @@ if __name__ == "__main__":
   # are we in a merge_request pipeline ?
   if 'CI_MERGE_REQUEST_IID' in env.keys():
     if not CheckEnvParameters(['K8S_SECRET_API_TOKEN']):
-      print("Make sure you have set a valid acces token for Gitlab API")
-      print("The K8S_SECRET_API_TOKEN environment variable should be set in 'Settings -> CI/CD -> Variables'")
-      sys.exit(1)
+      print("WARNING: Make sure you have set a valid acces token for Gitlab API." \
+        + "The K8S_SECRET_API_TOKEN environment variable should be set in 'Settings -> CI/CD -> Variables'" \
+        + "Without this token, some feature of the CI platform will be disabled.")
+      sys.exit(0)
     if not CheckEnvParameters(['CI_PROJECT_ID','CI_PIPELINE_ID']):
       sys.exit(1)
     mrInfo = GitlabRequest('merge_requests/'+env['CI_MERGE_REQUEST_IID'],token=env['K8S_SECRET_API_TOKEN'])
diff --git a/CI/configure_options.cmake b/CI/configure_options.cmake
index efc9f83144055750a70eeb735a01e8e7b4663d2d..342482f43999b4541561165baf376e1880b34c32 100644
--- a/CI/configure_options.cmake
+++ b/CI/configure_options.cmake
@@ -31,6 +31,9 @@ BUILD_EXAMPLES:BOOL=ON
 BUILD_SHARED_LIBS:BOOL=ON
 BUILD_TESTING:BOOL=ON")
 
+set (otb_qa_option
+"CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON")
+
 set (otb_use_option
 "OTB_USE_6S:BOOL=ON
 OTB_USE_CURL:BOOL=ON
@@ -58,10 +61,6 @@ OTB_USE_SSE_FLAGS:BOOL=ON")
 set (otb_wrap_option
 "OTB_WRAP_PYTHON:BOOL=ON")
 
-set (otb_data_option
-"OTB_DATA_USE_LARGEINPUT:BOOL=OFF
-OTB_DATA_LARGEINPUT_ROOT:PATH=${OTB_LARGEINPUT_ROOT}")
-
 set (cmake_configure_option
 "CMAKE_BUILD_TYPE=${CTEST_BUILD_CONFIGURATION}
 CMAKE_INSTALL_PREFIX:PATH=${CTEST_INSTALL_DIRECTORY}")
@@ -92,6 +91,13 @@ ${cmake_configure_option}
 ${site_option}
 ")
 
+if (QA)
+  set(concat_options
+"${concat_options}
+${otb_qa_option}
+")
+endif()
+
 #Transform the previous string in list
 string (REPLACE "\n" ";" otb_options ${concat_options})
 
diff --git a/CI/ctest2junit.xsl b/CI/ctest2junit.xsl
new file mode 100644
index 0000000000000000000000000000000000000000..e7de63690ff6cdf611741b3a7e98179d18fbd588
--- /dev/null
+++ b/CI/ctest2junit.xsl
@@ -0,0 +1,133 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="xml" indent="yes"/>
+<!-- convert ctest output to junit format -->
+<!--
+Inspired by https://stackoverflow.com/questions/6329215/how-to-get-ctest-results-in-hudson-jenkins
+Based on https://github.com/zanata/zanata-tests/blob/master/scripts/CTest2JUnit.xsl
+Extended by providing total Start date, total time, total test stats
+-->
+	<xsl:template match="/Site">
+            <xsl:variable name="StartDate"><xsl:value-of select="Testing/StartDateTime"/></xsl:variable>
+            <xsl:variable name="DoTime"><xsl:value-of select="Testing/EndTestTime - Testing/StartTestTime"/></xsl:variable>
+            <xsl:variable name="TotalTests"><xsl:value-of select="count(Testing/Test)"/></xsl:variable>
+            <xsl:variable name="Skipped"><xsl:value-of select="count(Testing/Test[@Status='notrun'])"/></xsl:variable>
+            <xsl:variable name="Disabled"><xsl:value-of select="count(Testing/Test/Results/Measurement[Value='Disabled'])"/></xsl:variable>
+            <xsl:variable name="Failed"><xsl:value-of select="count(Testing/Test[@Status='failed'])"/></xsl:variable>
+
+		<testsuite time="{$DoTime}" timestamp="{$StartDate}" tests="{$TotalTests}" failures="{$Failed}" skipped="{$Skipped}" disabled="{$Disabled}">
+
+			<xsl:variable name="BuildName"><xsl:value-of select="@BuildName"/></xsl:variable>
+			<xsl:variable name="BuildStamp"><xsl:value-of select="@BuildStamp"/></xsl:variable>
+			<xsl:variable name="Name"><xsl:value-of select="@Name"/></xsl:variable>
+			<xsl:variable name="Generator"><xsl:value-of select="@Generator"/></xsl:variable>
+			<xsl:variable name="CompilerName"><xsl:value-of select="@CompilerName"/></xsl:variable>
+			<xsl:variable name="OSName"><xsl:value-of select="@OSName"/></xsl:variable>
+			<xsl:variable name="Hostname"><xsl:value-of select="@Hostname"/></xsl:variable>
+			<xsl:variable name="OSRelease"><xsl:value-of select="@OSRelease"/></xsl:variable>
+			<xsl:variable name="OSVersion"><xsl:value-of select="@OSVersion"/></xsl:variable>
+			<xsl:variable name="OSPlatform"><xsl:value-of select="@OSPlatform"/></xsl:variable>
+			<xsl:variable name="Is64Bits"><xsl:value-of select="@Is64Bits"/></xsl:variable>
+			<xsl:variable name="VendorString"><xsl:value-of select="@VendorString"/></xsl:variable>
+			<xsl:variable name="VendorID"><xsl:value-of select="@VendorID"/></xsl:variable>
+			<xsl:variable name="FamilyID"><xsl:value-of select="@FamilyID"/></xsl:variable>
+			<xsl:variable name="ModelID"><xsl:value-of select="@ModelID"/></xsl:variable>
+			<xsl:variable name="ProcessorCacheSize"><xsl:value-of select="@ProcessorCacheSize"/></xsl:variable>
+			<xsl:variable name="NumberOfLogicalCPU"><xsl:value-of select="@NumberOfLogicalCPU"/></xsl:variable>
+			<xsl:variable name="NumberOfPhysicalCPU"><xsl:value-of select="@NumberOfPhysicalCPU"/></xsl:variable>
+			<xsl:variable name="TotalVirtualMemory"><xsl:value-of select="@TotalVirtualMemory"/></xsl:variable>
+			<xsl:variable name="TotalPhysicalMemory"><xsl:value-of select="@TotalPhysicalMemory"/></xsl:variable>
+			<xsl:variable name="LogicalProcessorsPerPhysical"><xsl:value-of select="@LogicalProcessorsPerPhysical"/></xsl:variable>
+			<xsl:variable name="ProcessorClockFrequency"><xsl:value-of select="@ProcessorClockFrequency"/></xsl:variable>
+			<properties>
+				<property name="BuildName" value="{$BuildName} {$DoTime}" />
+				<property name="BuildStamp" value="{$BuildStamp}" />
+				<property name="Name" value="{$Name}" />
+				<property name="Generator" value="{$Generator}" />
+				<property name="CompilerName" value="{$CompilerName}" />
+				<property name="OSName" value="{$OSName}" />
+				<property name="Hostname" value="{$Hostname}" />
+				<property name="OSRelease" value="{$OSRelease}" />
+				<property name="OSVersion" value="{$OSVersion}" />
+				<property name="OSPlatform" value="{$OSPlatform}" />
+				<property name="Is64Bits" value="{$Is64Bits}" />
+				<property name="VendorString" value="{$VendorString}" />
+				<property name="VendorID" value="{$VendorID}" />
+				<property name="FamilyID" value="{$FamilyID}" />
+				<property name="ModelID" value="{$ModelID}" />
+				<property name="ProcessorCacheSize" value="{$ProcessorCacheSize}" />
+				<property name="NumberOfLogicalCPU" value="{$NumberOfLogicalCPU}" />
+				<property name="NumberOfPhysicalCPU" value="{$NumberOfPhysicalCPU}" />
+				<property name="TotalVirtualMemory" value="{$TotalVirtualMemory}" />
+				<property name="TotalPhysicalMemory" value="{$TotalPhysicalMemory}" />
+				<property name="LogicalProcessorsPerPhysical" value="{$LogicalProcessorsPerPhysical}" />
+				<property name="ProcessorClockFrequency" value="{$ProcessorClockFrequency}" />
+			</properties>
+			<xsl:apply-templates select="Testing/Test"/>
+			
+			<system-out>
+				BuildName: <xsl:value-of select="$BuildName" />
+				BuildStamp: <xsl:value-of select="$BuildStamp" />
+				Name: <xsl:value-of select="$Name" />
+				Generator: <xsl:value-of select="$Generator" />
+				CompilerName: <xsl:value-of select="$CompilerName" />
+				OSName: <xsl:value-of select="$OSName" />
+				Hostname: <xsl:value-of select="$Hostname" />
+				OSRelease: <xsl:value-of select="$OSRelease" />
+				OSVersion: <xsl:value-of select="$OSVersion" />
+				OSPlatform: <xsl:value-of select="$OSPlatform" />
+				Is64Bits: <xsl:value-of select="$Is64Bits" />
+				VendorString: <xsl:value-of select="$VendorString" />
+				VendorID: <xsl:value-of select="$VendorID" />
+				FamilyID: <xsl:value-of select="$FamilyID" />
+				ModelID: <xsl:value-of select="$ModelID" />
+				ProcessorCacheSize: <xsl:value-of select="$ProcessorCacheSize" />
+				NumberOfLogicalCPU: <xsl:value-of select="$NumberOfLogicalCPU" />
+				NumberOfPhysicalCPU: <xsl:value-of select="$NumberOfPhysicalCPU" />
+				TotalVirtualMemory: <xsl:value-of select="$TotalVirtualMemory" />
+				TotalPhysicalMemory: <xsl:value-of select="$TotalPhysicalMemory" />
+				LogicalProcessorsPerPhysical: <xsl:value-of select="$LogicalProcessorsPerPhysical" />
+				ProcessorClockFrequency: <xsl:value-of select="$ProcessorClockFrequency" />
+			</system-out>
+		</testsuite>
+	</xsl:template>
+
+    <xsl:template match="Testing/Test">
+        <xsl:variable name="testcasename"><xsl:value-of select="Name"/></xsl:variable>
+        <xsl:variable name="testclassname"><xsl:value-of select=" concat('this', substring(Path,2))"/></xsl:variable>
+		<xsl:variable name="exectime">
+			<xsl:for-each select="Results/NamedMeasurement">
+				<xsl:if test="@name='Execution Time'">
+					<xsl:value-of select="Value"/>
+				</xsl:if>
+			</xsl:for-each>
+		</xsl:variable>
+		
+			<testcase name="{$testcasename}" classname="{$testclassname}" time="{$exectime}">
+            <xsl:if test="@Status = 'passed'">
+            <system-out><xsl:value-of select="Results/Measurement/Value/text()"/></system-out>
+            </xsl:if>
+            <xsl:if test="@Status = 'failed'">
+				<xsl:variable name="failtype">
+					<xsl:for-each select="Results/NamedMeasurement">
+						<xsl:if test="@name = 'Exit Code'">
+							<xsl:value-of select="Value"/>
+						</xsl:if>
+					</xsl:for-each>
+				</xsl:variable>
+				<xsl:variable name="failcode">
+					<xsl:for-each select="Results/NamedMeasurement">
+						<xsl:if test="@name = 'Exit Value'">
+							<xsl:value-of select="Value"/>
+						</xsl:if>
+					</xsl:for-each>
+				</xsl:variable>
+                <failure message="{$failtype} ({$failcode})"><xsl:value-of select="Results/Measurement/Value/text()" /></failure>
+            </xsl:if>
+            <xsl:if test="@Status = 'notrun'">
+                <skipped><xsl:value-of select="Results/Measurement/Value/text()" /></skipped>
+            </xsl:if>
+        </testcase>
+    </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/CI/deploy.sh b/CI/deploy.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d3b0385f05c70847526854123d27c4640956042c
--- /dev/null
+++ b/CI/deploy.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# Configure git for tar.xz
+git config tar.tar.xz.command "xz -c"
+
+pack_suffix=""
+if [ $1 = "develop" ] # check if the branch name is develop or not
+then # we are on develop
+  jobs_directory=/home/otbpush/test/$(date +%F)
+else # we are on a release branch
+  jobs_directory=/home/otbpush/test/staging
+  if [ "$#" -eq 2 ]
+    then # there is a rc tag, we need a suffix for packages
+    pack_suffix=-$(echo "$2" | grep -o "rc[0-9]*") # this retrieve the rc number
+  fi
+fi
+
+echo "jobs_directory=${jobs_directory}"
+echo "pack_suffix=${pack_suffix}"
+
+# Create today's directory on serveur otb5-vm2
+echo "Creating today's directory"
+ssh otbpush@otb5-vm2.orfeo-toolbox.org mkdir -p ${jobs_directory}
+# Delete latest
+echo "Deleting latest directory"
+if [ $1 = "develop" ]
+then # On develop
+  ssh otbpush@otb5-vm2.orfeo-toolbox.org rm -rf /home/otbpush/test/latest
+  # Create symilink
+  ssh otbpush@otb5-vm2.orfeo-toolbox.org ln -s ${jobs_directory} /home/otbpush/test/latest
+  # Cleaning old directory
+  matching_dirs=$(ls -1 | grep -oE '^20[0-9]{2}-[0-9]{2}-[0-9]{2}$' | sort)
+  history_length=11
+  rm -rf $(echo $matching_dirs | tr ' ' '\n' | head -n -${history_length})
+else # On release
+  # Remove what is inside staging area
+  ssh otbpush@otb5-vm2.orfeo-toolbox.org rm -rf ${jobs_directory}/*
+fi
+
+# Push package
+ls -all build_packages/
+echo "Renaming binary packages"
+# find build_packages/. -name "*.run" \
+# -exec sh -c 'mv "$1" "${1%.run}${pack_suffix}.run"' _ {} \;
+for name in $(find build_packages/. -name "OTB-*.*")
+  do 
+  len=(${#name})
+  mv "$name" "${name:0:$len-4}${pack_suffix}${name:$len-4}"
+done
+# TO REMOVE
+###########
+ls -all build_packages/
+###########
+
+echo "Pushing binary packages"
+scp build_packages/OTB-*.{run,zip} otbpush@otb5-vm2.orfeo-toolbox.org:${jobs_directory}/.
+# Push doc
+echo "Pushing documentation"
+scp build/{CookBook-*-html.tar.gz,\
+/Documentation/{Cookbook/latex/CookBook-*.pdf,Doxygen/OTB-Doxygen-*.tar.bz2}} \
+otbpush@otb5-vm2.orfeo-toolbox.org:${jobs_directory}/.
+
+# Create zip, tar.gz and tar.xy source
+echo "Creating source tarball and zip"
+git archive --format=zip -o OTB-sources-$CI_COMMIT_SHORT_SHA.zip HEAD
+git archive --format=tgz -o OTB-sources-$CI_COMMIT_SHORT_SHA.tar.gz HEAD
+git archive --format=tar.xz -o OTB-sources-$CI_COMMIT_SHORT_SHA.tar.xz HEAD
+# Remove old source file
+echo "Removing old sources"
+ssh otbpush@otb5-vm2.orfeo-toolbox.org \
+rm ${jobs_directory}/OTB-sources-*.zip \
+${jobs_directory}/OTB-sources-*.tar.*
+
+# Push new source file
+echo "Pushing new sources"
+scp OTB-sources-$CI_COMMIT_SHORT_SHA.* \
+otbpush@otb5-vm2.orfeo-toolbox.org:${jobs_directory}/
+
+ 
\ No newline at end of file
diff --git a/CI/dev_env.bat b/CI/dev_env.bat
new file mode 100644
index 0000000000000000000000000000000000000000..061c9ee0b528531399a17926e184cb48877b5026
--- /dev/null
+++ b/CI/dev_env.bat
@@ -0,0 +1,106 @@
+@echo off
+:: check input arguments
+if %1.==. (
+  echo "No arch"
+  call :Help
+  goto :eof
+)
+
+if %2.==. (
+  echo "No project"
+  call :Help
+  goto :eof
+)
+
+if /I "%1"=="help" (
+  call :Help
+  goto :eof
+)
+
+if /I "%1"=="/help" (
+  call :Help
+  goto :eof
+)
+
+if /I "%1"=="-help" (
+  call :Help
+  goto :eof
+)
+
+set ARCH=%1
+set PROJECT=%2
+
+if %3.==. (
+  set SHORT_TARGET=10
+) else (
+  set SHORT_TARGET=%3
+)
+
+if %4.==. (
+  set VCVER=14.0
+) else (
+  set VCVER=%4
+)
+
+set TARGET=%SHORT_TARGET%
+if "%TARGET%"=="10" (
+  set TARGET=10.0.17763.0
+)
+
+:: Setup home dir (so that ssh configuration works fine)
+:: if "%USERNAME%"=="otbbot" (
+  set HOMEDRIVE=C:
+  set HOMEPATH=\Users\otbbot
+::)
+echo Home dir: %HOMEDRIVE%%HOMEPATH%
+
+:: Setup Python
+set PATH=C:\tools\Python35-%ARCH%;%PATH%
+set PATH=C:\tools\Python35-%ARCH%\Scripts;%PATH%
+
+:: Setup GL dlls
+set PATH=%PATH%;C:\tools\GL\%ARCH%\bin
+
+:: Setup compiler
+call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" %ARCH% %TARGET% -vcvars_ver=%VCVER%
+
+:: Setup Clcache
+set CLCACHE_DIR=C:\clcache\%PROJECT%-%ARCH%-%TARGET%-%VCVER%
+set CLCACHE_HARDLINK=1
+:: set CLCACHE_SERVER=1
+set CLCACHE_CL=
+for /F "delims=" %%a in ('where cl.exe') do @if defined CLCACHE_CL (break ) else (set CLCACHE_CL=%%a)
+
+echo CL path: "%CLCACHE_CL%"
+
+:: install clcache.exe as cl.exe
+copy C:\tools\Python35-%ARCH%\Scripts\clcache.exe C:\clcache\cl.exe
+set PATH=C:\clcache;%PATH%
+
+:: we need to change cache max size: clcache -M <size-in-bytes>
+if "%PROJECT%"=="xdk" (
+  call "clcache.exe" -M 3000000000
+)
+if "%PROJECT%"=="otb" (
+  call "clcache.exe" -M 2000000000
+)
+
+set IMAGE_NAME=windows-%SHORT_TARGET%-%ARCH%-vc%VCVER%
+echo Generated IMAGE_NAME: %IMAGE_NAME%
+
+:: setup path to perl, but add it last ... (there is a libstdc++.dll in that folder...)
+set PATH=%PATH%;C:\tools\perl\perl\bin
+
+goto :eof
+
+:Help
+setlocal
+echo "Usage: dev_env.bat <compiler_arch>  <project>  [<target-os>  [<vc_version>]]"
+echo "  <compiler_arch> : 'x86' | 'x64'"
+echo "  <project>       : 'xdk' | 'otb'"
+echo "  <target-os>     : '8.1' | '10' (default)"
+echo "  <vc_version>    :"
+echo "    '14.20' (i.e. VS 2019)"
+echo "    '14.16' (i.e. VS 2017)"
+echo "    '14.0'  (i.e. VS 2015) (default)"
+endlocal
diff --git a/CI/main_ci.cmake b/CI/main_ci.cmake
index 6c116722e8d2a033b88141c70af90d9ef01b5dd5..324c18fe116e8580f949c623dd6f584fabd6a0c4 100644
--- a/CI/main_ci.cmake
+++ b/CI/main_ci.cmake
@@ -25,7 +25,12 @@ get_filename_component(OTB_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY)
 set (ENV{LANG} "C") # Only ascii output
 
 # Build Configuration : Release, Debug..
-set (CTEST_BUILD_CONFIGURATION "Release")
+if(ci_build_type)
+  set (CTEST_BUILD_CONFIGURATION ${ci_build_type})
+else()
+  set (CTEST_BUILD_CONFIGURATION "Release")
+endif()
+
 set (CTEST_CMAKE_GENERATOR "Ninja")
 
 # detect short sha
@@ -42,7 +47,7 @@ set_dash_build_name()
 
 # set pipelines to enable documentation
 set(ci_cookbook_profiles mr develop release)
-set(ci_doxygen_profiles mr develop release)
+set(ci_doxygen_profiles develop release)
 list(FIND ci_cookbook_profiles ${ci_profile} ci_do_cookbook)
 list(FIND ci_doxygen_profiles ${ci_profile} ci_do_doxygen)
 
@@ -76,9 +81,6 @@ set (PROJECT_SOURCE_DIR "${OTB_SOURCE_DIR}")
 # Ctest command value
 set (CMAKE_COMMAND "cmake")
 
-# Data directory setting
-set (OTB_LARGEINPUT_ROOT "") # todo
-
 message(STATUS "CI profile : ${ci_profile}")
 
 #The following file set the CONFIGURE_OPTIONS variable
@@ -121,7 +123,12 @@ endif()
 # ------------------------------ Build -----------------------------------------
 if(ci_skip_install)
   message(STATUS "Skip install")
-  set(CTEST_BUILD_TARGET)
+  if (ci_build_target)
+    message(STATUS "Building target: ${ci_build_target}")
+    set(CTEST_BUILD_TARGET ${ci_build_target})
+  else()
+    set(CTEST_BUILD_TARGET)
+  endif()
 else()
   set(CTEST_BUILD_TARGET install)
 endif()
@@ -162,7 +169,11 @@ if ( NOT _test_rv EQUAL 0 )
 endif()
 
 # ----------------------------- Submit -----------------------------------------
-ctest_submit()
+if(ci_skip_submit)
+  message(STATUS "Skip submit")
+else()
+  ctest_submit()
+endif()
 
 # ---------------------------- Doxygen -----------------------------------------
 if(ENABLE_DOXYGEN)
diff --git a/CI/main_packages.cmake b/CI/main_packages.cmake
index cb2d8c1175de8397ccd9c562a4d8cc6d356c5768..a9c3f330f9a9cc452b6d6b1a37a368701f6fe0c9 100644
--- a/CI/main_packages.cmake
+++ b/CI/main_packages.cmake
@@ -29,9 +29,20 @@ get_filename_component( OTB_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY )
 set ( DEBUG "1" )
 
 set ( CTEST_BUILD_CONFIGURATION "Release" )
-set ( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
-set ( CTEST_BUILD_FLAGS "-j1" )
+if(WIN32)
+  set ( CTEST_CMAKE_GENERATOR "NMake Makefiles JOM" )
+  set ( CTEST_BUILD_FLAGS "/S" )
+else()
+  set ( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
+  set ( CTEST_BUILD_FLAGS "-j1")
+endif()
 set ( CTEST_BUILD_NAME "Packages" )
+# Detect site
+if(NOT DEFINED IMAGE_NAME)
+  if(DEFINED ENV{IMAGE_NAME})
+    set(IMAGE_NAME $ENV{IMAGE_NAME})
+  endif()
+endif()
 set ( CTEST_SITE "${IMAGE_NAME}" )
 
 # Find the build name and CI profile
@@ -56,13 +67,14 @@ set ( CONFIGURE_OPTIONS
 "-DCMAKE_INSTALL_PREFIX=${CTEST_INSTALL_DIRECTORY};\
 -DOTB_BINARY_DIR=${OTB_SOURCE_DIR}/build;\
 -DSUPERBUILD_INSTALL_DIR=${OTB_SOURCE_DIR}/xdk;\
--DSUPERBUILD_BINARY_DIR=${OTB_SOURCE_DIR}/build;" )
+-DSUPERBUILD_BINARY_DIR=${OTB_SOURCE_DIR}/build;\
+-DNAME_SUFFIX=${NAME_SUFFIX};" )
 
 # Look for a GIT command-line client.
 find_program(CTEST_GIT_COMMAND NAMES git git.cmd)
 
 # Sources are already checked out : do nothing for update
-set(CTEST_GIT_UPDATE_CUSTOM echo No update)
+set(CTEST_GIT_UPDATE_CUSTOM "${CMAKE_COMMAND}" "-E" "echo" "No update")
 
 
 ctest_start( Experimental TRACK CI_Package )
diff --git a/CI/main_qa.cmake b/CI/main_qa.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..b58b216d9dd0c47fd1b50d2e1e33ded25db77215
--- /dev/null
+++ b/CI/main_qa.cmake
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+#     https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+get_filename_component( OTB_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY )
+
+set( CMAKE_EXPORT_COMPILE_COMMANDS ON )
+set( ci_build_type "Debug" )
+set( CTEST_TEST_TIMEOUT 1500)
+
+include( "${CMAKE_CURRENT_LIST_DIR}/main_superbuild.cmake" )
diff --git a/CI/main_superbuild.cmake b/CI/main_superbuild.cmake
index b3203ae0200e2a9d9b8e4ce9b4ce6c24e1db45cb..27ac7ffe2cc39abd094f93e6a62f095cc03cacae 100644
--- a/CI/main_superbuild.cmake
+++ b/CI/main_superbuild.cmake
@@ -32,17 +32,31 @@ get_xdk()
 
 set( INSTALL_DIR "${XDK_PATH}" )
 
-# FIX ME this part might platform dependent
-set( GDAL_DATA "${XDK_PATH}/share/gdal" )
-set( GEOTIFF_CSV "${XDK_PATH}/share/epsg_csv" )
-set( PROJ_LIB "${XDK_PATH}/share" )
-set( CTEST_ENVIRONMENT
-"PATH=${XDK_PATH}/lib:${XDK_PATH}/bin:$ENV{PATH}
+if(WIN32)
+  file(TO_NATIVE_PATH "${XDK_PATH}" XDK_PATH_NATIVE)
+  file(TO_NATIVE_PATH "${CTEST_BINARY_DIRECTORY}/bin" OTB_BUILD_BIN_DIR_NATIVE)
+  set(ENV{PATH} "$ENV{PATH};${OTB_BUILD_BIN_DIR_NATIVE}" )
+  set(ENV{PATH} "${XDK_PATH_NATIVE}\\bin;$ENV{PATH}" )
+  set(ENV{PATH} "$ENV{PATH};${XDK_PATH_NATIVE}\\lib" )
+  set(ENV{GDAL_DATA} "${XDK_PATH_NATIVE}\\data" )
+  set(ENV{GEOTIFF_CSV} "${XDK_PATH_NATIVE}\\share\\epsg_csv" )
+  set(ENV{PROJ_LIB} "${XDK_PATH_NATIVE}\\share" )
+  # needed to load Qt plugins for testing, not for binary packages where we use a qt.conf file
+  set(ENV{QT_PLUGIN_PATH} "${XDK_PATH_NATIVE}\\plugins")
+  set( CTEST_ENVIRONMENT
+"PATH=$ENV{PATH}
+GDAL_DATA=$ENV{GDAL_DATA}
+GEOTIFF_CSV=$ENV{GEOTIFF_CSV}
+PROJ_LIB=$ENV{PROJ_LIB}
 ")
-# It seems that we do not need that
-# GDAL_DATA= GDAL_DATA
-# GEOTIFF_CSV= GEOTIFF_CSV
-# PROJ_LIB= PROJ_LIB
+else()
+  set(ENV{PATH} "${XDK_PATH}/lib:${XDK_PATH}/bin:$ENV{PATH}" )
+  set( GDAL_DATA "${XDK_PATH}/share/gdal" )
+  set( GEOTIFF_CSV "${XDK_PATH}/share/epsg_csv" )
+  set( PROJ_LIB "${XDK_PATH}/share" )
+  set( CTEST_ENVIRONMENT
+"PATH=$ENV{PATH}
+")
+endif()
 
 include( "${CMAKE_CURRENT_LIST_DIR}/main_ci.cmake" )
-
diff --git a/CI/otb-macos-superbuild.cmake b/CI/otb-macos-superbuild.cmake
index 8fa073741d7346f44f84b3ec8c36d79e81d390c5..7b6f1cc43c9c1bb36a2e2885b57cece503f01417 100644
--- a/CI/otb-macos-superbuild.cmake
+++ b/CI/otb-macos-superbuild.cmake
@@ -24,4 +24,6 @@ set(site_option
 "OTB_USE_GLUT=OFF
 OTB_USE_GLFW=OFF
 CMAKE_C_COMPILER_LAUNCHER:STRING=ccache
-CMAKE_CXX_COMPILER_LAUNCHER:STRING=ccache")
+CMAKE_CXX_COMPILER_LAUNCHER:STRING=ccache
+OTB_DATA_USE_LARGEINPUT:BOOL=ON") 
+# Large input path are in an environment variable on macOS
diff --git a/CI/otb_coverage.sh b/CI/otb_coverage.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0b5d4b219fdb1584778edf7d8d321b5eca080e20
--- /dev/null
+++ b/CI/otb_coverage.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# usage : call CI/otb_coverage.sh from source dir
+OTB_DIR="$(dirname $0)/.."
+OTB_DIR="$(readlink -f $OTB_DIR)"
+
+if [ -z "$BUILD_DIR" ]; then
+BUILD_DIR=${OTB_DIR}/build
+fi
+
+echo Generating gcov reports in $BUILD_DIR ...
+cd $BUILD_DIR
+find $BUILD_DIR -name "*.gcda" -exec llvm-cov gcov -p '{}' > /dev/null \;
+ls *.gcov | grep -E -v '#Modules#[a-zA-Z0-9]+#[a-zA-Z0-9]+#(include|src|app)#' | xargs -L 1 rm
+echo Filtered $(ls $BUILD_DIR/*.gcov | wc -l) gcov reports
+
+gcovr -r $OTB_DIR -x -g --object-directory=$BUILD_DIR > $BUILD_DIR/coverage_report.xml
+echo Generated $BUILD_DIR/coverage_report.xml with $(grep -c '<class ' $BUILD_DIR/coverage_report.xml) classes
diff --git a/CI/prepare_superbuild.cmake b/CI/prepare_superbuild.cmake
index c77c73b17de7e1779f8a763ad15fd87a20e60081..ec99220d64881c82e27b846fcb4cf3a297ba0329 100644
--- a/CI/prepare_superbuild.cmake
+++ b/CI/prepare_superbuild.cmake
@@ -27,10 +27,22 @@ get_filename_component(OTB_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY)
 set ( SUPERBUILD_SOURCE_DIR "${OTB_SOURCE_DIR}/SuperBuild" )
 
 set ( CTEST_BUILD_CONFIGURATION "Release" )
-set ( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
+if(WIN32)
+  set ( CTEST_CMAKE_GENERATOR "NMake Makefiles JOM" )
+  set ( CTEST_BUILD_FLAGS "/S" )
+else()
+  set ( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
+  set ( CTEST_BUILD_FLAGS "-j16")
+endif()
 set ( PROJECT_SOURCE_DIR "${SUPERBUILD_SOURCE_DIR}" )
 set ( CTEST_SOURCE_DIRECTORY "${SUPERBUILD_SOURCE_DIR}" )
 set ( CTEST_BINARY_DIRECTORY "${OTB_SOURCE_DIR}/build/" )
+# Detect site
+if(NOT DEFINED IMAGE_NAME)
+  if(DEFINED ENV{IMAGE_NAME})
+    set(IMAGE_NAME $ENV{IMAGE_NAME})
+  endif()
+endif()
 set ( CTEST_SITE "${IMAGE_NAME}" )
 
 
@@ -48,9 +60,16 @@ set (CTEST_INSTALL_DIRECTORY "${OTB_SOURCE_DIR}/xdk/")
 # HACK
 # This is needed because when using return() function ctest is trying
 # to run the CTEST_COMMAND. And we need it to not produce an error
-set (CTEST_COMMAND "echo \"Exit\"") # HACK FIX ME
+##set (CTEST_COMMAND "echo \"Exit\"") # HACK FIX ME
 set (CMAKE_COMMAND "cmake")
 
+if(WIN32)
+  file(TO_NATIVE_PATH "${CTEST_INSTALL_DIRECTORY}" XDK_INSTALL_DIR_NATIVE)
+  set(ENV{PATH} "${XDK_INSTALL_DIR_NATIVE}\\bin;$ENV{PATH}" )
+  set(ENV{PATH} "$ENV{PATH};${XDK_INSTALL_DIR_NATIVE}\\lib" )
+  # set(ENV{CMAKE_PREFIX_PATH} "${XDK_INSTALL_DIR}" )
+endif()
+
 ########################################################################
 ########################################################################
 # Build process
@@ -64,14 +83,12 @@ find_program(CTEST_GIT_COMMAND NAMES git git.cmd)
 set( GIT "${CTEST_GIT_COMMAND}" )
 
 # Sources are already checked out : do nothing for update
-set(CTEST_GIT_UPDATE_CUSTOM echo No update)
+set(CTEST_GIT_UPDATE_CUSTOM "${CMAKE_COMMAND}" "-E" "echo" "No update")
 
 ctest_start (Experimental TRACK CI_Prepare)
 
 ctest_update( SOURCE "${OTB_SOURCE_DIR}" )
 
-set(CTEST_BUILD_FLAGS "-j16")
-
 set ( SB_CONFIGURE_OPTIONS "")
 include( "${CMAKE_CURRENT_LIST_DIR}/sb_configure_options.cmake" )
 
@@ -84,8 +101,7 @@ ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}"
 
 if ( NOT _configure_rv EQUAL 0 )
   ctest_submit()
-  message( SEND_ERROR "An error occurs during ctest_configure. Dependencies might be buggy.")
-  return()
+  message( FATAL_ERROR "An error occurs during ctest_configure. Dependencies might be buggy.")
 endif()
 
 ########################################################################
@@ -130,160 +146,167 @@ execute_process(
   )
 if ( IS_SB_BUILD )
   message( "Superbuild is already build for ${IMAGE_NAME} with sources as ${SB_MD5}")
-  return()
 else()
   message( "No build available, this job will build and push OTB_DEPENDS")
-endif()
-####################################
-# Back to build
-
-ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}"
-            TARGET "OTB_DEPENDS"
-            RETURN_VALUE _build_rv
-            NUMBER_ERRORS _build_nb_err
-            CAPTURE_CMAKE_ERROR _build_error
-            )
-
-if ( DEBUG )
-  message( "Status for build:" )
-  message("_build_rv=${_build_rv}")
-  message("_build_nb_err=${_build_nb_err}")
-  message("_build_error=${_build_error}")
-endif()
-
-if ( ( NOT ${_build_nb_err} EQUAL 0 ) OR ( ${_build_error} EQUAL -1 ))
-  message( FATAL_ERROR "An error occurs during ctest_build.")
-endif()
-
-ctest_submit()
-
-########################################################################
-########################################################################
-# Git process
-########################################################################
-########################################################################
-
-# WE PUSH ONLY IF BUILD SUCCEED
-# The image used will be passed to this script.
-# TODO verify that images does not have forbidden char in there name
-# TODO right now we rely on ctest_build to know whether there has been an error
-# in build, whereas SuperBuild does not necessarily return an error if something
-# goes wrong
-
-# REPOSITORY_GIT_URL and REMOTE whould be the same. Right now there are
-# different because one is https and one is ssh. Both should be ssh.
-set( REPOSITORY_GIT_URL "git@gitlab.orfeo-toolbox.org:gbonnefille/superbuild-artifact.git")
-# We clone master to have a basic configuration, mainly a correct .gitattribute
-# git clone $REMOTE --branch master --depth 1 superbuild-artifact
-execute_process(
-  COMMAND ${GIT} "clone" "${REPOSITORY_GIT_URL}"
-  "--branch" "master" "--depth" "1" "superbuild-artifact"
-  WORKING_DIRECTORY "${OTB_SOURCE_DIR}"
-  )
-set ( SB_ARTIFACT_GIT "${OTB_SOURCE_DIR}/superbuild-artifact" )
-
-# create a branche
-execute_process(
-  COMMAND ${GIT} "checkout" "-b" "${BRANCH_NAME}"
-  WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
-  RESULT_VARIABLE co_res
-  OUTPUT_VARIABLE co_out
-  ERROR_VARIABLE co_err
-  )
-
-if ( DEBUG )
-  message( "Step 4: check-o")
-  message( "co_res = ${co_res}" )
-  message( "co_out = ${co_out}" )
-  message( "co_err = ${co_err}" )
-endif()
-
-set ( SB_TAR_NAME "SuperBuild_Install.tar" )
-
-# Creating the tar
-# May be for easier maintainability the tar name should be the same as the
-# file inside.
-execute_process(
-  COMMAND ${CMAKE_COMMAND} "-E" "tar" "cf" "${SB_ARTIFACT_GIT}/${SB_TAR_NAME}"
-  -- "${CTEST_INSTALL_DIRECTORY}"
-  WORKING_DIRECTORY ${OTB_SOURCE_DIR}
-  )
+  ####################################
+  # Back to build
+  
+  ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}"
+              TARGET "OTB_DEPENDS"
+              RETURN_VALUE _build_rv
+              NUMBER_ERRORS _build_nb_err
+              CAPTURE_CMAKE_ERROR _build_error
+              )
+  
+  if ( DEBUG )
+    message( "Status for build:" )
+    message("_build_rv=${_build_rv}")
+    message("_build_nb_err=${_build_nb_err}")
+    message("_build_error=${_build_error}")
+  endif()
+  
+  if ( ( NOT ${_build_nb_err} EQUAL 0 ) OR ( ${_build_error} EQUAL -1 ))
+    ctest_submit()
+    message( FATAL_ERROR "An error occurs during ctest_build.")
+  endif()
+  
+  ctest_submit()
+  
+  ########################################################################
+  ########################################################################
+  # Git process
+  ########################################################################
+  ########################################################################
+  
+  # WE PUSH ONLY IF BUILD SUCCEED
+  # The image used will be passed to this script.
+  # TODO verify that images does not have forbidden char in there name
+  # TODO right now we rely on ctest_build to know whether there has been an error
+  # in build, whereas SuperBuild does not necessarily return an error if something
+  # goes wrong
+  set ( SB_ARTIFACT_GIT "${OTB_SOURCE_DIR}/superbuild-artifact" )
+  
+  # REPOSITORY_GIT_URL and REMOTE whould be the same. Right now there are
+  # different because one is https and one is ssh. Both should be ssh.
+  set( REPOSITORY_GIT_URL "git@gitlab.orfeo-toolbox.org:gbonnefille/superbuild-artifact.git")
+  # We clone master to have a basic configuration, mainly a correct .gitattribute
+  # git clone $REMOTE --branch master --depth 1 superbuild-artifact
+  execute_process(
+    COMMAND ${GIT} "clone" "${REPOSITORY_GIT_URL}"
+    "--branch" "master" "--depth" "1" "superbuild-artifact"
+    WORKING_DIRECTORY "${OTB_SOURCE_DIR}"
+    )
 
-if ( DEBUG )
-  if (EXISTS "${SB_ARTIFACT_GIT}/${SB_TAR_NAME}")
-    message("Tar file exists in superbuild_artefact at: ${SB_ARTIFACT_GIT}/${SB_TAR_NAME}")
-  else()
-    message("Tar file does not exist")
+  # create a branche
+  execute_process(
+    COMMAND ${GIT} "checkout" "-b" "${BRANCH_NAME}"
+    WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
+    RESULT_VARIABLE co_res
+    OUTPUT_VARIABLE co_out
+    ERROR_VARIABLE co_err
+    )
+  
+  if ( DEBUG )
+    message( "Step 4: check-o")
+    message( "co_res = ${co_res}" )
+    message( "co_out = ${co_out}" )
+    message( "co_err = ${co_err}" )
   endif()
-endif()
+  
+  set ( SB_TAR_NAME "SuperBuild_Install.tar" )
+  
+  # create the tar
+  # We need to create tar in its directory to avoid weird name in file
+  # "tar: Removing leading `../../' from member names"
+  # WARNING
+  # We are creating a tar containing xdk/.., so when extracting the archive in
+  # an other environment the output file will be xdk... Obvious isn't it?
+  # Well... Not for everyone...
+  # May be for easier maintainability the tar name should be the same as the
+  # file inside.
+  execute_process(
+    COMMAND ${CMAKE_COMMAND} "-E" "tar" "cf" "superbuild-artifact/${SB_TAR_NAME}"
+    -- "${CTEST_INSTALL_DIRECTORY}"
+    WORKING_DIRECTORY ${OTB_SOURCE_DIR}
+    )
 
-# add the file
-execute_process(
-  COMMAND ${GIT} "add" "${SB_TAR_NAME}"
-  WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
-  RESULT_VARIABLE add_res
-  OUTPUT_VARIABLE add_out
-  ERROR_VARIABLE add_err
-  )
+  # In a near futur it might be nice to clean up the mess we made...
 
-if ( DEBUG )
-  message( "Step 5: add")
-  message( "add_res = ${add_res}" )
-  message( "add_out = ${add_out}" )
-  message( "add_err = ${add_err}" )
-endif()
+  if ( DEBUG )
+    if (EXISTS "${SB_ARTIFACT_GIT}/${SB_TAR_NAME}")
+      message("Tar file exists in superbuild_artefact at: ${SB_ARTIFACT_GIT}/${SB_TAR_NAME}")
+    else()
+      message("Tar file does not exist")
+    endif()
+  endif()
+  
+  # add the file
+  execute_process(
+    COMMAND ${GIT} "add" "${SB_TAR_NAME}"
+    WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
+    RESULT_VARIABLE add_res
+    OUTPUT_VARIABLE add_out
+    ERROR_VARIABLE add_err
+    )
 
+  if ( DEBUG )
+    message( "Step 5: add")
+    message( "add_res = ${add_res}" )
+    message( "add_out = ${add_out}" )
+    message( "add_err = ${add_err}" )
+  endif()
 
-# commit
-# We need the author because otherwise the mail is wrong
-# In our case if toto is deploying a key in superbuild-artifact repo
-# the the mail will be toto's
-execute_process(
-  COMMAND ${GIT} "commit" "--author=\"otbbot <otbbot@orfeo-toolbox.org>\""
-  "-m" "\"New Superbuild for ${SB_MD5} on ${IMAGE_NAME}\""
-  WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
-  RESULT_VARIABLE com_res
-  OUTPUT_VARIABLE com_out
-  ERROR_VARIABLE com_err
-  )
+  # commit
+  # We need the author because otherwise the mail is wrong
+  # In our case if toto is deploying a key in superbuild-artifact repo
+  # the the mail will be toto's
+  execute_process(
+    COMMAND ${GIT} "commit" "--author=\"otbbot <otbbot@orfeo-toolbox.org>\""
+    "-m" "\"New Superbuild for ${SB_MD5} on ${IMAGE_NAME}\""
+    WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
+    RESULT_VARIABLE com_res
+    OUTPUT_VARIABLE com_out
+    ERROR_VARIABLE com_err
+    )
 
-if ( DEBUG )
-  message( "Step 6: com")
-  message( "com_res = ${com_res}" )
-  message( "com_out = ${com_out}" )
-  message( "com_err = ${com_err}" )
-endif()
+  if ( DEBUG )
+    message( "Step 6: com")
+    message( "com_res = ${com_res}" )
+    message( "com_out = ${com_out}" )
+    message( "com_err = ${com_err}" )
+  endif()
 
+  # This part is just for debug
+  if ( DEBUG )
+    execute_process(
+      COMMAND ${GIT} "log" "-1"
+      WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
+      RESULT_VARIABLE log_res
+      OUTPUT_VARIABLE log_out
+      ERROR_VARIABLE log_err
+      )
+
+    message( "Step 6bis: log")
+    message( "log_res = ${log_res}" )
+    message( "log_out = ${log_out}" )
+    message( "log_err = ${log_err}" )
+  endif()
 
-# This part is just for debug
-if ( DEBUG )
+  # push
+  # we should be able to do a simple : git push origin $BRANCH_NAME
   execute_process(
-    COMMAND ${GIT} "log" "-1"
+    COMMAND ${GIT} "push" "${REPOSITORY_GIT_URL}" "${BRANCH_NAME}"
     WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
-    RESULT_VARIABLE log_res
-    OUTPUT_VARIABLE log_out
-    ERROR_VARIABLE log_err
+    RESULT_VARIABLE push_res
+    OUTPUT_VARIABLE push_out
+    ERROR_VARIABLE push_err
     )
 
-  message( "Step 6bis: log")
-  message( "log_res = ${log_res}" )
-  message( "log_out = ${log_out}" )
-  message( "log_err = ${log_err}" )
-endif()
-
-# push
-# we should be able to do a simple : git push origin $BRANCH_NAME
-execute_process(
-  COMMAND ${GIT} "push" "${REPOSITORY_GIT_URL}" "${BRANCH_NAME}"
-  WORKING_DIRECTORY ${SB_ARTIFACT_GIT}
-  RESULT_VARIABLE push_res
-  OUTPUT_VARIABLE push_out
-  ERROR_VARIABLE push_err
-  )
+  if ( DEBUG )
+    message( "Step 7: push")
+    message( "push_res = ${push_res}" )
+    message( "push_out = ${push_out}" )
+    message( "push_err = ${push_err}" )
+  endif()
 
-if ( DEBUG )
-  message( "Step 7: push")
-  message( "push_res = ${push_res}" )
-  message( "push_out = ${push_out}" )
-  message( "push_err = ${push_err}" )
-endif()
\ No newline at end of file
+endif()
diff --git a/CI/ubuntu-18.04-llvm-qa.cmake b/CI/ubuntu-18.04-llvm-qa.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0aea390ca319d6addaa6815b9ca2dc83e3971625
--- /dev/null
+++ b/CI/ubuntu-18.04-llvm-qa.cmake
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+#     https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Configuration options for ubuntu-18.04-llvm-qa
+
+set(site_option
+"CMAKE_C_COMPILER:STRING=clang
+CMAKE_CXX_COMPILER:STRING=clang++
+CMAKE_C_FLAGS:STRING=--coverage
+CMAKE_CXX_FLAGS:STRING=--coverage
+CMAKE_EXE_LINKER_FLAGS:STRING=-fuse-ld=lld
+CMAKE_MODULE_LINKER_FLAGS:STRING=-fuse-ld=lld
+CMAKE_SHARED_LINKER_FLAGS:STRING=-fuse-ld=lld
+")
diff --git a/Modules/Core/SpatialObjects/CMakeLists.txt b/CI/windows-10-x64-vc14.0.cmake
similarity index 82%
rename from Modules/Core/SpatialObjects/CMakeLists.txt
rename to CI/windows-10-x64-vc14.0.cmake
index f51c1fe865fb50d10cc08f27a4b1d3cdfcd378b6..dc954ec8ce49f6812c9c481ab5e41a90a5b91940 100644
--- a/Modules/Core/SpatialObjects/CMakeLists.txt
+++ b/CI/windows-10-x64-vc14.0.cmake
@@ -18,6 +18,8 @@
 # limitations under the License.
 #
 
-project(OTBSpatialObjects)
+# Configuration options for windows-10-x64-vc14.0.cmake
 
-otb_module_impl()
+set(site_option
+"CMAKE_CXX_FLAGS:STRING=/DTHROW_QCRITICAL=0 /DWIN32 /D_WINDOWS /W3 /GR /EHsc
+")
diff --git a/CI/windows-8.1-x64-vc14.0.cmake b/CI/windows-8.1-x64-vc14.0.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..de06cc7a12e38df5851e44f7381cbabd12066f3c
--- /dev/null
+++ b/CI/windows-8.1-x64-vc14.0.cmake
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+#     https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Configuration options for windows-8.1-x64-vc14.0.cmake
+
+set(site_option
+"CMAKE_CXX_FLAGS:STRING=/DTHROW_QCRITICAL=0 /DWIN32 /D_WINDOWS /W3 /GR /EHsc
+")
diff --git a/CI/windows-8.1-x86-vc14.0.cmake b/CI/windows-8.1-x86-vc14.0.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..b0f57960658f30b1df67106e36ee2dcaa57715f5
--- /dev/null
+++ b/CI/windows-8.1-x86-vc14.0.cmake
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+#     https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Configuration options for windows-8.1-x86-vc14.0.cmake
+
+set(site_option
+"CMAKE_CXX_FLAGS:STRING=/DTHROW_QCRITICAL=0 /DWIN32 /D_WINDOWS /W3 /GR /EHsc
+")
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c162d39a17e6c8203d186fdad434ae93a651dc74..256b63ce38b97cbf568db835ed361fa371d9a004 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -117,7 +117,7 @@ find_package ( PythonLibs )
 # Configure the default OTB_DATA_ROOT for the location of OTB Data.
 find_path(OTB_DATA_ROOT
   NAMES README-OTB-Data
-  HINTS ${OTB_SOURCE_DIR}/Data $ENV{OTB_DATA_ROOT}
+  HINTS ${OTB_SOURCE_DIR}/Data
   )
 #mark_as_advanced(OTB_DATA_ROOT)
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c57bb8eef8fd1eff27e994be2578f54aa1383edc..67732a9168fd3a2bc4601113c7118284bb96adff 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -58,9 +58,10 @@ then send a merge request.
 Note that we also accept PRs on our [GitHub mirror](https://github.com/orfeotoolbox/OTB)
 which we will manually merge.
 
-Feature branches are tested on multiple platforms on the OTB test infrastructure (a.k.a the [Dashboard](https://cdash.orfeo-toolbox.org/)). They appear in the FeatureBranches section. 
+Feature branches are tested on multiple platforms on the OTB
+[CI infrastructure](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/pipelines). 
 
-Caveat: even if the Dashboard build on develop branch is broken, it is not
+Caveat: even if the CI build on develop branch is broken, it is not
 allowed to push fixes directly on develop. The developer trying to fix the
 build should create a merge request and submit it for review. Direct push to
 develop without review must be avoided.
@@ -100,33 +101,36 @@ OTB team.
 * Merge requests **must receive at least 2 positives votes from core developers** (members of Main Repositories group in Gitlab with at least "Developer" level; this includes PSC members) before being merged
 * The merger is responsible for checking that the branch is up-to-date with develop
 * Merge requests can be merged by anyone (not just PSC or RM) with push access to develop
-* Merge requests can be merged once the dashboard is proven green for this branch.
-  This condition is mandatory unless reviewers and authors explicitely agree that
-  it can be skipped (for instance in case of documentation merges or compilation
-  fixes on develop). Branches of that sort can be identified with the ~patch label, 
-  which tells the reviewer that the author would like to merge without dashboard testing.
+* Merge requests can be merged once the CI pipeline passes successfully. See
+  next section for details on the CI pipelines.
 
-Branches can be registered for dashboard testing by adding one line in `Config/feature_branches.txt` in [otb-devutils repository](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-devutils.git).
 
-For branches in the main repository, the syntax is the following:
+### Using the CI platform
 
-```
-branch_name [otb-data_branch_name]
+The CI pipelines are triggered automatically when pushing commits. If you push
+to a fork, you will need a few settings to trigger properly the CI pipelines:
 
-```
-The second branch name is optional. It can be set if you need to modify [otb-data](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git) according to your changes.
+* You must add Runners for your fork: the best way is to ask access to the
+  runners from main repository when doing your first MR. During code review,
+  someone from CI admins will assign the runners to your fork.
+* [Optional] You can create a
+  [personal access token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html)
+  (choose the scope API) and add it as a secret variable: on the project page of
+  your fork, go to Settings -> CI/CD -> Variables, add the variable `K8S_SECRET_API_TOKEN`
+  with your token as value (you should mask this variable for security reasons).
 
-For branches in forks, the syntax is the following:
-```
-user/branch_name [user/otb-data_branch_name]
-```
-Again, the second branch name is optional.
+When your pipeline ends, there are two cases:
 
-For users without push access to [otb-devutils repository](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-devutils.git), the modification can be asked through a merge requests to this repository.
+* if all the jobs succeed, you see a green pipeline, which means no problem was
+  found on your commit.
+* if one job fails, you see a red pipeline, which means something is broken in
+  your commit. The pipeline widget on Gitlab will tell you which job failed. You
+  will also find special jobs "cdash:..." in the stage `external` that provide
+  a link to the [Dashboard](https://cdash.orfeo-toolbox.org/index.php?project=OTB)
+  where you can look more in details into compilation errors and failed tests.
 
-Once the feature branch is registered for testing, it should appear in the *FeatureBranches* section of the [OTB dashboard](https://cdash.orfeo-toolbox.org/index.php?project=OTB) next day (remember tests are run on a nightly basis).
-
-Do not forget to remove the feature branch for testing once it has been merged.
+More details on the CI platform can be found
+[here](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/wikis/OTB-Continuous-Integration-platform).
 
 ### Contribution license agreement
 
diff --git a/Data/Baseline/Examples/ChangeDetection/KullbackLeiblerProfileChDetTest.png b/Data/Baseline/Examples/ChangeDetection/KullbackLeiblerProfileChDetTest.png
index 823c2911de5005d27f3ba5637bf320f12c793643..f7d4ba8ed40b68799d9ba56a8186fdad62f802b2 100644
--- a/Data/Baseline/Examples/ChangeDetection/KullbackLeiblerProfileChDetTest.png
+++ b/Data/Baseline/Examples/ChangeDetection/KullbackLeiblerProfileChDetTest.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:8e37611e0c9e004ae01a41628a9c0be6a6948167427e6623829cd75b1bae44b9
-size 98119
+oid sha256:5273c30572ea01479051681b59ea87c0a01006a27faa7acd79f93923f45a7e8c
+size 105454
diff --git a/Data/Baseline/OTB/Files/dmDisparityMapEstimationOutput1.txt b/Data/Baseline/OTB/Files/dmDisparityMapEstimationOutput1.txt
index 9057e51b07e342f82f43fd5addc374e9becc4416..36ddc47cc14b0c55c236e05e3a8f7f6072bc8224 100644
--- a/Data/Baseline/OTB/Files/dmDisparityMapEstimationOutput1.txt
+++ b/Data/Baseline/OTB/Files/dmDisparityMapEstimationOutput1.txt
@@ -1,65 +1,13 @@
-Point [25.000000, 28.000000] -> transform parameters: [-1, 1, 2, 0.9999999999999982, 1.999999999999999]
-Point [33.000000, 28.000000] -> transform parameters: [-1, 1, 2, 0.9999999999999982, 1.999999999999999]
 Point [29.000000, 32.000000] -> transform parameters: [-1, 1, 2, 0.9999999999999982, 1.999999999999999]
-Point [195.000000, 34.000000] -> transform parameters: [-1, -2, 1, -1.99999999999999, 0.9999999999999986]
-Point [203.000000, 34.000000] -> transform parameters: [-1, -2, 1, -1.99999999999999, 0.9999999999999986]
-Point [25.000000, 36.000000] -> transform parameters: [-1, 1, 2, 0.9999999999999982, 1.999999999999999]
-Point [33.000000, 36.000000] -> transform parameters: [-1, 1, 2, 0.9999999999999982, 1.999999999999999]
-Point [105.000000, 38.000000] -> transform parameters: [-0.4326462096884831, -0.8237850307980636, -2.1762149692019364, -0.8237850307980573, -2.17621496920194]
-Point [113.000000, 38.000000] -> transform parameters: [-0.4326462096884831, -0.8237850307980636, -2.1762149692019364, -0.8237850307980573, -2.17621496920194]
 Point [199.000000, 38.000000] -> transform parameters: [-1, -2, 1, -1.99999999999999, 0.9999999999999986]
-Point [109.000000, 42.000000] -> transform parameters: [-0.4326462096884831, -0.8237850307980636, -2.1762149692019364, -0.8237850307980573, -2.17621496920194]
-Point [195.000000, 42.000000] -> transform parameters: [-1, -2, 1, -1.99999999999999, 0.9999999999999986]
-Point [203.000000, 42.000000] -> transform parameters: [-1, -2, 1, -1.99999999999999, 0.9999999999999986]
-Point [105.000000, 46.000000] -> transform parameters: [-0.4326462096884831, -0.8237850307980636, -2.1762149692019364, -0.8237850307980573, -2.17621496920194]
-Point [113.000000, 46.000000] -> transform parameters: [-0.4326462096884831, -0.8237850307980636, -2.1762149692019364, -0.8237850307980573, -2.17621496920194]
-Point [182.000000, 82.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019426, -0.8237850307980593]
-Point [190.000000, 82.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019426, -0.8237850307980593]
-Point [186.000000, 86.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019426, -0.8237850307980593]
-Point [182.000000, 90.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019426, -0.8237850307980593]
-Point [190.000000, 90.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019426, -0.8237850307980593]
-Point [118.000000, 94.000000] -> transform parameters: [-0.06895526364944375, 0.0041981524022816075, 0.01659005014019499, 0.004198152402284198, 0.016590050140193883]
-Point [126.000000, 94.000000] -> transform parameters: [-0.06895526364944375, 0.0041981524022816075, 0.01659005014019499, 0.004198152402284198, 0.016590050140193883]
-Point [62.000000, 98.000000] -> transform parameters: [-1, -3, 0, -2.999999999999998, -2.997447705593446e-17]
-Point [70.000000, 98.000000] -> transform parameters: [-1, -3, 0, -2.999999999999998, -2.997447705593446e-17]
-Point [122.000000, 98.000000] -> transform parameters: [-0.06895526364944375, 0.0041981524022816075, 0.01659005014019499, 0.004198152402284198, 0.016590050140193883]
-Point [66.000000, 102.000000] -> transform parameters: [-1, -3, 0, -2.999999999999998, -2.997447705593446e-17]
-Point [118.000000, 102.000000] -> transform parameters: [-0.06895526364944375, 0.0041981524022816075, 0.01659005014019499, 0.004198152402284198, 0.016590050140193883]
-Point [126.000000, 102.000000] -> transform parameters: [-0.06895526364944375, 0.0041981524022816075, 0.01659005014019499, 0.004198152402284198, 0.016590050140193883]
-Point [62.000000, 106.000000] -> transform parameters: [-1, -3, 0, -2.999999999999998, -2.997447705593446e-17]
-Point [70.000000, 106.000000] -> transform parameters: [-1, -3, 0, -2.999999999999998, -2.997447705593446e-17]
-Point [21.000000, 127.000000] -> transform parameters: [-0.4094814161469302, -0.09996668018703403, 0.09996668018702337, -0.09996668018703297, 0.09996668018703014]
-Point [29.000000, 127.000000] -> transform parameters: [-0.4094814161469302, -0.09996668018703403, 0.09996668018702337, -0.09996668018703297, 0.09996668018703014]
-Point [25.000000, 131.000000] -> transform parameters: [-0.4094814161469302, -0.09996668018703403, 0.09996668018703758, -0.09996668018703297, 0.09996668018703014]
-Point [175.000000, 131.000000] -> transform parameters: [-1, 2, 0, 1.9999999999999871, 2.0182200400791482e-17]
-Point [183.000000, 131.000000] -> transform parameters: [-1, 2, 0, 1.9999999999999871, 2.0182200400791482e-17]
-Point [21.000000, 135.000000] -> transform parameters: [-0.4094814161469302, -0.09996668018703403, 0.09996668018703758, -0.09996668018703297, 0.09996668018703014]
-Point [29.000000, 135.000000] -> transform parameters: [-0.4094814161469302, -0.09996668018703403, 0.09996668018703758, -0.09996668018703297, 0.09996668018703014]
+Point [109.000000, 42.000000] -> transform parameters: [-0.452124907113126, -0.8283223404045827, -2.0723224585710938, -0.8283223404045758, -2.072322458571092]
+Point [186.000000, 86.000000] -> transform parameters: [-0.4521249071131251, 2.0723224585710796, -0.8283223404045685, 2.0723224585710915, -0.8283223404045712]
+Point [122.000000, 98.000000] -> transform parameters: [-0.07914484780444003, 0.004023414455602392, 0.1883684912752983, 0.0040234144556013235, 0.18836849127529462]
+Point [66.000000, 102.000000] -> transform parameters: [-1, -3, 0, -2.9999999999999964, 5.3833972119105215e-17]
+Point [25.000000, 131.000000] -> transform parameters: [-0.4126585211258881, 0.05046050479198172, -0.05046050479197106, 0.050460504791982844, -0.050460504791982816]
 Point [179.000000, 135.000000] -> transform parameters: [-1, 2, 0, 1.9999999999999871, 2.0182200400791482e-17]
-Point [175.000000, 139.000000] -> transform parameters: [-1, 2, 0, 1.9999999999999871, 2.0182200400791482e-17]
-Point [183.000000, 139.000000] -> transform parameters: [-1, 2, 0, 1.9999999999999871, 2.0182200400791482e-17]
-Point [110.000000, 154.000000] -> transform parameters: [-1, -2, 1, -1.9999999999999931, 0.9999999999999927]
-Point [118.000000, 154.000000] -> transform parameters: [-1, -2, 1, -1.9999999999999931, 0.9999999999999927]
 Point [114.000000, 158.000000] -> transform parameters: [-1, -2, 1, -1.9999999999999931, 0.9999999999999927]
-Point [110.000000, 162.000000] -> transform parameters: [-1, -2, 1, -1.9999999999999931, 0.9999999999999927]
-Point [118.000000, 162.000000] -> transform parameters: [-1, -2, 1, -1.9999999999999931, 0.9999999999999927]
-Point [39.000000, 171.000000] -> transform parameters: [-0.4326462096884826, 2.1762149692019435, 0.8237850307980636, 2.1762149692019412, 0.8237850307980553]
-Point [45.000000, 171.000000] -> transform parameters: [-0.4326462096884826, 2.1762149692019435, 0.8237850307980636, 2.1762149692019412, 0.8237850307980553]
-Point [42.000000, 174.000000] -> transform parameters: [-0.4326462096884826, 2.1762149692019435, 0.8237850307980636, 2.1762149692019412, 0.8237850307980553]
-Point [38.000000, 178.000000] -> transform parameters: [-0.4326462096884826, 2.1762149692019435, 0.8237850307980636, 2.1762149692019412, 0.8237850307980553]
-Point [46.000000, 178.000000] -> transform parameters: [-0.4326462096884826, 2.1762149692019435, 0.8237850307980636, 2.1762149692019412, 0.8237850307980553]
-Point [191.000000, 193.000000] -> transform parameters: [-0.40948141614693134, -2.099966680187009, -1.9000333198129624, -2.0999666801870225, -1.9000333198129742]
-Point [199.000000, 193.000000] -> transform parameters: [-0.40948141614693134, -2.099966680187009, -1.9000333198129624, -2.0999666801870225, -1.9000333198129742]
-Point [195.000000, 197.000000] -> transform parameters: [-0.40948141614693134, -2.099966680187009, -1.9000333198129624, -2.0999666801870225, -1.9000333198129742]
-Point [191.000000, 201.000000] -> transform parameters: [-0.40948141614693134, -2.099966680187009, -1.9000333198129624, -2.0999666801870225, -1.9000333198129742]
-Point [199.000000, 201.000000] -> transform parameters: [-0.40948141614693134, -2.099966680187009, -1.9000333198129624, -2.0999666801870225, -1.9000333198129742]
-Point [74.000000, 214.000000] -> transform parameters: [-0.3243961363713258, -0.3581175553554914, -0.49646256945948153, -0.358117555355491, -0.4964625694594842]
-Point [82.000000, 214.000000] -> transform parameters: [-0.3243961363713258, -0.3581175553554914, -0.49646256945948153, -0.358117555355491, -0.4964625694594842]
-Point [78.000000, 218.000000] -> transform parameters: [-0.3243961363713258, -0.3581175553554914, -0.49646256945948153, -0.358117555355491, -0.4964625694594842]
-Point [74.000000, 222.000000] -> transform parameters: [-0.3243961363713258, -0.3581175553554914, -0.49646256945948153, -0.358117555355491, -0.4964625694594842]
-Point [82.000000, 222.000000] -> transform parameters: [-0.3243961363713258, -0.3581175553554914, -0.49646256945948153, -0.358117555355491, -0.4964625694594842]
-Point [139.000000, 227.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019417, -0.8237850307980512]
-Point [147.000000, 227.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019417, -0.8237850307980512]
-Point [143.000000, 231.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019417, -0.8237850307980512]
-Point [139.000000, 235.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019417, -0.8237850307980512]
-Point [147.000000, 235.000000] -> transform parameters: [-0.43264620968848305, 2.1762149692019364, -0.8237850307980636, 2.1762149692019417, -0.8237850307980512]
+Point [42.000000, 174.000000] -> transform parameters: [-0.45212490711312603, 2.0723224585710938, 0.8283223404045827, 2.0723224585710924, 0.8283223404045742]
+Point [195.000000, 197.000000] -> transform parameters: [-0.05964744901725145, -0.3946432423196029, -0.455084544098014, -0.39464324231959125, -0.45508454409802646]
+Point [78.000000, 218.000000] -> transform parameters: [-0.30451124953005193, -0.3869494822710493, -0.37966725310383254, -0.3869494822710459, -0.37966725310382177]
+Point [143.000000, 231.000000] -> transform parameters: [-0.45212490711312164, 2.072322458571108, -0.8283223404045543, 2.0723224585710946, -0.8283223404045682]
diff --git a/Data/Baseline/OTB/Files/feTvLineSpatialObjectListToRightAnglePointSetFilterOutputAscii.txt b/Data/Baseline/OTB/Files/feTvLineSpatialObjectListToRightAnglePointSetFilterOutputAscii.txt
deleted file mode 100644
index 997f47bcdcaae1070baaea238dc69b7641f9418f..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Files/feTvLineSpatialObjectListToRightAnglePointSetFilterOutputAscii.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Number of right angles detected  1
- Right Angle found in point : [30.5626, 10.5977]
diff --git a/Data/Baseline/OTB/Files/feTvLocaLHoughLinesDetected.txt b/Data/Baseline/OTB/Files/feTvLocaLHoughLinesDetected.txt
deleted file mode 100644
index 47c0ce6df62e963724f1aae381ee5193e84a1a0f..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Files/feTvLocaLHoughLinesDetected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-size of the Line list 8
-[19, 9] 	[0, 8]
-[18, 39] 	[19, 20]
-[18, 48] 	[18, 40]
-[39, 9] 	[20, 8]
-[20, 39] 	[21, 20]
-[20, 48] 	[21, 40]
-[48, 9] 	[40, 8]
-[48, 35] 	[40, 24]
diff --git a/Data/Baseline/OTB/Files/prTvGenericMapProjection.1.txt b/Data/Baseline/OTB/Files/prTvGenericMapProjection.1.txt
deleted file mode 100644
index 3eacc0fa4ce4c194366a31a62b2a84837fdb78a5..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Files/prTvGenericMapProjection.1.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-PROJCS["UTM Zone 31, Northern Hemisphere",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]
-
-Forward projection: 
-[1.44, 43.605] -> [374100.828760369, 4829184.80636283]
-
-PROJCS["UTM Zone 31, Northern Hemisphere",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]
-
-Inverse projection: 
-[374100.8, 4829184.8] -> [1.43999964524438, 43.6049999378673]
-
diff --git a/Data/Baseline/OTB/Files/prTvGenericMapProjection.2.txt b/Data/Baseline/OTB/Files/prTvGenericMapProjection.2.txt
deleted file mode 100644
index 3624dc5e998eda57ff7c1d0f27065878aefb5930..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Files/prTvGenericMapProjection.2.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-PROJCS["WGS 84 / UTM zone 31N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32631"]]
-
-Forward projection: 
-[1.44, 43.605] -> [374100.828760369, 4829184.80636283]
-
-PROJCS["WGS 84 / UTM zone 31N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32631"]]
-
-Inverse projection: 
-[374100.8, 4829184.8] -> [1.43999964524438, 43.6049999378673]
-
diff --git a/Data/Baseline/OTB/Files/prTvGenericMapProjection.txt b/Data/Baseline/OTB/Files/prTvGenericMapProjection.txt
index 476cc5832003c60cd692d35e2921c1bb3d347aaf..0627ec3216ba499116bbee347056f07f604cc1b4 100644
--- a/Data/Baseline/OTB/Files/prTvGenericMapProjection.txt
+++ b/Data/Baseline/OTB/Files/prTvGenericMapProjection.txt
@@ -1,10 +1,6 @@
-PROJCS["UTM Zone 31, Northern Hemisphere",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AXIS["Lat",NORTH],AXIS["Long",EAST],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]
-
 Forward projection: 
 [1.44, 43.605] -> [374100.8287608, 4829184.80641377]
 
-PROJCS["UTM Zone 31, Northern Hemisphere",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9108"]],AXIS["Lat",NORTH],AXIS["Long",EAST],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]
-
 Inverse projection: 
 [374100.8, 4829184.8] -> [1.439999645251, 43.6049999374087]
 
diff --git a/Data/Baseline/OTB/Images/bfTvSpatialObjectDrawingNoInput.png b/Data/Baseline/OTB/Images/bfTvSpatialObjectDrawingNoInput.png
deleted file mode 100644
index 248eddfbd34802c4df5abea1db0c834197e60021..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/bfTvSpatialObjectDrawingNoInput.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d77aaaf4b06909d791c130fa9a64e214ff414d9419b8803137ea68b5a4f0a003
-size 555
diff --git a/Data/Baseline/OTB/Images/bfTvSpatialObjectDrawingNoInput.png.aux.xml b/Data/Baseline/OTB/Images/bfTvSpatialObjectDrawingNoInput.png.aux.xml
deleted file mode 100644
index ab08091c3a5feff33bbc1eb1da446be58bca537b..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/bfTvSpatialObjectDrawingNoInput.png.aux.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<PAMDataset>
-  <GeoTransform> -1.0050000000000000e+02,  1.0000000000000000e+00,  0.0000000000000000e+00, -5.0500000000000000e+01,  0.0000000000000000e+00,  1.0000000000000000e+00</GeoTransform>
-</PAMDataset>
diff --git a/Data/Baseline/OTB/Images/cdTVKullbackLeiblerProfileImageFilterOutput.tif b/Data/Baseline/OTB/Images/cdTVKullbackLeiblerProfileImageFilterOutput.tif
index 48b2c70ef84462b022991021b618cef2873f0050..3fe5bd7e66a8ee59998200f62298688e2a606e7f 100644
--- a/Data/Baseline/OTB/Images/cdTVKullbackLeiblerProfileImageFilterOutput.tif
+++ b/Data/Baseline/OTB/Images/cdTVKullbackLeiblerProfileImageFilterOutput.tif
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e6bb44d10e6bda4bf05b1da502f38ed37da4bb4255303ef425bf5cfcca317547
-size 14126924
+oid sha256:8c95283e5fd179085f8e0ae6cb23cfed03d8b0d24f2213591c33d97fe3dd360a
+size 6721840
diff --git a/Data/Baseline/OTB/Images/feFilterHoughTransformDraw.tif b/Data/Baseline/OTB/Images/feFilterHoughTransformDraw.tif
deleted file mode 100644
index fd3d9522e06aa3d3d2a5bf71d06d66c03904a689..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFilterHoughTransformDraw.tif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:58b4f13bbf32deac4b872668d5a340b42ea9f1259553d1252783d6076531b0a9
-size 11435
diff --git a/Data/Baseline/OTB/Images/feFilterLocalHoughDraw_amst_20_20_1.png b/Data/Baseline/OTB/Images/feFilterLocalHoughDraw_amst_20_20_1.png
deleted file mode 100644
index d6b013f88b610af1c98cc9f13fe60cb4c13a7bc9..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFilterLocalHoughDraw_amst_20_20_1.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:fabb94ee9bccd808a70ec623d26d65786ff6a94c161fdb3e6ff8cb79dd2ca41f
-size 60303
diff --git a/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.1.tif b/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.1.tif
deleted file mode 100644
index eadc230e77375f333be99144a4a695c64fca6896..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.1.tif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e626a87b27e815c8b876f6692fc07f916b75c0f8f880fb73371f301081aa6533
-size 1000
diff --git a/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.2.tif b/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.2.tif
deleted file mode 100644
index a70c482c13046caba4d8e94b56a2a6fc3ac0ca86..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.2.tif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8c5924c750b50f19823be9a8fbaa9f17fa0613b5263d9ca3540bff32d4c683d1
-size 1198
diff --git a/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.tif b/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.tif
deleted file mode 100644
index 4800959c76f105162224211b20cd740731bd0691..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFiltreExtractSegments_ImageLine.tif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6b67e0c1bb4037fb1ba9c9d7be6af308a97815485ecc8165d9e4fe46b4d172c2
-size 1044
diff --git a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_ImageLine_20_20_2.1.tif b/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_ImageLine_20_20_2.1.tif
deleted file mode 100644
index 9aeae9380dfbadda8c470ed1b6c4d3a4bd11a4de..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_ImageLine_20_20_2.1.tif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bb9ebbd80324367ae3f76a09c95084b039b00127be0c01068220420726b73223
-size 363
diff --git a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_ImageLine_20_20_2.tif b/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_ImageLine_20_20_2.tif
deleted file mode 100644
index e32bb136da91ff7b8e450cd80fff793c6add2266..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_ImageLine_20_20_2.tif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4cad44c6c8ce5abf0bc63b1ce688334acb363b68ecf73f8830b4e3670e4b4dbf
-size 518
diff --git a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_Line_20_10_2.1.png b/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_Line_20_10_2.1.png
deleted file mode 100644
index 339cd2f845893ede4c3547d21c70143f22db10c3..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_Line_20_10_2.1.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:fdeea5daa6ff8b2fd5656d0d3a529ebbc84d2fe2380dd3d7af2bb70e2837938a
-size 539
diff --git a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_Line_20_10_2.png b/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_Line_20_10_2.png
deleted file mode 100644
index 824c8191bdb90fbd0b7d5c5514b62e83fbbdc835..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feFiltreLocalHoughDraw_Line_20_10_2.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0fb3004f3c97f142fdcc86b7609c611f761ed1b3ac99e3c6ce82e0ad48a0ff99
-size 548
diff --git a/Data/Baseline/OTB/Images/feTvFillGapfilter.png b/Data/Baseline/OTB/Images/feTvFillGapfilter.png
deleted file mode 100644
index 4d7cc4b6090786088154021fdf52953904aba934..0000000000000000000000000000000000000000
--- a/Data/Baseline/OTB/Images/feTvFillGapfilter.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bbfa27dd4184a504e9bdfab422715f20c108270fdf2c29c313d641630bd2cd95
-size 280
diff --git a/Data/Baseline/OTB/Images/ioImageFileReaderExtendedFileName_Skipgeom_pr.1.txt b/Data/Baseline/OTB/Images/ioImageFileReaderExtendedFileName_Skipgeom_pr.1.txt
new file mode 100644
index 0000000000000000000000000000000000000000..09e380316b635e512aeda735d377368184b9403c
--- /dev/null
+++ b/Data/Baseline/OTB/Images/ioImageFileReaderExtendedFileName_Skipgeom_pr.1.txt
@@ -0,0 +1,15 @@
+ProjRef: GEOGCS["WGS 84",
+    DATUM["WGS_1984",
+        SPHEROID["WGS 84",6378137,298.257223563,
+            AUTHORITY["EPSG","7030"]],
+        AUTHORITY["EPSG","6326"]],
+    PRIMEM["Greenwich",0,
+        AUTHORITY["EPSG","8901"]],
+    UNIT["degree",0.0174532925199433,
+        AUTHORITY["EPSG","9122"]],
+    AXIS["Latitude",NORTH],
+    AXIS["Longitude",EAST],
+    AUTHORITY["EPSG","4326"]]
+Origin: [1943.5, 2364.5]
+Spacing: [1, 1]
+
diff --git a/Data/Input/pointSet.png b/Data/Input/pointSet.png
index 1b006e4232561e958c1cfefbfeb13739ea9b5b8a..79c87a7648a5d2bb363ae607b4fb1141ab775f68 100644
--- a/Data/Input/pointSet.png
+++ b/Data/Input/pointSet.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:f4f74ea5af34eec2f36f0f393fcc061ff91f3e7e08343a179439319f9c5406eb
-size 746
+oid sha256:14edc20c18435114c76bde6445ac53b1b48888adaaadabf9ddc615a4fc446603
+size 672
diff --git a/Data/Input/training/training.dbf b/Data/Input/training/training.dbf
new file mode 100755
index 0000000000000000000000000000000000000000..a801689ad76cfb40daf088a0bbe460ca043e4f8c
--- /dev/null
+++ b/Data/Input/training/training.dbf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:88650d26df9784caadaa9684ba37473544b2f131588a6ed155dec6cb3a750caf
+size 583257
diff --git a/Data/Input/training/training.prj b/Data/Input/training/training.prj
new file mode 100755
index 0000000000000000000000000000000000000000..5adb2a9108a4bd847464a2c506a40c8d199faa69
--- /dev/null
+++ b/Data/Input/training/training.prj
@@ -0,0 +1 @@
+PROJCS["RGF93_Lambert_93",GEOGCS["GCS_RGF93",DATUM["D_RGF_1993",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["Meter",1]]
\ No newline at end of file
diff --git a/Data/Input/training/training.shp b/Data/Input/training/training.shp
new file mode 100755
index 0000000000000000000000000000000000000000..730c51d1df89bdbefd3067f484c9cc8f9cfe1bca
--- /dev/null
+++ b/Data/Input/training/training.shp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e1c17dff62d346c046ed85418814db4b19f52fcb14001ae268f3e3468386d265
+size 2454248
diff --git a/Data/Input/training/training.shx b/Data/Input/training/training.shx
new file mode 100755
index 0000000000000000000000000000000000000000..af9e2a01dcbb8bb2b12eb27c20a24c2d2e3b2262
--- /dev/null
+++ b/Data/Input/training/training.shx
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c72e6f244e74a6088669aedd8ef7b6b3df757e981ee76883a2c0b4402d1a3ca5
+size 39972
diff --git a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
index 5cb3224bc01e41a3a1df7511dd28f1c5b050f722..5755cf1aec0b2c8a95e23167dab4866b828bec5e 100755
--- a/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
+++ b/Documentation/Cookbook/Scripts/otbGenerateWrappersRstDoc.py
@@ -83,9 +83,12 @@ def GetApplicationExamplePythonSnippet(app,idx,expand = False, inputpath="",outp
         paramtype = app.GetParameterType(param)
         paramrole = app.GetParameterRole(param)
         if paramtype == ParameterType_ListView:
-            break # TODO
+            if app.GetListViewSingleSelectionMode(param):
+                output += "\t" + appname + ".SetParameterString("+EncloseString(param)+", "+EncloseString(value)+")"
+            else:
+                output += "\t" + appname + ".SetParameterStringList("+EncloseString(param)+", "+EncloseString(value)+")"
         if paramtype == ParameterType_Group:
-            break # TODO
+            pass
         if paramtype ==  ParameterType_Choice:
             #app.SetParameterString(param,value)
             output+= "\t" + appname + ".SetParameterString(" + EncloseString(param) + "," + EncloseString(value) + ")"
diff --git a/Documentation/Cookbook/rst/CompilingOTBFromSource.rst b/Documentation/Cookbook/rst/CompilingOTBFromSource.rst
index 84dccaaf529465b0f31124b78401f8e5f0e3c593..9ea5c820ebd1d3b2fa6083f2fd9ec5afd0532c72 100644
--- a/Documentation/Cookbook/rst/CompilingOTBFromSource.rst
+++ b/Documentation/Cookbook/rst/CompilingOTBFromSource.rst
@@ -196,6 +196,12 @@ of all our dependencies on `the Orfeo ToolBox website
 <https://www.orfeo-toolbox.org/packages>`_ (pick the ’SuperBuild-archives’
 corresponding to the OTB version you want to build).
 
+**Notes about GDAL:** Since OTB 7.0, SuperBuild's GDAL version is 2.4.1. This version needs pkg-config to correctly find OpenJPEG (needed to read and write images with formats such as .jp2, .j2k), the minimal version is 0.21 for GDAL 2.4.1. You can install it with:
+
+::
+
+    apt-get install pkg-config
+
 **Notes about Qt:** Unlike other dependencies, building Qt5 on all platforms is
 not a trivial task but OTB SuperBuild does its best to facilitate this for the
 user. So there is still some additional package installation, one has to do as a
diff --git a/Documentation/Cookbook/rst/PythonAPI.rst b/Documentation/Cookbook/rst/PythonAPI.rst
index 6f61f1b4084faebb6cc1f94b459c82c34567b148..b299082dd861557999a75038a089c99cb38077a4 100644
--- a/Documentation/Cookbook/rst/PythonAPI.rst
+++ b/Documentation/Cookbook/rst/PythonAPI.rst
@@ -218,6 +218,68 @@ implementation does not break it, for instance by using an internal
 writer to write intermediate data. In this case, execution should
 still be correct, but some intermediate data will be read or written.
 
+Mixed in-memory / on-disk connection
+------------------------------------
+
+As an extension to the connection of OTB Applications (described in previous
+section), a mixed mode is also available to easily switch between:
+
+- **in-memory**: if you want to avoid unecessary I/O between applications
+- **on-disk**: if you want intermediate outputs on disk
+
+This mixed mode is based on the ``Application::ConnectImage()`` function. This
+is how you use it:
+
+.. code-block:: python
+
+    # for in-memory mode
+    app1 = otb.Registry.CreateApplication("Smoothing")
+    app2 = otb.Registry.CreateApplication("Smoothing")
+    
+    app1.IN = input_image
+    
+    app2.ConnectImage("in", app1, "out")
+    app2.OUT = output_image
+    app2.ExecuteAndWriteOutput()
+
+Comparing with the standard in-memory connection, you can notice that:
+
+- the syntax to do the connection is simpler
+- you don't need to call ``Execute()`` on upstream applications anymore,
+  this is done recursively by calling ``ExecuteAndWriteOutput()`` on the latest
+  application
+
+The on-disk version of this code is very similar:
+
+.. code-block:: python
+
+    # for on-disk mode
+    app1 = otb.Registry.CreateApplication("Smoothing")
+    app2 = otb.Registry.CreateApplication("Smoothing")
+    
+    app1.IN = input_image
+    app1.OUT = temp_image
+    
+    app2.ConnectImage("in", app1, "out")
+    app2.OUT = output_image
+    app2.PropagateConnectMode(False)
+    app2.ExecuteAndWriteOutput()
+
+The function ``PropagateConnectMode()`` is applied recursively in the upstream
+applications. It allows to change between the 2 modes:
+
+- ``True`` : means in-memory mode (this is the default)
+- ``False`` : means on-disk mode
+
+When you want to use the on-disk mode, you have to specify the path to
+the intermediate image in the **output** image parameter of the upstream
+application (``app1.OUT`` in the previous example). If this path is empty, the
+in-memory mode is used as fallback.
+
+This feature also works for ``InputImageList``. Calling the function
+``ConnectImage("il", app1, "out")``, with ``il`` being an input image list, will
+append a new image to the list, and connect it to output parameter ``out``.
+
 Load and save parameters to XML
 -------------------------------
 
@@ -341,6 +403,7 @@ Here is a small example of what can be done:
 .. code-block:: python
 
   import otbApplication as otb
+  from sys import argv
   
   # Create a smoothing application
   app = otb.Registry.CreateApplication("Smoothing")
@@ -354,7 +417,8 @@ Here is a small example of what can be done:
   myRegion = otb.itkRegion()
   myRegion['size'][0] = 20
   myRegion['size'][1] = 25
-  myRegion['index'].Fill(10)
+  myRegion['index'][0] = 10
+  myRegion['index'][1] = 10
   ram = app.PropagateRequestedRegion("out",myRegion)
   
   # Check the requested region on the input image
@@ -387,43 +451,10 @@ happens, this documentation will report the OTB version that fixes the issue.
 Calling UpdateParameters()
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-These wrappers are made as a mirror of the C++ API, so there is a function
-``UpdateParameters()``. Its role is to update parameters that depend on others.
-It is called at least once at the beginning of ``Execute()``.
-
-In command line and GUI launchers, this functions gets called each time a
-parameter of the application is modified. In Python, this mechanism is not
-automated: there are cases where you may have to call it yourself.
-
-Let's take an example with the application ``PolygonClassStatictics``. In this
-application, the choices available in the parameter ``field`` depend on the list
-of fields actually present in the vector file ``vec``. If you try to set the
-parameters ``vec`` and ``field``, you will get an error:
-
-.. code-block:: python
-
-    import otbApplication as otb
-    app = otb.Registry.CreateApplication("PolygonClassStatistics")
-    app.SetParameterString("vec","../../src/OTB-Data/Input/Classification/variousVectors.sqlite")
-    app.SetParameterString("field", "label")
-
-::
-
-  Traceback (most recent call last):
-    File "<stdin>", line 1, in <module>
-    File "/home/gpasero/Projet_OTB/build/OTB/lib/otb/python/otbApplication.py", line 897, in SetParameterString
-      def SetParameterString(self, *args): return _otbApplication.Application_SetParameterString(self, *args)
-  RuntimeError: Exception thrown in otbApplication Application_SetParameterString: /home/gpasero/Projet_OTB/src/OTB/Modules/Wrappers/ApplicationEngine/src/otbWrapperListViewParameter.cxx:141:
-  itk::ERROR: ListViewParameter(0x149da10): Cannot find label
-
-The error says that the choice ``label`` is not recognized, because ``UpdateParameters()``
-was not called after setting the vector file. The solution is to call it before
-setting the ``field`` parameter:
-
-.. code-block:: python
-
-    app.UpdateParameters()
-    app.SetParameterString("field", "label")
+``UpdateParameters()`` is available to the Python API. But in normal use, it
+does not need to be called manually. From OTB 7.0.0 and later, it is called
+automatically after each call to ``SetParameter*()`` methods. With previous versions
+of OTB you may need to call it after setting a parameter.
 
 No metadata in NumPy arrays
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Documentation/Cookbook/rst/recipes/featextract.rst b/Documentation/Cookbook/rst/recipes/featextract.rst
index 23267e65276dc6d011b2a4967ff2dc73bf335792..64eea1135b99651510c300a8a0adbbaaed4b05f8 100644
--- a/Documentation/Cookbook/rst/recipes/featextract.rst
+++ b/Documentation/Cookbook/rst/recipes/featextract.rst
@@ -36,10 +36,10 @@ The application can be used like this:
 
 ::
 
-    otbcli_LocalStatisticExtraction  -in        InputImage
+    otbcli_LocalStatisticExtraction  -in        InputImage.tif
                                      -channel   1
                                      -radius    3
-                                     -out       OutputImage
+                                     -out       OutputImage.tif
 
 Edge extraction
 ---------------
diff --git a/Documentation/Cookbook/rst/recipes/residual_registration.rst b/Documentation/Cookbook/rst/recipes/residual_registration.rst
index aeb8615cba67ba0e3550a3e2611ddd84f1cdbcb0..435e1846fc9af11033e9649187b064e84eaee1b0 100644
--- a/Documentation/Cookbook/rst/recipes/residual_registration.rst
+++ b/Documentation/Cookbook/rst/recipes/residual_registration.rst
@@ -29,7 +29,7 @@ register two images. This process can be easily extended to perform
 image series registration.
 
 The aim of this example is to describe how to register a Level 1
-QuickBird image over an orthorectify Pleiades image over the area of
+QuickBird image over an orthorectified Pleiades image over the area of
 Toulouse, France.
 
 |image1| |image2| 
@@ -40,35 +40,30 @@ Extract metadata from the image reference
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 We first dump geometry metadata of the image we want to refine in a text
-file. In OTB, we use the extension *.geom* for this type of file. As you
-will see the application which will estimate a refine geometry only
+file. In OTB, we use the extension *.geom* for this type of file.
+The application to estimate a refined geometry only
 needs as input this metadata and a set of homologous points. The
 refinement application will create a new *.geom* file containing refined
 geometry parameters which can be used after for reprojection for
 example.
 
-The use of external *.geom* file is available in OTB since release
-:math:`3.16`. See
-`here <http://wiki.orfeo-toolbox.org/index.php/ExtendedFileName>`__ for
-more information.
+External *.geom* files can also be used with :ref:`extended filenames<extended-filenames>`.
 
 ::
 
-
-    otbcli_ReadImageInfo   -in slave_image
-                           -outkwl TheGeom.geom
+    otbcli_ReadImageInfo -in slave_image
+                         -outkwl TheGeom.geom
 
 Extract homologous points from images
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The main idea of the residual registration is to estimate an second
+The main idea of the residual registration is to estimate a second
 transformation (after the application of sensors model).
+The homologous point application uses an interest point detection method to
+get a set of points with matches in both images.
 
-The homologous point application use interest point detection method to
-get a set of point which match in both images.
-
-The basic idea is to use this set of homologous points and estimate with
-them a residual transformation between the two images.
+The basic idea is to use this set of homologous points to estimate 
+a residual transformation between the two images.
 
 There is a wide variety of keypoint detectors in the literature, and they 
 allow for the detection and description of local features in images. These algorithms
diff --git a/Examples/ChangeDetection/test/CMakeLists.txt b/Examples/ChangeDetection/test/CMakeLists.txt
index e2306923885f4497235e3270453439b7932ffe21..76d9eada21561b1525a114164018ae8f2c69e28f 100644
--- a/Examples/ChangeDetection/test/CMakeLists.txt
+++ b/Examples/ChangeDetection/test/CMakeLists.txt
@@ -83,5 +83,5 @@ otb_add_test(NAME cdTeKullbackLeiblerProfileChDetTest COMMAND ${OTB_TEST_DRIVER}
     ${INPUTDATA}/GomaAvant.png
     ${INPUTDATA}/GomaApres.png
     ${TEMP}/KullbackLeiblerProfileChDetTest.png
-    5 51 1 12 24
+    5 30 1 6 12
 )
diff --git a/Examples/Radiometry/CMakeLists.txt b/Examples/Radiometry/CMakeLists.txt
index 48af7c1d8fb654efb198553c3b648b932073c558..edb63b4c9677736cfc944e776943440b5562f012 100644
--- a/Examples/Radiometry/CMakeLists.txt
+++ b/Examples/Radiometry/CMakeLists.txt
@@ -27,6 +27,11 @@ target_link_libraries(ARVIMultiChannelRAndBAndNIRVegetationIndexImageFilter ${OT
 if(OTB6S_LOADED)
 add_executable(AtmosphericCorrectionSequencement AtmosphericCorrectionSequencement.cxx)
 target_link_libraries(AtmosphericCorrectionSequencement ${OTB_LIBRARIES})
+if(MSVC)
+  set_target_properties(AtmosphericCorrectionSequencement PROPERTIES LINK_FLAGS "/STACK:10000000")
+elseif(MINGW)
+  set_target_properties(AtmosphericCorrectionSequencement PROPERTIES LINK_FLAGS "-Wl,--stack,10000000")
+endif()
 endif()
 
 add_executable(AVIMultiChannelRAndGAndNIRVegetationIndexImageFilter AVIMultiChannelRAndGAndNIRVegetationIndexImageFilter.cxx)
diff --git a/Modules/Adapters/CurlAdapters/src/otbCurlHelper.cxx b/Modules/Adapters/CurlAdapters/src/otbCurlHelper.cxx
index fc47583a39d2d3b6e03d5821ee0971b070abf494..6b9a27b731665c595b78dc8b50ac1c29f7794a23 100644
--- a/Modules/Adapters/CurlAdapters/src/otbCurlHelper.cxx
+++ b/Modules/Adapters/CurlAdapters/src/otbCurlHelper.cxx
@@ -185,7 +185,7 @@ public:
   }
 
 protected:
-  CurlFileDescriptorResource(){}
+  CurlFileDescriptorResource(): m_File(nullptr) {}
 
   ~CurlFileDescriptorResource() override
   {
@@ -195,9 +195,9 @@ protected:
 private:
   FILE *      m_File;
 
-  // prevent copying and assignment; not implemented
-  CurlFileDescriptorResource (const CurlFileDescriptorResource &);
-  CurlFileDescriptorResource & operator= (const CurlFileDescriptorResource &);
+  // prevent copying and assignment
+  CurlFileDescriptorResource (const CurlFileDescriptorResource &) = delete;
+  CurlFileDescriptorResource & operator= (const CurlFileDescriptorResource &) = delete;
 }; //end of class FileResource
 
 #endif // OTB_USE_CURL
diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRFieldWrapper.hxx b/Modules/Adapters/GdalAdapters/include/otbOGRFieldWrapper.hxx
index 2f1fb0596102830698b677c3514b1dd283d94d34..8adb1a2709286d623f14496743f04e6e32557aec 100644
--- a/Modules/Adapters/GdalAdapters/include/otbOGRFieldWrapper.hxx
+++ b/Modules/Adapters/GdalAdapters/include/otbOGRFieldWrapper.hxx
@@ -451,7 +451,6 @@ T otb::ogr::Field::GetValue() const
   typedef typename boost::mpl::at<internal::FieldType_Map, T>::type Kind;
   //const int VALUE = Kind::value;
   BOOST_STATIC_ASSERT(!(boost::is_same<Kind, boost::mpl::void_>::value));
-  assert(m_Definition.GetType() == Kind::value && "OGR field type mismatches the type of requested field value");
   typedef typename boost::mpl::at<internal::FieldGetters_Map, Kind>::type GetterType;
   // If you experience a static assertion failure in the line below, it means
   // the field cannot be extracted into the type requested.
diff --git a/Modules/Adapters/GdalAdapters/include/otbSpatialReference.h b/Modules/Adapters/GdalAdapters/include/otbSpatialReference.h
index 5cdc3ac46519f4e7ceb6e5493fbc5caef3d2fe0d..68c659dcfe339922cd68259880b19a82acf12335 100644
--- a/Modules/Adapters/GdalAdapters/include/otbSpatialReference.h
+++ b/Modules/Adapters/GdalAdapters/include/otbSpatialReference.h
@@ -21,6 +21,7 @@
 #define otbSpatialReference_h
 
 #include "OTBGdalAdaptersExport.h"
+#include "ogr_spatialref.h"
 
 #include <memory>
 #include <string>
@@ -150,6 +151,14 @@ public:
    */
   unsigned int ToEPSG() const;
 
+#if GDAL_VERSION_NUM >= 3000000
+  /** Set the Axis mapping strategy
+   * proxy to the eponym ogr spatial reference method
+   * \param strategy Axis mapping stategy
+   */
+  void SetAxisMappingStrategy(OSRAxisMappingStrategy strategy);
+#endif
+
   /**
    * Find which UTM zone a given (lat,lon) point falls in.
    * \pre -180<=lon<=180
diff --git a/Modules/Adapters/GdalAdapters/src/otbSpatialReference.cxx b/Modules/Adapters/GdalAdapters/src/otbSpatialReference.cxx
index 19958c297110bb1920f4f547686e6dcfdb0daa14..fa7259e85003baf9a1938d21ae3d077e34a18229 100644
--- a/Modules/Adapters/GdalAdapters/src/otbSpatialReference.cxx
+++ b/Modules/Adapters/GdalAdapters/src/otbSpatialReference.cxx
@@ -291,4 +291,12 @@ void SpatialReference::UTMFromGeoPoint(double lon, double lat, unsigned int & zo
   // post conditions
   assert(zone<=60);
 }
+
+#if GDAL_VERSION_NUM >= 3000000
+void SpatialReference::SetAxisMappingStrategy(OSRAxisMappingStrategy strategy)
+{
+  m_SR.get()->SetAxisMappingStrategy(strategy);
+};
+#endif
+
 }
diff --git a/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx b/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx
index 6b6e55539e049d637baa59a75a8ac51794b61cc6..756ea62890030193ea0b2291b78a44b078a7d587 100644
--- a/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx
+++ b/Modules/Applications/AppClassification/app/otbComputeConfusionMatrix.cxx
@@ -110,7 +110,7 @@ private:
 
   // Documentation
   SetDocLongDescription("This application computes the confusion matrix of a classification map relative to a ground truth dataset. "
-      "This ground truth can be given as a raster or a vector data. Only reference and produced pixels with values different "
+      "The ground truth can be provided as either a raster or a vector data. Only reference and produced pixels with values different "
       "from NoData are handled in the calculation of the confusion matrix. The confusion matrix is organized the following way: "
       "rows = reference labels, columns = produced labels. In the header of the output file, the reference and produced class labels "
       "are ordered according to the rows/columns of the confusion matrix.");
@@ -149,21 +149,21 @@ private:
   SetParameterDescription("ref.vector.field","Field name containing the label values");
   SetListViewSingleSelectionMode("ref.vector.field",true);
   
-  AddParameter(ParameterType_Int,"ref.raster.nodata","Value for nodata pixels in ref raster");
+  AddParameter(ParameterType_Int,"ref.raster.nodata","Value for nodata pixels in the reference raster");
   SetDefaultParameterInt("ref.raster.nodata",0);
-  SetParameterDescription("ref.raster.nodata","Label to be treated as no data in ref raster.");
+  SetParameterDescription("ref.raster.nodata","Label to be treated as nodata in the reference raster.");
   MandatoryOff("ref.raster.nodata");
   DisableParameter("ref.raster.nodata");
 
-  AddParameter(ParameterType_Int,"ref.vector.nodata","Value for nodata pixels in ref vector");
+  AddParameter(ParameterType_Int,"ref.vector.nodata","Value for nodata pixels in the reference vector");
   SetDefaultParameterInt("ref.vector.nodata",0);
-  SetParameterDescription("ref.vector.nodata","Label to be treated as no data in ref vector. Please note that this value is always used in vector mode, to generate default values. Please set it to a value that does not correspond to a class label.");
+  SetParameterDescription("ref.vector.nodata","Label to be treated as nodata in the reference vector. Please note that this value is always used in vector mode, to generate default values. Please set it to a value that does not correspond to a class label.");
   MandatoryOff("ref.vector.nodata");
   DisableParameter("ref.vector.nodata");
 
 
-  AddParameter(ParameterType_Int,"nodatalabel","Value for nodata pixels in input image");
-  SetParameterDescription("nodatalabel","Label to be treated as no data in input image");
+  AddParameter(ParameterType_Int,"nodatalabel","Value for nodata pixels in the input image");
+  SetParameterDescription("nodatalabel","Label to be treated as nodata in the input image");
   SetDefaultParameterInt("nodatalabel",0);
   
   MandatoryOff("nodatalabel");
diff --git a/Modules/Applications/AppClassification/app/otbComputeOGRLayersFeaturesStatistics.cxx b/Modules/Applications/AppClassification/app/otbComputeOGRLayersFeaturesStatistics.cxx
index c8b721a62b32d6cc73b19633b9f9b3adcc8830a7..647d1982e0c3f64a9db298ad1970b59a20c60ba2 100644
--- a/Modules/Applications/AppClassification/app/otbComputeOGRLayersFeaturesStatistics.cxx
+++ b/Modules/Applications/AppClassification/app/otbComputeOGRLayersFeaturesStatistics.cxx
@@ -51,7 +51,7 @@ private:
     SetName("ComputeOGRLayersFeaturesStatistics");
     SetDescription("Compute statistics of the features in a set of OGR Layers");
 
-    SetDocLongDescription("Compute statistics (mean and standard deviation) of the features in a set of OGR Layers, and write them in an XML file. This XML file can then be used by the training application.");
+    SetDocLongDescription("Compute statistics (mean and standard deviation) of the features in a set of OGR Layers, and write them in an XML file. The resulting XML file can then be used by the training application.");
     SetDocLimitations("Experimental. For now only shapefiles are supported.");
     SetDocAuthors("David Youssefi during internship at CNES");
     SetDocSeeAlso("OGRLayerClassifier,TrainVectorClassifier");
diff --git a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
index e7a45871aed3263db1c0530ef3b5507737317380..1900c8e416fbcfb3295891b03d1bac06bf4f11b0 100644
--- a/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbImageClassifier.cxx
@@ -80,9 +80,9 @@ private:
     SetDescription("Performs a classification of the input image according to a model file.");
 
     // Documentation
-    SetDocLongDescription("This application performs an image classification based on a model file produced by the TrainImagesClassifier application. Pixels of the output image will contain the class labels decided by the classifier (maximal class label = 65535). The input pixels can be optionally centered and reduced according to the statistics file produced by the ComputeImagesStatistics application. An optional input mask can be provided, in which case only input image pixels whose corresponding mask value is greater than 0 will be classified. By default, the remaining of pixels will be given the label 0 in the output image.");
+    SetDocLongDescription("This application performs an image classification based on a model file produced by the TrainImagesClassifier application. Pixels of the output image will contain the class labels decided by the classifier (maximal class label = 65535). The input pixels can be optionally centered and reduced according to the statistics file produced by the ComputeImagesStatistics application. An optional input mask can be provided, in which case only input image pixels whose corresponding mask value is greater than 0 will be classified. By default, the remaining pixels will be given the label 0 in the output image.");
 
-    SetDocLimitations("The input image must have the same type, order and number of bands than the images used to produce the statistics file and the SVM model file. If a statistics file was used during training by the TrainImagesClassifier, it is mandatory to use the same statistics file for classification. If an input mask is used, its size must match the input image size.");
+    SetDocLimitations("The input image must have the same type, order and number of bands as the images used to produce the statistics file and the SVM model file. If a statistics file was used during training by the TrainImagesClassifier, it is mandatory to use the same statistics file for classification. If an input mask is used, its size must match the input image size.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("TrainImagesClassifier, ValidateImagesClassifier, ComputeImagesStatistics");
 
@@ -92,21 +92,21 @@ private:
     SetParameterDescription( "in", "The input image to classify.");
 
     AddParameter(ParameterType_InputImage,  "mask",   "Input Mask");
-    SetParameterDescription( "mask", "The mask allows restricting classification of the input image to the area where mask pixel values are greater than 0.");
+    SetParameterDescription( "mask", "The mask restricts the classification of the input image to the area where mask pixel values are greater than 0.");
     MandatoryOff("mask");
 
     AddParameter(ParameterType_InputFilename, "model", "Model file");
     SetParameterDescription("model", "A model file (produced by TrainImagesClassifier application, maximal class label = 65535).");
 
     AddParameter(ParameterType_InputFilename, "imstat", "Statistics file");
-    SetParameterDescription("imstat", "A XML file containing mean and standard deviation to center and reduce samples before classification (produced by ComputeImagesStatistics application).");
+    SetParameterDescription("imstat", "An XML file containing mean and standard deviation to center and reduce samples before classification (produced by ComputeImagesStatistics application).");
     MandatoryOff("imstat");
 
     AddParameter(ParameterType_Int, "nodatalabel", "Label mask value");
     SetParameterDescription("nodatalabel", "By default, "
       "hidden pixels will have the assigned label 0 in the output image. "
-      "It's possible to define the label mask by another value, "
-      "but be careful to not take a label from another class (max. 65535).");
+      "It is possible to define the label mask by another value, "
+      "but be careful not to use a label from another class (max. 65535).");
 
     SetDefaultParameterInt("nodatalabel", 0);
     MandatoryOff("nodatalabel");
@@ -137,7 +137,7 @@ private:
 
     AddParameter(ParameterType_Int, "nbclasses", "Number of classes in the model");
     SetDefaultParameterInt("nbclasses", 20);
-    SetParameterDescription("nbclasses","The number of classes is needed for the probamap output in order to set the number of output bands.");
+    SetParameterDescription("nbclasses","The number of classes is required by the output of the probability map in order to set the number of output bands.");
    
    // Doc example parameter settings
     SetDocExampleParameterValue("in", "QB_1_ortho.tif");
diff --git a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
index 0ceba570e9bfe6706231ba91d8bf750f3c36fbcb..5eec689e80194642584dd54e09a64b073f60d14d 100644
--- a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
+++ b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
@@ -59,7 +59,7 @@ protected:
     InitKMClassification();
 
     // init at the end cleanup
-    AddParameter( ParameterType_Bool, "cleanup", "Temporary files cleaning" );
+    AddParameter( ParameterType_Bool, "cleanup", "Clean-up of temporary files" );
     SetParameterDescription( "cleanup",
                            "If activated, the application will try to clean all temporary files it created" );
     SetParameterInt("cleanup", 1);
@@ -119,7 +119,7 @@ protected:
       "By default, hidden pixels will have the assigned label 0 in the output image. "
       "It's possible to define the label mask by another value, "
       "but be careful to not take a label from another class. "
-      "This application initialize the labels from 0 to N-1, "
+      "This application initializes the labels from 0 to N-1, "
       "N is the number of class (defined by 'nc' parameter).");
   }
 
@@ -387,12 +387,12 @@ private:
         "6) TrainVectorClassifier: train the SharkKMeans model,\n"
         "7) ImageClassifier: perform the classification of the input image "
             "according to a model file.\n\n"
-        "It's possible to choice random/periodic modes of the SampleSelection application.\n"
-        "If you want keep the temporary files (sample selected, model file, ...), "
+        "It is possible to choose random/periodic modes of the SampleSelection application.\n"
+        "If you do not want to keep the temporary files (sample selected, model file, ...), "
         "initialize cleanup parameter.\n"
         "For more information on shark KMeans algorithm [1].");
 
-    SetDocLimitations("The application doesn't support NaN in the input image");
+    SetDocLimitations("The application does not support NaN in the input image");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("ImageEnvelope, PolygonClassStatistics, SampleSelection, SampleExtraction, "
       "PolygonClassStatistics, TrainVectorClassifier, ImageClassifier.\n\n"
diff --git a/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx b/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx
index eecf74ed45b38c57bde61331f92f3d0eeebd11f5..af1a1d0402b965650d28747d95a3cb235903be37 100644
--- a/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx
+++ b/Modules/Applications/AppClassification/app/otbMultiImageSamplingRate.cxx
@@ -79,9 +79,9 @@ private:
       "input CSV file (first column is class name, second one is the required "
       "samples number).\n\n"
       "The multi-image modes (mim) are proportional, equal and custom. The custom "
-      "mode lets the users choose the distribution of samples among the "
+      "mode lets the user choose the distribution of samples among the "
       "images. The different behaviours are described below. Ti(c) and Ni(c) "
-      " refers resp. to the total number and needed number of samples in "
+      " refers respectively to the total number and needed number of samples in "
       "image i for class c. Let's call L the total number of images.\n\n"
       "* strategy = all\n\n"
       "    - Same behaviour for all modes: take all samples\n\n"
@@ -160,8 +160,8 @@ private:
     AddParameter(ParameterType_String,"strategy.total.v","The number of samples to generate");
     SetParameterDescription("strategy.total.v","The number of samples to generate" "In the case of the custom multi-image mode, several values can be given for each image.");
  
-    AddChoice("strategy.all","Take all samples");
-    SetParameterDescription("strategy.all","Take all samples");
+    AddChoice("strategy.all","Use all samples");
+    SetParameterDescription("strategy.all","Use all samples");
 
     // Default strategy : smallest
     SetParameterString("strategy","smallest");
@@ -169,13 +169,13 @@ private:
     AddParameter(ParameterType_Choice, "mim", "Multi-Image Mode");
 
     AddChoice("mim.proportional", "Proportional");
-    SetParameterDescription("mim.proportional","Split proportionally the required number of samples");
+    SetParameterDescription("mim.proportional","Split the required number of samples proportionally");
 
     AddChoice("mim.equal", "equal");
-    SetParameterDescription("mim.equal","Split equally the required number of samples");
+    SetParameterDescription("mim.equal","Equal split of the required number of samples");
 
     AddChoice("mim.custom", "Custom");
-    SetParameterDescription("mim.custom","Split the required number of samples following user choice.");
+    SetParameterDescription("mim.custom","Split the number of samples based on the user's choice.");
 
     // Doc example parameter settings
     SetDocExampleParameterValue("il", "stats_1.xml stats_2.xml");
diff --git a/Modules/Applications/AppClassification/app/otbPredictRegression.cxx b/Modules/Applications/AppClassification/app/otbPredictRegression.cxx
index 886009b1fa1701fbc916194c01c468290f7dcdb0..b088810145126212e8c99ed904d1232c306c1f7c 100644
--- a/Modules/Applications/AppClassification/app/otbPredictRegression.cxx
+++ b/Modules/Applications/AppClassification/app/otbPredictRegression.cxx
@@ -150,7 +150,7 @@ private:
     // TODO : use CSV input/output ?
 
     AddParameter(ParameterType_InputImage,  "mask",   "Input Mask");
-    SetParameterDescription( "mask", "The mask allow restricting "
+    SetParameterDescription( "mask", "The mask restrict the "
       "classification of the input image to the area where mask pixel values "
       "are greater than 0.");
     MandatoryOff("mask");
@@ -160,10 +160,10 @@ private:
       "TrainRegression application).");
 
     AddParameter(ParameterType_InputFilename, "imstat", "Statistics file");
-    SetParameterDescription("imstat", "A XML file containing mean and standard"
+    SetParameterDescription("imstat", "An XML file containing mean and standard"
       " deviation to center and reduce samples before prediction "
       "(produced by ComputeImagesStatistics application). If this file contains"
-      "one more band than the sample size, the last stat of last band will be"
+      "one more band than the sample size, the last stat of the last band will be"
       "applied to expand the output predicted value");
     MandatoryOff("imstat");
 
diff --git a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx
index d789b556198a4c12f271e81daeeeec730b9ae894..c2bc93f144a79313db493355e1b39e024905d487 100644
--- a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx
+++ b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx
@@ -90,13 +90,13 @@ private:
         "The application selects a set of samples from geometries "
         "intended for training (they should have a field giving the associated "
         "class). \n\nFirst of all, the geometries must be analyzed by the PolygonClassStatistics application "
-        "to compute statistics about the geometries, which are summarized in an xml file. "
-        "\nThen, this xml file must be given as input to this application (parameter instats).\n\n"
+        "to compute statistics about the geometries, which are summarized in an XML file. "
+        "\nThen, this XML file must be given as an input to this application (parameter instats).\n\n"
         "The input support image and the input training vectors shall be given in "
         "parameters 'in' and 'vec' respectively. Only the sampling grid (origin, size, spacing)"
         "will be read in the input image.\n"
         "There are several strategies to select samples (parameter strategy) : \n\n"
-        "  - smallest (default) : select the same number of sample in each class"
+        "  - smallest (default) : select the same number of samples in each class"
         " so that the smallest one is fully sampled.\n"
         "  - constant : select the same number of samples N in each class"
         " (with N below or equal to the size of the smallest class).\n"
@@ -104,13 +104,13 @@ private:
         " (first column is class name, second one is the required samples number).\n\n"
         "  - percent: set a target global percentage of samples to use. Class proportions will be respected. \n\n"
         "  - total: set a target total number of samples to use. Class proportions will be respected. \n\n"
-        "There is also a choice on the sampling type to performs : \n\n"
+        "There is also a choice of the sampling type to perform: \n\n"
         "  - periodic : select samples uniformly distributed\n"
         "  - random : select samples randomly distributed\n\n"
         "Once the strategy and type are selected, the application outputs samples positions"
         "(parameter out).\n\n"
 
-        "The other parameters to look at are : \n\n"
+        "The other parameters to consider are: \n\n"
         "  - layer : index specifying from which layer to pick geometries.\n"
         "  - field : set the field name containing the class.\n"
         "  - mask : an optional raster mask can be used to discard samples.\n"
@@ -193,11 +193,11 @@ private:
     SetMinimumParameterIntValue("strategy.total.v",1);
     SetDefaultParameterInt("strategy.total.v",1000);
 
-    AddChoice("strategy.smallest","Set same number of samples for all classes, with the smallest class fully sampled");
-    SetParameterDescription("strategy.smallest","Set same number of samples for all classes, with the smallest class fully sampled");
+    AddChoice("strategy.smallest","Set the same number of samples for all classes, with the smallest class fully sampled");
+    SetParameterDescription("strategy.smallest","Set the same number of samples for all classes, with the smallest class fully sampled");
 
-    AddChoice("strategy.all","Take all samples");
-    SetParameterDescription("strategy.all","Take all samples");
+    AddChoice("strategy.all","Use all samples");
+    SetParameterDescription("strategy.all","Use all samples");
 
     // Default strategy : smallest
     SetParameterString("strategy","smallest");
@@ -306,7 +306,7 @@ private:
       // total
       case 3:
       {
-      otbAppLogINFO("Sampling strategy: set the total number of samples to generate, use classes proportions.");
+      otbAppLogINFO("Sampling strategy: set the total number of samples to generate, use class proportions.");
       m_RateCalculator->SetTotalNumberOfSamples(this->GetParameterInt("strategy.total.v"));
       }
       break;
@@ -321,7 +321,7 @@ private:
       // all samples
       case 5:
         {
-        otbAppLogINFO("Sampling strategy : take all samples");
+        otbAppLogINFO("Sampling strategy : use all samples");
         m_RateCalculator->SetAllSamples();
         }
       break;
diff --git a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
index 567dd28889ae03e3eda019b031e1344073bf12e0..c029f386c2073225feb22ae58f07a6f8f404661d 100644
--- a/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainImagesClassifier.cxx
@@ -49,8 +49,8 @@ public:
         "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 "
+        "Training and validation sample lists are built such that each class is equally represented in both lists. One parameter controlls the ratio "
+        "between the number of samples in training and validation sets. Two parameters manage 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"
@@ -62,7 +62,7 @@ public:
 
         "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.");
+        "ML model type chosen. There is no image or 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 ac1977b4da907d5a1f0910457c918e786084f714..b576735070fe35c01c0954bfa7de49d055a7f4a2 100644
--- a/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
@@ -106,7 +106,7 @@ void DoInit() override
 
   // Documentation
   SetDocLongDescription(
-    "This application trains a classifier from multiple input images or a csv "
+    "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\n"
@@ -131,7 +131,7 @@ void DoInit() override
   //Group IO
   AddParameter( ParameterType_Group , "io" , "Input and output data" );
   SetParameterDescription("io" , 
-    "This group of parameters allows setting input and output data." );
+    "This group of parameters set the input and output data." );
   AddParameter( ParameterType_InputImageList , "io.il", "Input Image List" );
   SetParameterDescription( "io.il" , 
     "A list of input images. First (n-1) bands should contain the predictor. "
@@ -163,7 +163,7 @@ void DoInit() override
   AddParameter( ParameterType_Group , "sample" , 
     "Training and validation samples parameters" );
   SetParameterDescription( "sample" ,
-    "This group of parameters allows you to set training and validation sample "
+    "This group of parameters allows one to set training and validation sample "
     "lists parameters." );
 
   AddParameter( ParameterType_Int , "sample.mt" , 
diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
index fbd04d4a4b5c0fa213d5266d3588b1f8de7202cb..343ac7cec8649e26eb42b36b3b9e8082a0d12999 100644
--- a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
@@ -65,7 +65,7 @@ protected:
       "classification.\nThis application is based on LibSVM, OpenCV Machine "
       "Learning (2.3.1 and later), and Shark ML The output of this application "
       "is a text model file, whose format corresponds to the ML model type "
-      "chosen. There is no image nor vector data output.");
+      "chosen. There are no image or vector data outputs created.");
     SetDocLimitations("None");
     SetDocAuthors( "OTB Team" );
     SetDocSeeAlso( " " );
diff --git a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
index c15b65b53d8db58f7b1ba692d99ada789f12a3f7..1f0401aeec3586afc10d2964d60c26fc665ef5df 100644
--- a/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbVectorClassifier.cxx
@@ -98,12 +98,12 @@ private:
       "(maximal class label = 65535). \n"
       "There are two modes: \n"
         "1) Update mode: add of the 'cfield' field containing the predicted class in the input file. \n"
-        "2) Write mode: copies the existing fields of the input file in the output file "
+        "2) Write mode: copies the existing fields of the input file to the output file "
            " and add the 'cfield' field containing the predicted class. \n"
       "If you have declared the output file, the write mode applies. "
       "Otherwise, the input file update mode will be applied.");
 
-    SetDocLimitations("Shapefiles are supported. But the SQLite format is only supported in update mode.");
+    SetDocLimitations("Shapefiles are supported, but the SQLite format is only supported in update mode.");
     SetDocSeeAlso("TrainVectorClassifier");
     AddDocTag(Tags::Learning);
 
@@ -215,8 +215,22 @@ private:
         // Beware that itemIndex differs from ogr layer field index
         unsigned int itemIndex = GetSelectedItems("feat")[idx];
         std::string fieldName = GetChoiceNames( "feat" )[itemIndex];
+        switch ((*it)[fieldName].GetType())
+        {
+        case OFTInteger:
+          mv[idx] = static_cast<ValueType>((*it)[fieldName].GetValue<int>());
+          break;
+        case OFTInteger64:
+          mv[idx] = static_cast<ValueType>((*it)[fieldName].GetValue<int>());
+          break;
+        case OFTReal:
+          mv[idx] = static_cast<ValueType>((*it)[fieldName].GetValue<double>());
+          break;
+        default:
+          itkExceptionMacro(<< "incorrect field type: " << (*it)[fieldName].GetType() << ".");
+        }
+        
         
-        mv[idx] = static_cast<ValueType>((*it)[fieldName].GetValue<double>());
         }
       input->PushBack(mv);
       }
@@ -369,7 +383,23 @@ private:
       ogr::Feature dstFeature(outLayer.GetLayerDefn());
       dstFeature.SetFrom( *it , TRUE);
       dstFeature.SetFID(it->GetFID());
-      dstFeature[classfieldname].SetValue<int>(target->GetMeasurementVector(count)[0]);
+      switch (dstFeature[classfieldname].GetType())
+        {
+        case OFTInteger:
+          dstFeature[classfieldname].SetValue<int>(target->GetMeasurementVector(count)[0]);
+          break;
+        case OFTInteger64:
+          dstFeature[classfieldname].SetValue<int>(target->GetMeasurementVector(count)[0]);
+          break;
+        case OFTReal:
+          dstFeature[classfieldname].SetValue<double>(target->GetMeasurementVector(count)[0]);
+          break;
+        case OFTString:
+          dstFeature[classfieldname].SetValue<std::string>(std::to_string(target->GetMeasurementVector(count)[0]));
+          break;
+        default:
+          itkExceptionMacro(<< "incorrect field type: " << dstFeature[classfieldname].GetType() << ".");
+        }
       if (computeConfidenceMap)
         dstFeature[confFieldName].SetValue<double>(quality->GetMeasurementVector(count)[0]);
       if (updateMode)
diff --git a/Modules/Applications/AppClassification/include/otbTrainVectorBase.h b/Modules/Applications/AppClassification/include/otbTrainVectorBase.h
index bc5c716aef98324bcd14882b451fc2636dbfe9cc..24b731cbd6b09ef5e81bb45388fddbcd43801ca3 100644
--- a/Modules/Applications/AppClassification/include/otbTrainVectorBase.h
+++ b/Modules/Applications/AppClassification/include/otbTrainVectorBase.h
@@ -65,7 +65,7 @@ public:
   typedef typename Superclass::SampleType           SampleType;
   typedef typename Superclass::ListSampleType       ListSampleType;
   typedef typename Superclass::TargetListSampleType TargetListSampleType;
-
+  
   typedef double ValueType;
   typedef itk::VariableLengthVector <ValueType> MeasurementType;
 
@@ -127,7 +127,10 @@ protected:
     {
       m_SelectedCFieldIdx = selectedCFieldIdx;
       // Handle only one class field name, if several are provided only the first one is used.
-      m_SelectedCFieldName = selectedCFieldIdx.empty() ? cFieldNames.front() : cFieldNames[selectedCFieldIdx.front()];
+      if (selectedCFieldIdx.empty())
+        m_SelectedCFieldName.clear();
+      else
+        m_SelectedCFieldName = cFieldNames[selectedCFieldIdx.front()];
     }
   };
 
@@ -185,12 +188,6 @@ protected:
   void DoInit() override;
   void DoUpdateParameters() override;
   void DoExecute() override;
-
-private:
-  /**
-   * Get the field of the input feature corresponding to the input field
-   */
-  inline TOutputValue GetFeatureField(const ogr::Feature& feature, int field);
 };
 
 }
diff --git a/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx b/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx
index c1e4f88f1cf9f428a038da63d99161e26daa9f66..eaaa8bee3189933a532c3c21abbde7a65dc77e87 100644
--- a/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainVectorBase.hxx
@@ -237,23 +237,6 @@ TrainVectorBase<TInputValue, TOutputValue>
   return measurement;
 }
 
-// Template specialization for the integer case (i.e.classification), to avoid a cast from double to integer
-template <>
-inline int
-TrainVectorBase<float, int>
-::GetFeatureField(const ogr::Feature & feature, int fieldIndex)
-{
-  return(feature[fieldIndex].GetValue<int>());
-}
-
-template <class TInputValue, class TOutputValue>
-inline TOutputValue
-TrainVectorBase<TInputValue, TOutputValue>
-::GetFeatureField(const ogr::Feature & feature, int fieldIndex)
-{
-  return(feature[fieldIndex].GetValue<double>());
-}
-
 template <class TInputValue, class TOutputValue>
 typename TrainVectorBase<TInputValue, TOutputValue>::SamplesWithLabel
 TrainVectorBase<TInputValue, TOutputValue>
@@ -310,12 +293,45 @@ TrainVectorBase<TInputValue, TOutputValue>
         MeasurementType mv;
         mv.SetSize( m_FeaturesInfo.m_NbFeatures );
         for( unsigned int idx = 0; idx < m_FeaturesInfo.m_NbFeatures; ++idx )
-          mv[idx] = feature[featureFieldIndex[idx]].GetValue<double>();
+        {
+          switch (feature[featureFieldIndex[idx]].GetType())
+          {
+          case OFTInteger:
+            mv[idx] = static_cast<ValueType>(feature[featureFieldIndex[idx]].GetValue<int>());
+            break;
+          case OFTInteger64:
+            mv[idx] = static_cast<ValueType>(feature[featureFieldIndex[idx]].GetValue<int>());
+            break;
+          case OFTReal:
+            mv[idx] = static_cast<ValueType>(feature[featureFieldIndex[idx]].GetValue<double>());
+            break;
+          default:
+            itkExceptionMacro(<< "incorrect field type: " << feature[featureFieldIndex[idx]].GetType() << ".");
+          }
+        }
 
         input->PushBack( mv );
 
         if(cFieldIndex>=0 && ogr::Field(feature,cFieldIndex).HasBeenSet())
-          target->PushBack(GetFeatureField(feature,cFieldIndex));
+        {
+          switch (feature[cFieldIndex].GetType())
+          {
+          case OFTInteger:
+            target->PushBack(static_cast<ValueType>(feature[cFieldIndex].GetValue<int>()));
+            break;
+          case OFTInteger64:
+            target->PushBack(static_cast<ValueType>(feature[cFieldIndex].GetValue<int>()));
+            break;
+          case OFTReal:
+            target->PushBack(static_cast<ValueType>(feature[cFieldIndex].GetValue<double>()));
+            break;
+          case OFTString:
+            target->PushBack(static_cast<ValueType>(std::stod(feature[cFieldIndex].GetValue<std::string>())));
+            break;
+          default:
+            itkExceptionMacro(<< "incorrect field type: " << feature[featureFieldIndex[cFieldIndex]].GetType() << ".");
+          }
+        }
         else
           target->PushBack( 0. );
 
diff --git a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx
index 44e961db2e5737455709b8a1cb6adfcca8a9fef5..d27c1e2019de888531ed707038aced05dc63c4ea 100644
--- a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx
+++ b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx
@@ -84,7 +84,7 @@ private:
   {
     SetName("HomologousPointsExtraction");
     SetDescription("Compute homologous points between images using keypoints");
-    SetDocLongDescription("This application allows computing homologous points between images using keypoints. "
+    SetDocLongDescription("This application computes homologous points between images using keypoints. "
       " SIFT or SURF keypoints can be used and the band on which keypoints are computed can be set independently for both images."
       " The application offers two modes:"
       " the first is the full mode where keypoints are extracted from the full extent of both images"
@@ -97,7 +97,7 @@ private:
       "The elevation parameters are to deal more precisely with sensor modelling in case of sensor geometry data. "
       "The outvector option allows creating a vector file with segments corresponding to the localisation error between the matches."
       " It can be useful to assess the precision of a registration for instance."
-      " The vector file is always reprojected to EPSG:4326 to allow display in a GIS."
+      " The vector file is always reprojected to EPSG:4326 so that it can be displayed in a GIS."
       " This is done via reprojection or by applying the image sensor models.");
     // Documentation
     SetDocLimitations("Full mode does not handle large images.");
@@ -150,7 +150,7 @@ private:
     SetParameterDescription("mode.full","Extract and match all keypoints, loading both images entirely into memory");
 
     AddChoice("mode.geobins","Search keypoints in small spatial bins regularly spread across first image");
-    SetParameterDescription("mode.geobins","This method allows retrieving a set of tie points regulary spread across image 1. Corresponding bins in image 2 are retrieved using sensor and geographical information if available. The first bin position takes into account the margin parameter. Bins are cropped to the largest image region shrunk by the margin parameter for both in1 and in2 images.");
+    SetParameterDescription("mode.geobins","This method retrieves a set of tie points regulary spread across image 1. Corresponding bins in image 2 are retrieved using sensor and geographical information if available. The first bin position takes into account the margin parameter. Bins are cropped to the largest image region shrunk by the margin parameter for both in1 and in2 images.");
 
     AddParameter(ParameterType_Int,"mode.geobins.binsize","Size of bin");
     SetParameterDescription("mode.geobins.binsize","Radius of the spatial bin in pixels");
diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
index 690f5887bf6d418cce6f23cab8d423b26832f2e6..cecb7e9045780d5011ed840afb4a4b679469c352 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
+++ b/Modules/Applications/AppDimensionalityReduction/app/otbDimensionalityReduction.cxx
@@ -89,7 +89,7 @@ private:
   {
     SetName("DimensionalityReduction");
     SetDescription("Perform Dimension reduction of the input image.");
-    SetDocLongDescription("Performs dimensionality reduction on input image. PCA,NA-PCA,MAF,ICA methods are available. It is also possible to compute the inverse transform to reconstruct the image. It is also possible to optionally export the transformation matrix to a text file.");
+    SetDocLongDescription("Performs dimensionality reduction on input image. PCA,NA-PCA,MAF,ICA methods are available. It is also possible to compute the inverse transform to reconstruct the image and to optionally export the transformation matrix to a text file.");
     SetDocLimitations("This application does not provide the inverse transform and the transformation matrix export for the MAF.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(
diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx
index 3258373e4e5d2801208c0f52170089f92ff4d7f6..eef3f474648e1ff29ad7b915bf52a286a68ad110 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx
+++ b/Modules/Applications/AppDimensionalityReduction/app/otbImageDimensionalityReduction.cxx
@@ -126,7 +126,7 @@ private:
   {
     SetName("ImageDimensionalityReduction");
     SetDescription("Performs dimensionality reduction of the input image "
-      "according to a dimensionality reduction model file.");
+      "based on a dimensionality reduction model file.");
 
     // Documentation
     SetDocLongDescription("This application reduces the dimension of an input"
@@ -162,7 +162,7 @@ private:
                             "TrainRegression application).");
 
     AddParameter(ParameterType_InputFilename, "imstat", "Statistics file");
-    SetParameterDescription("imstat", "A XML file containing mean and standard"
+    SetParameterDescription("imstat", "An XML file containing mean and standard"
       " deviation to center and reduce samples before prediction "
       "(produced by ComputeImagesStatistics application). If this file contains"
                             "one more bands than the sample size, the last stat of last band will be"
diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbTrainDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbTrainDimensionalityReduction.cxx
index d5ea4307e9ce7b46da59c1a4a9dcbe6f9de16519..78914ed6f878e9788aa854171148345bd06e6f41 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/otbTrainDimensionalityReduction.cxx
+++ b/Modules/Applications/AppDimensionalityReduction/app/otbTrainDimensionalityReduction.cxx
@@ -129,7 +129,9 @@ private:
       otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Read);
     otb::ogr::Layer layer = source->GetLayer(0);
     ListSampleType::Pointer input = ListSampleType::New();
-    const int nbFeatures = GetParameterStringList("feat").size();
+    
+    const auto inputIndexes = GetParameterStringList("feat");
+    const int nbFeatures = inputIndexes.size();
 
     input->SetMeasurementVectorSize(nbFeatures);
     otb::ogr::Layer::const_iterator it = layer.cbegin();
@@ -140,7 +142,20 @@ private:
       mv.SetSize(nbFeatures);
       for(int idx=0; idx < nbFeatures; ++idx)
         {
-        mv[idx] = (*it)[GetParameterStringList("feat")[idx]].GetValue<double>();
+        switch ((*it)[inputIndexes[idx]].GetType())
+        {
+          case OFTInteger:
+            mv[idx] = static_cast<ValueType>((*it)[inputIndexes[idx]].GetValue<int>());
+            break;
+          case OFTInteger64:
+            mv[idx] = static_cast<ValueType>((*it)[inputIndexes[idx]].GetValue<int>());
+            break;
+          case OFTReal:
+            mv[idx] = static_cast<ValueType>((*it)[inputIndexes[idx]].GetValue<double>());
+            break;
+          default:
+            itkExceptionMacro(<< "incorrect field type: " << (*it)[inputIndexes[idx]].GetType() << ".");
+        }
         }
       input->PushBack(mv);
       }
diff --git a/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx b/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx
index ab279f88451e0ded18335a4ef47c977832ffc562..2629ce715998a58b38902703e53d5e85d6889b46 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx
+++ b/Modules/Applications/AppDimensionalityReduction/app/otbVectorDimensionalityReduction.cxx
@@ -98,7 +98,7 @@ private:
     SetParameterDescription("in","The input vector data to reduce.");
 
     AddParameter(ParameterType_InputFilename, "instat", "Statistics file");
-    SetParameterDescription("instat", "A XML file containing mean and standard "
+    SetParameterDescription("instat", "An XML file containing mean and standard "
       "deviation to center and reduce samples before dimensionality reduction "
       "(produced by ComputeImagesStatistics application).");
     MandatoryOff("instat");
@@ -221,7 +221,20 @@ private:
       
       for(int idx=0; idx < nbFeatures; ++idx)
         {
-        mv[idx] = static_cast<float>( (*it)[inputIndexes[idx]].GetValue<double>() );
+        switch ((*it)[inputIndexes[idx]].GetType())
+        {
+          case OFTInteger:
+            mv[idx] = static_cast<ValueType>((*it)[inputIndexes[idx]].GetValue<int>());
+            break;
+          case OFTInteger64:
+            mv[idx] = static_cast<ValueType>((*it)[inputIndexes[idx]].GetValue<int>());
+            break;
+          case OFTReal:
+            mv[idx] = static_cast<ValueType>((*it)[inputIndexes[idx]].GetValue<double>());
+            break;
+          default:
+            itkExceptionMacro(<< "incorrect field type: " << (*it)[inputIndexes[idx]].GetType() << ".");
+        }
         }
       input->PushBack(mv);
       }
@@ -399,7 +412,23 @@ private:
 
       for (std::size_t i=0; i<outFields.size(); ++i)
         {
-        dstFeature[outFields[i]].SetValue<double>(target->GetMeasurementVector(count)[i]);
+        switch (dstFeature[outFields[i]].GetType())
+        {
+        case OFTInteger:
+          dstFeature[outFields[i]].SetValue<int>(target->GetMeasurementVector(count)[0]);
+          break;
+        case OFTInteger64:
+          dstFeature[outFields[i]].SetValue<int>(target->GetMeasurementVector(count)[0]);
+          break;
+        case OFTReal:
+          dstFeature[outFields[i]].SetValue<double>(target->GetMeasurementVector(count)[0]);
+          break;
+        case OFTString:
+          dstFeature[outFields[i]].SetValue<std::string>(std::to_string(target->GetMeasurementVector(count)[0]));
+          break;
+        default:
+          itkExceptionMacro(<< "incorrect field type: " << dstFeature[outFields[i]].GetType() << ".");
+        }
         }
       if (updateMode)
         {
diff --git a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
index 3996335d03290236e7ff2f1e93a1d94b35d11dda..90567d1850907f0808a36c9c1eed7ac8eff89423 100644
--- a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
+++ b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
@@ -94,8 +94,8 @@ private:
     AddParameter(ParameterType_InputImage, "in",  "Input Image");
     SetParameterDescription("in", "This will take an input image to be transformed"
       " image. For FFT inverse transform, it expects a complex image as two-band"
-      " image in which first band represent real part and second band represent"
-      " imaginary part.");
+      " image in which the first band represents the real part and second band represents"
+      " the imaginary part.");
 
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
     SetParameterDescription("out", "This parameter holds the output file name to"
diff --git a/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx b/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
index ca0706944733396ba64efee0f18151caf4872cf0..d9b69923594d3ac3b632d7dc2ea882e754b483f4 100644
--- a/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
+++ b/Modules/Applications/AppEdge/app/otbEdgeExtraction.cxx
@@ -66,7 +66,7 @@ private:
     // Documentation
     SetDocLongDescription(
         "This application computes edge features on a selected channel of the input."
-        "It uses different filter such as gradient, Sobel and Touzi");
+        "It uses different filters such as gradient, Sobel and Touzi");
 
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
@@ -102,9 +102,9 @@ private:
     // Touzi Section
     AddChoice("filter.touzi", "Touzi");
     SetParameterDescription("filter.touzi",
-                            "This filter is more suited for radar images. It has a spatial parameter "
+                            "This filter is more suited to 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.");
+                            "the less sensitive the filter is to the speckle noise, but micro edge will be missed.");
     AddParameter(ParameterType_Int, "filter.touzi.xradius", "X radius of the neighborhood");
     SetDefaultParameterInt("filter.touzi.xradius", 1);
     AddParameter(ParameterType_Int, "filter.touzi.yradius", "Y radius of the neighborhood");
diff --git a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
index 2463437174bffcaad5df5962eda5752cdf53fa99..5112c05145c2ad0c93ed03d4f3334d2faace2e36 100644
--- a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
+++ b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
@@ -148,7 +148,7 @@ private:
     SetDescription("This application is the implementation of the histogram "
       "equalization algorithm. It can be used to enhance contrast in an image "
       "or to reduce the dynamic of the image without losing too much contrast. "
-      "It offers several options as a no data value, "
+      "It offers several options as a nodata value, "
       "a contrast limitation factor, a local version of the algorithm and "
       "also a mode to equalize the luminance of the image.");
 
@@ -162,7 +162,7 @@ private:
       "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 "
+      "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 "
diff --git a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
index 443db5226b295b9463bcfc45a6ca85bbc829e1ca..f1d4efdf4e3f9508c3de58bf042f038f4668f01e 100644
--- a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
+++ b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
@@ -61,7 +61,7 @@ private:
     SetDescription( "Apply a smoothing filter to an image" );
 
     SetDocLongDescription( "This application applies a smoothing filter to an "
-      "image. Three methodes can be used: a gaussian filter , a mean filter "
+      "image. Three methods can be used: a gaussian filter , a mean filter "
       ", or an anisotropic diffusion using the Perona-Malik algorithm." );
     SetDocLimitations( "None") ;
     SetDocAuthors( "OTB-Team" );
diff --git a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
index c826e18469e98ee9fee259b919ad7665da875123..476f7b5710619cc8ba21a12721f723636956398b 100644
--- a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
@@ -374,18 +374,7 @@ private:
   bool CropRegionOfInterest()
   {
     FloatVectorImageType::RegionType region;
-    if ( !HasUserValue("sizex") )
-      SetParameterInt( "sizex" , 
-        GetDefaultParameterInt( "sizex" ) );
-    if ( !HasUserValue("sizey") )
-      SetParameterInt( "sizey" , 
-        GetDefaultParameterInt( "sizey" ) );
-    if ( !HasUserValue("startx") )
-      SetParameterInt( "startx" , 
-        GetDefaultParameterInt( "startx" ) );
-    if ( !HasUserValue("starty") )
-      SetParameterInt( "starty" , 
-        GetDefaultParameterInt( "starty" ) );
+
     region.SetSize(0,  GetParameterInt("sizex"));
     region.SetSize(1,  GetParameterInt("sizey"));
     region.SetIndex(0, GetParameterInt("startx"));
diff --git a/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx b/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx
index 47a68fbdd17d2dd0eda919200f188fcf4007cf74..20a7833a9124e40fcdf0edcf633d0a2b23c397d0 100644
--- a/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx
+++ b/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx
@@ -59,7 +59,10 @@ SetName("LocalStatisticExtraction");
 SetDescription("Computes local statistical moments on every pixel in the selected channel of the input image");
 
 // Documentation
-SetDocLongDescription("This application computes the 4 local statistical moments on every pixel in the selected channel of the input image, over a specified neighborhood. The output image is multi band with one statistical moment (feature) per band. Thus, the 4 output features are the Mean, the Variance, the Skewness and the Kurtosis. They are provided in this exact order in the output image.");
+SetDocLongDescription("This application computes the 4 local statistical moments on every pixel in the "
+    "selected channel of the input image, over a specified neighborhood. The output image is multi band "
+    "with one statistical moment (feature) per band. Thus, the 4 output features are the Mean, the "
+    "Variance, the Skewness and the Kurtosis. They are provided in this exact order in the output image.");
 SetDocLimitations("None");
 SetDocAuthors("OTB-Team");
 SetDocSeeAlso("otbRadiometricMomentsImageFunction class");
@@ -74,7 +77,7 @@ AddParameter(ParameterType_OutputImage, "out", "Feature Output Image");
 SetParameterDescription("out", "Output image containing the local statistical moments.");
 
 AddParameter(ParameterType_Int,  "channel",  "Selected Channel");
-SetParameterDescription("channel", "The selected channel index");
+SetParameterDescription("channel", "The selected channel index (1 based)");
 SetDefaultParameterInt("channel", 1);
 SetMinimumParameterIntValue("channel", 1);
 
@@ -102,7 +105,6 @@ void DoUpdateParameters() override
 void DoExecute() override
 {
   FloatVectorImageType::Pointer inImage = GetParameterImage("in");
-  inImage->UpdateOutputInformation();
   int nbChan = inImage->GetNumberOfComponentsPerPixel();
 
   if( GetParameterInt("channel") > nbChan )
@@ -118,12 +120,10 @@ void DoExecute() override
   m_ExtractorFilter->SetSizeX(inImage->GetLargestPossibleRegion().GetSize(0));
   m_ExtractorFilter->SetSizeY(inImage->GetLargestPossibleRegion().GetSize(1));
   m_ExtractorFilter->SetChannel(GetParameterInt("channel"));
-  m_ExtractorFilter->UpdateOutputInformation();
 
   m_Filter = FilterType::New();
   m_Filter->SetInput(m_ExtractorFilter->GetOutput());
   m_Filter->SetRadius(GetParameterInt("radius"));
-  m_Filter->UpdateOutputInformation();
 
   SetParameterOutputImage("out", m_Filter->GetOutput());
 
diff --git a/Modules/Core/Common/include/otbImageRegionTileMapSplitter.h b/Modules/Core/Common/include/otbImageRegionTileMapSplitter.h
index 63767c7acd12477f27151969288ebbcfb384973b..fdcf4e67c1fb37bc614f3beda83ff711b1570bec 100644
--- a/Modules/Core/Common/include/otbImageRegionTileMapSplitter.h
+++ b/Modules/Core/Common/include/otbImageRegionTileMapSplitter.h
@@ -123,7 +123,7 @@ public:
                               const RegionType& region) override;
 
 protected:
-  ImageRegionTileMapSplitter() : m_AlignStep(256){}
+  ImageRegionTileMapSplitter() : m_SplitsPerDimension{0}, m_AlignStep(256) {}
   ~ImageRegionTileMapSplitter() override {}
   void PrintSelf(std::ostream& os, itk::Indent indent) const override;
 
diff --git a/Modules/Core/Common/src/otbSystem.cxx b/Modules/Core/Common/src/otbSystem.cxx
index c265159970c6b9a30ddefbe936ee24317e62514f..d2124254b9ae69ffc6cba229306eab78141598c9 100644
--- a/Modules/Core/Common/src/otbSystem.cxx
+++ b/Modules/Core/Common/src/otbSystem.cxx
@@ -29,6 +29,8 @@
                    WIN32 / MSVC++ implementation
  *====================================================================*/
 #include <Windows.h>
+#include <tchar.h>
+#include <stdio.h>
 #ifndef WIN32CE
 #  include <io.h>
 #else
@@ -73,8 +75,8 @@ System::GetRootName(const std::string& filename)
 
 std::vector<std::string> System::Readdir(const std::string&  pszPath)
 {
-  struct _finddata_t       c_file;
-  long                     hFile;
+  WIN32_FIND_DATA          c_file;
+  HANDLE                   hFile = INVALID_HANDLE_VALUE;
   std::vector<std::string> listFileFind;
   std::string              pszFileSpec;
   std::string              path(pszPath);
@@ -83,15 +85,15 @@ std::vector<std::string> System::Readdir(const std::string&  pszPath)
 
   pszFileSpec = path + "\\*.*";
 
-  if ((hFile = _findfirst(pszFileSpec.c_str(), &c_file)) != -1L)
+  if ((hFile = FindFirstFile(pszFileSpec.c_str(), &c_file)) != INVALID_HANDLE_VALUE)
     {
     do
       {
-      listFileFind.push_back(c_file.name);
+      listFileFind.push_back(c_file.cFileName);
       }
-    while (_findnext(hFile, &c_file) == 0);
+    while (FindNextFile(hFile, &c_file) != 0);
 
-    _findclose(hFile);
+    FindClose(hFile);
     }
 
   return listFileFind;
diff --git a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageBlackmanFunction.h b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageBlackmanFunction.h
index 910908443fdc97c419798ce2423adb6b8a98e18f..4bad6a65ef34138eb623b6ea0b3e1310fd104583 100644
--- a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageBlackmanFunction.h
+++ b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageBlackmanFunction.h
@@ -41,6 +41,7 @@ template<class TInput = double, class TOutput = double>
 class BlackmanWindowFunction
 {
 public:
+  BlackmanWindowFunction(): m_Radius(1), m_Factor1(CONST_PI), m_Factor2(2.0 * CONST_PI) {} // default radius is 1 at construction
   void SetRadius(unsigned int radius)
   {
     m_Radius = radius;
@@ -95,8 +96,7 @@ template<class TInputImage, class TBoundaryCondition = itk::ConstantBoundaryCond
       double, class TInputInterpolator = double, class TOutputInterpolator = double>
 class ITK_EXPORT WindowedSincInterpolateImageBlackmanFunction :
   public WindowedSincInterpolateImageFunctionBase<TInputImage,
-      typename Function::BlackmanWindowFunction<TInputInterpolator,
-          TOutputInterpolator>,
+      typename Function::BlackmanWindowFunction<TInputInterpolator, TOutputInterpolator>,
       TBoundaryCondition,
       TCoordRep>
 {
diff --git a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageCosineFunction.h b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageCosineFunction.h
index 5f37e59be5177494d82108c153bb6573d6f20940..46a65cc60de9715b6b79840467666e9620f89336 100644
--- a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageCosineFunction.h
+++ b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageCosineFunction.h
@@ -41,6 +41,7 @@ template<class TInput = double, class TOutput = double>
 class CosineWindowFunction
 {
 public:
+  CosineWindowFunction(): m_Radius(1), m_Factor(CONST_PI / 2.0) {} // default radius is 1 at construction
   void SetRadius(unsigned int radius)
   {
     m_Radius = radius;
@@ -63,9 +64,9 @@ public:
     return (x == 0.0) ? static_cast<TOutput>(temp) : static_cast<TOutput>(temp * std::sin(px) / px);
   }
 private:
+  unsigned int m_Radius;
   // Equal to \f$ \frac{\pi}{2 m} \f$
   double       m_Factor;
-  unsigned int m_Radius;
 };
 } //namespace Function
 
diff --git a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageGaussianFunction.h b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageGaussianFunction.h
index 9d20a68c81157570f581e298fc48fb05072b2e73..b2a6bdc1bc0e18be51b28cce02508d960bfe1e9b 100644
--- a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageGaussianFunction.h
+++ b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageGaussianFunction.h
@@ -41,6 +41,7 @@ template<class TInput = double, class TOutput = double>
 class GaussianWindowFunction
 {
 public:
+  GaussianWindowFunction(): m_Radius(1), m_Factor(-2.0 / CONST_PI) {} // default radius is 1 at construction
   void SetRadius(unsigned int radius)
   {
     m_Radius = radius;
@@ -63,8 +64,8 @@ public:
     return (x == 0.0) ? static_cast<TOutput>(temp) : static_cast<TOutput>(temp * std::sin(px) / px);
   }
 private:
-  double       m_Factor;
   unsigned int m_Radius;
+  double       m_Factor;
 };
 
 } //namespace Function
diff --git a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageHammingFunction.h b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageHammingFunction.h
index 003bbdd2508a615eea5ab186762d922eec7579ce..2ea6af2790e9608479ea1ac09f7b2731b84506bb 100644
--- a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageHammingFunction.h
+++ b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageHammingFunction.h
@@ -41,6 +41,7 @@ template<class TInput = double, class TOutput = double>
 class HammingWindowFunction
 {
 public:
+  HammingWindowFunction(): m_Radius(1), m_Factor(CONST_PI) {} // default radius is 1 at construction
   void SetRadius(unsigned int radius)
   {
     m_Radius = radius;
@@ -63,9 +64,9 @@ public:
     return (x == 0.0) ? static_cast<TOutput>(temp) : static_cast<TOutput>(temp * std::sin(px) / px);
   }
 private:
+  unsigned int m_Radius;
   // Equal to \f$ \frac{\pi}{m} \f$
   double       m_Factor;
-  unsigned int m_Radius;
 };
 
 } //namespace Function
diff --git a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageLanczosFunction.h b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageLanczosFunction.h
index bfd9162671520e945d0c28c078a55775677a5d37..8e0e6355aea1385c6b47f84ab7f980576963c4aa 100644
--- a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageLanczosFunction.h
+++ b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageLanczosFunction.h
@@ -43,6 +43,7 @@ template<class TInput = double, class TOutput = double>
 class LanczosWindowFunction
 {
 public:
+  LanczosWindowFunction(): m_Radius(1), m_Factor(CONST_PI) {} // default factor is 1 at construction
   void SetRadius(unsigned int radius)
   {
     m_Radius = radius;
@@ -74,9 +75,9 @@ public:
     return (x == 0.0) ? static_cast<TOutput>(temp) : static_cast<TOutput>(temp * std::sin(px) / px);
   }
 private:
+  unsigned int m_Radius;
   // Equal to \f$ \frac{\pi}{m} \f$
   double       m_Factor;
-  unsigned int m_Radius;
 };
 } //namespace Function
 
diff --git a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageWelchFunction.h b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageWelchFunction.h
index 5625f2f41188490ce2536de72c88234ceae79743..03fa31a4a3540bc9bed73e21e71ff9862dccc606 100644
--- a/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageWelchFunction.h
+++ b/Modules/Core/Interpolation/include/otbWindowedSincInterpolateImageWelchFunction.h
@@ -41,6 +41,7 @@ template<class TInput = double, class TOutput = double>
 class WelchWindowFunction
 {
 public:
+  WelchWindowFunction() : m_Radius(1), m_Factor(1) {} // default radius is 1 at construction
   void SetRadius(unsigned int radius)
   {
     m_Radius = radius;
@@ -63,9 +64,9 @@ public:
     return (x == 0.0) ? static_cast<TOutput>(temp) : static_cast<TOutput>(temp * std::sin(px) / px);
   }
 private:
+  unsigned int m_Radius;
   // Equal to \f$ \frac{1}{m^2} \f$
   double       m_Factor;
-  unsigned int m_Radius;
 };
 } //namespace Function
 
diff --git a/Modules/Core/PointSet/include/otbPointSetExtractROI.hxx b/Modules/Core/PointSet/include/otbPointSetExtractROI.hxx
index 8f55da34976475272ff1bbee67bf8f956bc2f1a7..30fe8820c94117163845a4d8d143751c621c6125 100644
--- a/Modules/Core/PointSet/include/otbPointSetExtractROI.hxx
+++ b/Modules/Core/PointSet/include/otbPointSetExtractROI.hxx
@@ -32,7 +32,7 @@ namespace otb
  */
 template <class TInputPointSet, class TOutputPointSet>
 PointSetExtractROI<TInputPointSet, TOutputPointSet>
-::PointSetExtractROI()
+::PointSetExtractROI() : m_StartX(0), m_StartY(0), m_SizeX(0), m_SizeY(0)
 {
 }
 
diff --git a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectFilter.h b/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectFilter.h
deleted file mode 100644
index 441154ff18cf772d288828a4b206a90eb1f4a57f..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectFilter.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbDrawLineSpatialObjectFilter_h
-#define otbDrawLineSpatialObjectFilter_h
-
-#include "itkSpatialObjectToImageFilter.h"
-#include "otbDrawLineSpatialObjectListFilter.h"
-
-//#include <list>
-
-namespace otb
-{
-
-/** \class DrawLineSpatialObjectFilter
- * \brief Application of a filter which draw line in a binary image.
- *
- * This class implements a filter that draws line in a binary image.
- * Inputs are a LineSpatialObject and an input image that is used to
- * allocate the output image. This filter copies the input image in
- * the output image.
- *
- *
- * \ingroup OTBSpatialObjects
- */
-
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT DrawLineSpatialObjectFilter :
-  //public itk::SpatialObjectToImageFilter< itk::LineSpatialObject<2>, TOutputImage >
-  public itk::ImageToImageFilter<TInputImage, TOutputImage>
-{
-public:
-  /**   Extract dimensions as well of the images of entry of exit. */
-  itkStaticConstMacro(InputImageDimension,
-                      unsigned int,
-                      TInputImage::ImageDimension);
-  itkStaticConstMacro(OutputImageDimension,
-                      unsigned int,
-                      TOutputImage::ImageDimension);
-
-  /** typedef for the classes standards. */
-  typedef DrawLineSpatialObjectFilter Self;
-  //typedef itk::ImageTo< itk::LineSpatialObject<2>, TOutputImage > Superclass;
-  typedef itk::ImageToImageFilter<TInputImage, TOutputImage> Superclass;
-  typedef itk::SmartPointer<Self>                            Pointer;
-  typedef itk::SmartPointer<const Self>                      ConstPointer;
-
-  /** Method for management of the "object factory". */
-  itkNewMacro(Self);
-
-  /** Return the name of the class. */
-  itkTypeMacro(DrawLineSpatialObjectFilter, /*SpatialObjectToImageFilter*/ itk::ImageToImageFilter);
-
-  /** typedef Support for input & output image*/
-  typedef TInputImage InputImageType;
-
-  typedef TOutputImage                        OutputImageType;
-  typedef typename OutputImageType::PixelType OutputPixelType;
-
-  /** Support typedef for input & Output*/
-  typedef itk::LineSpatialObject<2> InputLineType;
-  typedef itk::ProcessObject        ProcessObjectType;
-
-  /** Typedef Support for lineList Type*/
-  typedef LineSpatialObjectList                       LineSpatialObjectListType;
-  typedef typename LineSpatialObjectListType::Pointer LineSpatialObjectListPointer;
-
-  /** Typedef Support for drawLineSpatialObjectListFilter*/
-  typedef otb::DrawLineSpatialObjectListFilter<InputImageType, OutputImageType> DrawLineSpatialObjectListFilterType;
-  typedef typename DrawLineSpatialObjectListFilterType::Pointer
-  DrawLineSpatialObjectListFilterPointerType;
-
-  /** Set/Get the image input of this process object. */
-  /*   virtual void SetInputImage(const InputImageType *image); */
-  /*   const InputImageType * GetInputImage(void); */
-
-  /** Get the input LineSpatialObjet (not const) */
-  virtual void SetInputLine(const InputLineType *line);
-  InputLineType * GetInputLine(void);
-
-  /** Set/Get pixel value */
-  itkSetMacro(Value, OutputPixelType);
-  itkGetConstReferenceMacro(Value, OutputPixelType);
-
-protected:
-  DrawLineSpatialObjectFilter();
-  ~DrawLineSpatialObjectFilter() override {}
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-  void GenerateData() override;
-
-private:
-  DrawLineSpatialObjectFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-  OutputPixelType m_Value;
-
-  DrawLineSpatialObjectListFilterPointerType m_DrawLineListFilter;
-
-};
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbDrawLineSpatialObjectFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectFilter.hxx b/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectFilter.hxx
deleted file mode 100644
index 12080e6d6dfcf8f7b55789d9bed9842abef8848a..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectFilter.hxx
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbDrawLineSpatialObjectFilter_hxx
-#define otbDrawLineSpatialObjectFilter_hxx
-
-#include "otbDrawLineSpatialObjectFilter.h"
-
-#include "itkDataObject.h"
-#include "itkMacro.h"
-#include "itkImageRegionIterator.h"
-#include "itkImageIteratorWithIndex.h"
-
-namespace otb
-{
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-DrawLineSpatialObjectFilter<TInputImage, TOutputImage>::DrawLineSpatialObjectFilter()
-{
-  this->SetNumberOfRequiredInputs(2);
-  this->SetNumberOfRequiredOutputs(1);
-
-  m_Value = static_cast<OutputPixelType>(255.0);
-  m_DrawLineListFilter = DrawLineSpatialObjectListFilterType::New();
-}
-
-template <class TInputImage, class TOutputImage>
-void
-DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
-::SetInputLine(const InputLineType *line)
-{
-  this->ProcessObjectType::SetNthInput(1,
-                                       const_cast<InputLineType *>(line));
-}
-
-template <class TInputImage, class TOutputImage>
-typename DrawLineSpatialObjectFilter<TInputImage, TOutputImage>::InputLineType *
-DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
-::GetInputLine(void)
-{
-  return static_cast<InputLineType *>
-           (this->ProcessObjectType::GetInput(1));
-}
-
-template <class TInputImage, class TOutputImage>
-void
-DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
-::GenerateData(void)
-{
-
-  typename InputImageType::ConstPointer input    = this->GetInput();
-  InputLineType *                       line     = this->GetInputLine();
-
-  typename OutputImageType::Pointer output   = this->GetOutput();
-
-  /** Create a new list line with one line*/
-  LineSpatialObjectListPointer lineList = LineSpatialObjectListType::New();
-  lineList->push_back(line);
-
-  /** Invoke the DrawLineSpatialObjectListFilter to draw the line */
-  m_DrawLineListFilter->SetInput(input);
-  m_DrawLineListFilter->SetInputLineSpatialObjectList(lineList);
-
-  m_DrawLineListFilter->GraftOutput(this->GetOutput());
-  m_DrawLineListFilter->Update();
-  this->GraftOutput(m_DrawLineListFilter->GetOutput());
-
-}
-
-/**
- * Standard "PrintSelf" method
- */
-template <class TInputImage, class TOutput>
-void
-DrawLineSpatialObjectFilter<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-  os << indent << "Path Value: " << m_Value << std::endl;
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectListFilter.h b/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectListFilter.h
deleted file mode 100644
index b13f26655d1d4ae8400d1370979b4096b61759aa..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectListFilter.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbDrawLineSpatialObjectListFilter_h
-#define otbDrawLineSpatialObjectListFilter_h
-
-#include "itkImageToImageFilter.h"
-#include "otbLineSpatialObjectList.h"
-
-namespace otb
-{
-
-/** \class DrawLineSpatialObjectListFilter
- * \brief Composite filter which draw lines in an image.
- *
- * This class implements a composite filter that draws a list of lines in
- * an input Image. This class
- *
- *
- *
- *
- * \ingroup OTBSpatialObjects
- */
-
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT DrawLineSpatialObjectListFilter :
-  public itk::ImageToImageFilter<TInputImage, TOutputImage>
-{
-public:
-  /**   Extract dimensions as well of the images of entry of exit. */
-  itkStaticConstMacro(InputImageDimension,
-                      unsigned int,
-                      TInputImage::ImageDimension);
-  itkStaticConstMacro(OutputImageDimension,
-                      unsigned int,
-                      TOutputImage::ImageDimension);
-
-  /** typedefs support for inputs & outputs*/
-  typedef TInputImage                          InputImageType;
-  typedef TOutputImage                         OutputImageType;
-  typedef typename OutputImageType::RegionType OutputImageRegionType;
-
-  /** typedef for the classes standards. */
-  typedef DrawLineSpatialObjectListFilter                    Self;
-  typedef itk::ImageToImageFilter<TInputImage, TOutputImage> Superclass;
-  typedef itk::SmartPointer<Self>                            Pointer;
-  typedef itk::SmartPointer<const Self>                      ConstPointer;
-
-  typedef LineSpatialObjectList                  LinesListType;
-  typedef LinesListType::LineType                LineType;
-  typedef LineType::PointListType                PointListType;
-  typedef typename LinesListType::const_iterator LineListIterator;
-
-  typedef itk::ProcessObject ProcessObjectType;
-
-  /** Method for management of the "object factory". */
-  itkNewMacro(Self);
-
-  /** Return the name of the class. */
-  itkTypeMacro(DrawLineSpatialObjectListFilter, ImageToImageFilter);
-
-  /** Definition of the input and output images */
-  typedef typename InputImageType::PixelType       InputPixelType;
-  typedef typename OutputImageType::PixelType      OutputPixelType;
-  typedef typename OutputImageType::IndexType      OutputIndexType;
-  typedef typename OutputIndexType::IndexValueType OutputIndexValueType;
-
-  /** Set/Get the image input of this process object. */
-  virtual void SetInputLineSpatialObjectList(const LinesListType * list);
-  LinesListType * GetInputLineSpatialObjectList(void);
-
-  /** Get/Set m_Value*/
-  itkGetMacro(Value, OutputPixelType);
-  itkSetMacro(Value, OutputPixelType);
-
-protected:
-  DrawLineSpatialObjectListFilter();
-  ~DrawLineSpatialObjectListFilter() override {}
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) override;
-
-  /**
-   * compute the intersection of the segment to draw with the region
-   */
-  virtual void CropSegment(OutputIndexType *indexToCrop,
-                           OutputIndexType *otherIndex,
-                           const OutputImageRegionType *outputRegionForThread) const;
-
-  virtual void CropRightSegment(OutputIndexType *indexToCrop,
-                                OutputIndexType *otherIndex,
-                                const OutputImageRegionType *outputRegionForThread) const;
-
-  virtual bool IsUpsideTheRegion(OutputIndexType *indexToCrop,
-                                 const OutputImageRegionType *outputRegionForThread) const;
-
-  virtual bool IsDownsideTheRegion(OutputIndexType *indexToCrop,
-                                   const OutputImageRegionType *outputRegionForThread) const;
-
-  virtual bool IsDownsideTheImage(OutputIndexType *indexToCrop) const;
-
-  virtual bool IsColumnOutsideOfTheRegion(OutputIndexType *indexToCheck,
-                                          OutputIndexType *otherToCheck,
-                                          const OutputImageRegionType *outputRegionForThread) const;
-
-private:
-  DrawLineSpatialObjectListFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-  OutputPixelType m_Value;
-  int             m_Length;
-  int             m_Width;
-
-};
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbDrawLineSpatialObjectListFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectListFilter.hxx b/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectListFilter.hxx
deleted file mode 100644
index 0f8af7bf807896690453d73e355a38bb843da831..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbDrawLineSpatialObjectListFilter.hxx
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbDrawLineSpatialObjectListFilter_hxx
-#define otbDrawLineSpatialObjectListFilter_hxx
-
-#include "otbDrawLineSpatialObjectListFilter.h"
-
-#include "itkLineIterator.h"
-#include "itkDataObject.h"
-#include "itkImageRegionIterator.h"
-
-namespace otb
-{
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
-::DrawLineSpatialObjectListFilter()
-{
-  this->SetNumberOfRequiredInputs(2);
-  this->SetNumberOfRequiredOutputs(1);
-
-  m_Value = static_cast<OutputPixelType>(255.);
-}
-
-template <class TInputImage, class TOutputImage>
-void
-DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
-::SetInputLineSpatialObjectList(const LinesListType * list)
-{
-  this->ProcessObjectType::SetNthInput(1,
-                                       const_cast<LinesListType *>(list));
-
-}
-
-template <class TInputImage, class TOutputImage>
-typename DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>::LinesListType *
-DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
-::GetInputLineSpatialObjectList(void)
-{
-  //ROMAIN
-  return static_cast</*const*/ LinesListType*>
-           (this->ProcessObjectType::GetInput(1));
-}
-
-template <class TInputImage, class TOutputImage>
-void
-DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType itkNotUsed(threadId))
-
-{
-  typename InputImageType::ConstPointer input  = this->GetInput();
-  typename OutputImageType::Pointer     output  = this->GetOutput();
-  typename LinesListType::Pointer       list = const_cast<LinesListType*>(this->GetInputLineSpatialObjectList());
-
-  /** Copy the input requested region in the output requested region*/
-  typedef itk::ImageRegionIterator<OutputImageType>     OutputIteratorType;
-  typedef itk::ImageRegionConstIterator<InputImageType> InputIteratorType;
-
-  OutputIteratorType    outputIt(output, outputRegionForThread);
-  InputIteratorType     inputIt(input,  outputRegionForThread);
-
-  outputIt.GoToBegin();
-  inputIt.GoToBegin();
-
-  for (outputIt.GoToBegin(); !outputIt.IsAtEnd(); ++outputIt, ++inputIt)
-    outputIt.Set(static_cast<OutputPixelType>(inputIt.Get()));
-
-  /** Draw the lines in the output image using lineIterator*/
-  typedef itk::LineIterator<OutputImageType> LineIteratorFilter;
-  OutputIndexType  indexBeginLine, indexEndLine;
-  LineListIterator itList = list->begin();
-
-  typename InputImageType::SizeType size = input->GetLargestPossibleRegion().GetSize();
-  m_Length = size[1];
-  m_Width  = size[0];
-
-  while (itList != list->end())
-    {
-    PointListType&                         pointsList = (*itList)->GetPoints();
-    typename PointListType::const_iterator itPoints = pointsList.begin();
-
-    indexBeginLine[0] = static_cast<OutputIndexValueType>((*itPoints).GetPosition()[0]);
-    indexBeginLine[1] = static_cast<OutputIndexValueType>((*itPoints).GetPosition()[1]);
-
-    ++itPoints;    //Get the second extremity of the segment
-
-    indexEndLine[0] = static_cast<OutputIndexValueType>((*itPoints).GetPosition()[0]);
-    indexEndLine[1] = static_cast<OutputIndexValueType>((*itPoints).GetPosition()[1]);
-
-    /** Crop the segment if it is outside the region in the left*/
-
-    if (!(this->IsColumnOutsideOfTheRegion(&indexBeginLine, &indexEndLine,
-                                           &outputRegionForThread) &&
-          this->IsColumnOutsideOfTheRegion(&indexEndLine, &indexBeginLine, &outputRegionForThread)))
-      {
-      if (indexEndLine[0] >= static_cast<OutputIndexValueType>(size[0]))
-        this->CropRightSegment(&indexEndLine,
-                               &indexBeginLine,
-                               &outputRegionForThread);
-
-      if (indexBeginLine[0] >= static_cast<OutputIndexValueType>(size[0]))
-        this->CropRightSegment(
-          &indexBeginLine,
-          &indexEndLine,
-          &
-          outputRegionForThread);
-      }
-
-    /**
-     * If an extremity is under the region
-     * Technically, the X component of the index is inside the image
-     */
-    if (this->IsDownsideTheImage(&indexBeginLine)  &&
-        input->GetLargestPossibleRegion().IsInside(indexEndLine))
-      this->CropSegment(&indexBeginLine,
-                        &indexEndLine,
-                        &outputRegionForThread);
-
-    if (this->IsDownsideTheImage(&indexEndLine) &&
-        input->GetLargestPossibleRegion().IsInside(indexBeginLine))
-      this->CropSegment(&indexEndLine,
-                        &indexBeginLine,
-                        &outputRegionForThread);
-
-    /** If the segments are not in the region (upside or downside the region)*/
-    if (!(this->IsUpsideTheRegion(&indexBeginLine,
-                                  &outputRegionForThread)   &&
-          this->IsUpsideTheRegion(&indexEndLine, &outputRegionForThread)) &&
-        !(this->IsDownsideTheRegion(&indexBeginLine,
-                                    &outputRegionForThread) &&
-          this->IsDownsideTheRegion(&indexEndLine, &outputRegionForThread)) &&
-        !(this->IsColumnOutsideOfTheRegion(&indexBeginLine, &indexEndLine,
-                                           &outputRegionForThread) &&
-          this->IsColumnOutsideOfTheRegion(&indexEndLine, &indexBeginLine, &outputRegionForThread))
-        )
-      {
-
-      /** Instantiation of the line iterator with begin and ending index*/
-      LineIteratorFilter   itLine(output, indexBeginLine, indexEndLine);
-
-      /** Iteration over the line and writing white lines */
-      while (!itLine.IsAtEnd())
-        {
-        if (outputRegionForThread.IsInside(itLine.GetIndex())) itLine.Set(m_Value);
-        ++itLine;
-        }
-      }
-
-    ++itList;
-    }
-}
-
-/**
- * Compute the intersection between the segment to draw and the region belonging to the current thread
- * It is used if the segment abcisse is greater than the width of the image
- *
- */
-template <class TInputImage, class TOutput>
-void
-DrawLineSpatialObjectListFilter<TInputImage, TOutput>
-::CropRightSegment(OutputIndexType *indexToCrop,
-                   OutputIndexType *otherIndex,
-                   const OutputImageRegionType *outputRegionForThread) const
-
-{
-
-  /** Dimensions of the buffered region*/
-  typename OutputImageRegionType::SizeType  size  = outputRegionForThread->GetSize();
-  //typename OutputImageRegionType::IndexType start = outputRegionForThread->GetIndex();
-
-  /** Equation of the line (Begin, End)*/
-  double lengthSegment = -(*otherIndex)[1] + (*indexToCrop)[1];
-  double slope         =  lengthSegment / ((*indexToCrop)[0]  - (*otherIndex)[0]);
-  double origin        =  (*otherIndex)[1] - (slope * (*otherIndex)[0]);
-
-  (*indexToCrop)[0] = static_cast<OutputIndexValueType>(size[0] - 1);
-  (*indexToCrop)[1] = static_cast<OutputIndexValueType>(slope * (*indexToCrop)[0] + origin + 0.5);
-}
-
-/**
- * Define if the point is upside the region or not
- *
- */
-template <class TInputImage, class TOutput>
-bool
-DrawLineSpatialObjectListFilter<TInputImage, TOutput>
-::IsUpsideTheRegion(OutputIndexType *indexToCrop, const OutputImageRegionType *outputRegionForThread) const
-
-{
-  /** Dimensions of the buffered region*/
-  //typename OutputImageRegionType::SizeType  size  = outputRegionForThread->GetSize();
-  typename OutputImageRegionType::IndexType start = outputRegionForThread->GetIndex();
-
-  return (*indexToCrop)[1] < static_cast<OutputIndexValueType>(start[1]);
-}
-
-/**
- * Define if the point is upside the region or not
- *
- */
-template <class TInputImage, class TOutput>
-bool
-DrawLineSpatialObjectListFilter<TInputImage, TOutput>
-::IsDownsideTheRegion(OutputIndexType *indexToCrop, const OutputImageRegionType *outputRegionForThread) const
-
-{
-  /** Dimensions of the buffered region*/
-  typename OutputImageRegionType::SizeType  size  = outputRegionForThread->GetSize();
-  typename OutputImageRegionType::IndexType start = outputRegionForThread->GetIndex();
-
-  return (*indexToCrop)[1] >= static_cast<OutputIndexValueType>(start[1] + size[1]); //The down limit of the region in the Y direction
-}
-
-/**
- * Define if the point is outside the hole image
- *
- */
-template <class TInputImage, class TOutput>
-bool
-DrawLineSpatialObjectListFilter<TInputImage, TOutput>
-::IsDownsideTheImage(OutputIndexType *indexToCrop) const
-
-{
-  return (*indexToCrop)[1] >= static_cast<OutputIndexValueType>(m_Length); //The down limit of the Image in the Y direction
-}
-
-/**
- *
- *
- */
-template <class TInputImage, class TOutput>
-bool
-DrawLineSpatialObjectListFilter<TInputImage, TOutput>
-::IsColumnOutsideOfTheRegion(OutputIndexType *indexToCheck,
-                             OutputIndexType *otherToCheck,
-                             const OutputImageRegionType *outputRegionForThread) const
-{
-  /** Dimensions of the buffered region*/
-  typename OutputImageRegionType::SizeType size = outputRegionForThread->GetSize();
-  bool                                     res = false, res1 = false, res2 = false;
-
-  if (((*indexToCheck)[0] >= static_cast<OutputIndexValueType>(size[0])) &&
-      ((*otherToCheck)[0] >= static_cast<OutputIndexValueType>(size[0]))) res  = true;
-
-  if ((*indexToCheck)[0] >= static_cast<OutputIndexValueType>(size[0]) &&
-      this->IsUpsideTheRegion(otherToCheck, outputRegionForThread)) res1 = true;
-
-  if ((*indexToCheck)[0] >= static_cast<OutputIndexValueType>(size[0]) &&
-      this->IsDownsideTheRegion(otherToCheck, outputRegionForThread)) res2 = true;
-
-  return res || res1 || res2;
-
-}
-
-/**
- * Compute the intersection between the segment to draw and the region belonging to the current thread
- *
- */
-template <class TInputImage, class TOutput>
-void
-DrawLineSpatialObjectListFilter<TInputImage, TOutput>
-::CropSegment(OutputIndexType *indexToCrop,
-              OutputIndexType *otherIndex,
-              const OutputImageRegionType *itkNotUsed(outputRegionForThread)) const
-
-{
-  OutputIndexType tempIndex;
-  tempIndex = *indexToCrop;
-
-  /** Dimensions of the buffered region*/
-  //typename OutputImageRegionType::SizeType  size = outputRegionForThread->GetSize();
-  //typename OutputImageRegionType::IndexType start = outputRegionForThread->GetIndex();
-
-  /** Equation of the line (Begin, End)*/
-  double slope = 0.;
-  double lengthSegment = 0.;
-  double origin = 0.;
-  double tempOtherIndexX = 0.;
-
-  /** Equation of the first Line*/
-
-  if (std::abs((*otherIndex)[0] - (*indexToCrop)[0]) < 1e-4) tempOtherIndexX = 0.000001;
-  else tempOtherIndexX = static_cast<double>((*otherIndex)[0]);
-
-  if ((*indexToCrop)[0] < (*otherIndex)[0]) lengthSegment = (*otherIndex)[1] - (*indexToCrop)[1];
-  else lengthSegment = (*indexToCrop)[1] - (*otherIndex)[1];
-
-  slope = lengthSegment / (tempOtherIndexX - static_cast<double>((*indexToCrop)[0]));
-  origin = (*indexToCrop)[1] - (slope * static_cast<double>((*indexToCrop)[0]));
-
-  if ((*indexToCrop)[1] < 0)
-    {
-    unsigned int Y = 0;
-    tempIndex[1] = Y;
-    tempIndex[0] = static_cast<unsigned int>((Y - origin) / slope);  // X = (Y-B)/A
-    }
-
-  if (this->IsDownsideTheImage(indexToCrop))
-    {
-    double Y = static_cast<double>(m_Length - 1) /*tstart[1]+size[1]-1*/;
-    tempIndex[1] = static_cast<OutputIndexValueType>(Y);
-    tempIndex[0] = static_cast<OutputIndexValueType>((Y - origin) / slope);  // X = (Y-B)/A
-    }
-
-  (*indexToCrop)[0] = tempIndex[0];
-  (*indexToCrop)[1] = tempIndex[1];
-}
-
-/**
- * Standard "PrintSelf" method
- */
-template <class TInputImage, class TOutput>
-void
-DrawLineSpatialObjectListFilter<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbImageToLineSpatialObjectListFilter.h b/Modules/Core/SpatialObjects/include/otbImageToLineSpatialObjectListFilter.h
deleted file mode 100644
index 5761019681b3219bf8223e487fe5c17baa11af05..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbImageToLineSpatialObjectListFilter.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbImageToLineSpatialObjectListFilter_h
-#define otbImageToLineSpatialObjectListFilter_h
-
-
-#include "itkProcessObject.h"
-#include "otbLineSpatialObjectList.h"
-
-namespace otb
-{
-/** \class ImageToLineSpatialObjectListFilter
- *  \brief Base class for all process objects that output LineSpatialObjectList.
- *
- * ImageToLineSpatialObjectListFilter is the base class for all process objects
- * that output list of LineSpatialObject.
- *
- *
- * \ingroup OTBSpatialObjects
- */
-
-template <class TInputImage>
-class ITK_EXPORT ImageToLineSpatialObjectListFilter : public itk::ProcessObject
-{
-public:
-
-  /**   Extract dimensions as well of the images of entry of exit. */
-  itkStaticConstMacro(InputImageDimension,
-                      unsigned int,
-                      TInputImage::ImageDimension);
-
-  typedef TInputImage InputImageType;
-
-  /** Standard class typedefs. */
-  typedef ImageToLineSpatialObjectListFilter Self;
-  typedef itk::ProcessObject                 Superclass;
-  typedef itk::SmartPointer<Self>            Pointer;
-  typedef itk::SmartPointer<const Self>      ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(ImageToLineSpatialObjectListFilter, itk::ProcessObject);
-
-  /** Some convenient typedefs. */
-  typedef LineSpatialObjectList            LinesListType;
-  typedef typename LinesListType::LineType LineType;
-
-  /** Definition of the input and output images */
-  typedef typename InputImageType::PixelType InputPixelType;
-
-  /** Definition of the size of the images. */
-  typedef typename InputImageType::SizeType SizeType;
-
-  typedef itk::ProcessObject ProcessObjectType;
-
-  /** Set/Get the input image */
-  using Superclass::SetInput;
-  void SetInput(const InputImageType *image);
-  const InputImageType * GetInput(void);
-
-  /** Set/Get the list of LineSpatialObject of this process object.  */
-  using Superclass::SetOutput;
-  void SetOutput(const LinesListType *list);
-  LinesListType * GetOutput(void);
-
-protected:
-  ImageToLineSpatialObjectListFilter();
-  ~ImageToLineSpatialObjectListFilter() override {}
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-  ImageToLineSpatialObjectListFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-};
-
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbImageToLineSpatialObjectListFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbImageToLineSpatialObjectListFilter.hxx b/Modules/Core/SpatialObjects/include/otbImageToLineSpatialObjectListFilter.hxx
deleted file mode 100644
index abe29e71686185c6a93864e683fe8372b6025d8f..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbImageToLineSpatialObjectListFilter.hxx
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbImageToLineSpatialObjectListFilter_hxx
-#define otbImageToLineSpatialObjectListFilter_hxx
-
-#include "otbImageToLineSpatialObjectListFilter.h"
-
-namespace otb
-{
-
-/**
- *
- */
-template<class TInputImage>
-ImageToLineSpatialObjectListFilter<TInputImage>::ImageToLineSpatialObjectListFilter()
-{
-  this->SetNumberOfRequiredInputs(1);
-  this->SetNumberOfRequiredOutputs(1);
-
-  typename LinesListType::Pointer list = LinesListType::New();
-  this->SetOutput(list);
-
-}
-
-template <class TInputImage>
-void
-ImageToLineSpatialObjectListFilter<TInputImage>
-::SetInput(const InputImageType *image)
-{
-  this->itk::ProcessObject::SetNthInput(0,
-                                        const_cast<InputImageType *>(image));
-}
-
-template <class TInputImage>
-const typename ImageToLineSpatialObjectListFilter<TInputImage>::InputImageType *
-ImageToLineSpatialObjectListFilter<TInputImage>
-::GetInput(void)
-{
-  return static_cast<const InputImageType *>
-           (this->itk::ProcessObject::GetInput(0));
-}
-
-template <class TInputImage>
-void
-ImageToLineSpatialObjectListFilter<TInputImage>
-::SetOutput(const LinesListType *list)
-{
-  this->ProcessObjectType::SetNthOutput(0,
-                                        const_cast<LinesListType *>(list));
-}
-
-template <class TInputImage>
-typename ImageToLineSpatialObjectListFilter<TInputImage>::LinesListType *
-ImageToLineSpatialObjectListFilter<TInputImage>
-::GetOutput(void)
-{
-  return static_cast<LinesListType *>
-           (this->ProcessObjectType::GetOutput(0));
-}
-
-/**
- *
- */
-template<class TInputImage>
-void
-ImageToLineSpatialObjectListFilter<TInputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbLineSpatialObject.h b/Modules/Core/SpatialObjects/include/otbLineSpatialObject.h
deleted file mode 100644
index 7ac1a390c7ab37fd2103791d117f8bcc069fb500..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbLineSpatialObject.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLineSpatialObject_h
-#define otbLineSpatialObject_h
-
-#include "itkPointBasedSpatialObject.h"
-#include "itkLineSpatialObjectPoint.h"
-
-namespace otb
-{
-/** \class LineSpatialObject
- *  \brief Representation of a Line based on the spatial object classes.
- *
- * The Line is basically defined by a set of points.
- *
- * \sa LineSpatialObjectPoint
- *
- * \ingroup OTBSpatialObjects
- */
-template <unsigned int VDimension = 3>
-class ITK_EXPORT LineSpatialObject
-  : public itk::PointBasedSpatialObject<VDimension>
-{
-public:
-  /** Standard typedefs */
-  typedef LineSpatialObject                        Self;
-  typedef itk::PointBasedSpatialObject<VDimension> Superclass;
-  typedef itk::SmartPointer<Self>                  Pointer;
-  typedef itk::SmartPointer<const Self>            ConstPointer;
-
-  /** Type macro */
-  itkNewMacro(Self);
-
-  /** Method for creation through the object factory. */
-  itkTypeMacro(LineSpatialObject, PointBasedSpatialObject);
-
-  /** Superclass typedefs */
-  typedef typename Superclass::SpatialObjectPointType SpatialObjectPointType;
-  typedef typename Superclass::PointType              PointType;
-  typedef typename Superclass::TransformType          TransformType;
-  typedef typename Superclass::BoundingBoxType        BoundingBoxType;
-
-  /** Additional typedefs */
-  typedef double                                         ScalarType;
-  typedef itk::LineSpatialObjectPoint<VDimension>        LinePointType;
-  typedef std::vector<LinePointType>                     PointListType;
-  typedef itk::VectorContainer<unsigned long, PointType> PointContainerType;
-  typedef itk::SmartPointer<PointContainerType>          PointContainerPointer;
-  typedef itk::SizeValueType SizeValueType;
-  typedef itk::IdentifierType IdentifierType;
-
-  /** Returns a reference to the list of the Line points.*/
-  PointListType& GetPoints(void);
-
-  /** Set the list of line points. */
-  void SetPoints(PointListType& newPoints);
-
-  /** Return a point in the list given the index */
-  const SpatialObjectPointType* GetPoint(IdentifierType id) const override
-  {
-    return &(m_Points[id]);
-  }
-
-  /** Return a point in the list given the index */
-  SpatialObjectPointType* GetPoint(IdentifierType id) override
-  {
-    return &(m_Points[id]);
-  }
-
-  /** Return the number of points in the list */
-  SizeValueType GetNumberOfPoints(void) const override
-  {
-    return m_Points.size();
-  }
-
-  /** Returns true if the line is evaluable at the requested point,
-   *  false otherwise. */
-  bool IsEvaluableAt(const PointType& point,
-                     unsigned int depth = 0, char * name = nullptr) const override;
-
-  /** Returns the value of the line at that point.
-   * Currently this function returns a binary value,
-   * but it might want to return a degree of membership
-   * in case of fuzzy Lines. */
-  bool ValueAt(const PointType& point, double& value,
-               unsigned int depth = 0, char * name = nullptr) const override;
-
-  /** Returns true if the point is inside the line, false otherwise. */
-  bool IsInside(const PointType& point,
-                unsigned int depth, char * name) const override;
-
-  /** Test whether a point is inside or outside the object
-   *  For computational speed purposes, it is faster if the method does not
-   *  check the name of the class and the current depth */
-  virtual bool IsInside(const PointType& point) const;
-
-  /** Compute the boundaries of the line.*/
-  bool ComputeLocalBoundingBox() const override;
-
-protected:
-  /** Constructor */
-  LineSpatialObject();
-  /** Destructor */
-  ~LineSpatialObject() override;
-  /** Method to print the object. */
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-  LineSpatialObject(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-  /** Point list */
-  PointListType m_Points;
-};
-} // End namespace otb
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbLineSpatialObject.hxx"
-#endif
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbLineSpatialObject.hxx b/Modules/Core/SpatialObjects/include/otbLineSpatialObject.hxx
deleted file mode 100644
index ecacfe40745b7ce266d8d256262b10e6920ffb01..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbLineSpatialObject.hxx
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLineSpatialObject_hxx
-#define otbLineSpatialObject_hxx
-
-
-#include "otbLineSpatialObject.h"
-#include "otbMacro.h"
-
-namespace otb
-{
-/** Constructor */
-template<unsigned int VDimension>
-LineSpatialObject<VDimension>
-::LineSpatialObject()
-{
-  this->SetDimension(VDimension);
-  this->SetTypeName("LineSpatialObject");
-  this->GetProperty()->SetRed(1);
-  this->GetProperty()->SetGreen(0);
-  this->GetProperty()->SetBlue(0);
-  this->GetProperty()->SetAlpha(1);
-  this->ComputeBoundingBox();
-}
-
-/** Destructor */
-template<unsigned int VDimension>
-LineSpatialObject<VDimension>
-::~LineSpatialObject()
-{}
-
-/** Returns a reference to the list of the Line points.*/
-template<unsigned int VDimension>
-typename LineSpatialObject<VDimension>::PointListType&
-LineSpatialObject<VDimension>
-::GetPoints()
-{
-  // otbMsgDevMacro( "Getting LinePoint list" );
-  return m_Points;
-}
-
-/** Set the list of Line points. */
-template<unsigned int VDimension>
-void
-LineSpatialObject<VDimension>
-::SetPoints(PointListType& points)
-{
-  // in this function, passing a null pointer as argument will
-  // just clear the list...
-  m_Points.clear();
-
-  typename PointListType::iterator it, end;
-  it = points.begin();
-  end = points.end();
-  while (it != end)
-    {
-    m_Points.push_back(*it);
-    ++it;
-    }
-
-  this->ComputeBoundingBox();
-  this->Modified();
-}
-
-/** Print the object. */
-template<unsigned int VDimension>
-void
-LineSpatialObject<VDimension>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  os << indent << "LineSpatialObject(" << this << ")" << std::endl;
-  os << indent << "ID: " << this->GetId() << std::endl;
-  os << indent << "nb of points: " << static_cast<unsigned long>(m_Points.size()) << std::endl;
-  Superclass::PrintSelf(os, indent);
-}
-
-/** Compute the boundaries of the line.*/
-template<unsigned int VDimension>
-bool
-LineSpatialObject<VDimension>
-::ComputeLocalBoundingBox() const
-{
-  // tbMsgDevMacro( "Computing tube bounding box" );
-  if (this->GetBoundingBoxChildrenName().empty()
-      || strstr(typeid(Self).name(), this->GetBoundingBoxChildrenName().c_str()))
-    {
-    typename PointListType::const_iterator it  = m_Points.begin();
-    typename PointListType::const_iterator end = m_Points.end();
-
-    if (it == end)
-      {
-      return false;
-      }
-    else
-      {
-      PointType pt = this->GetIndexToWorldTransform()->TransformPoint((*it).GetPosition());
-      PointType ptmin;
-      PointType ptmax;
-      ptmin[0] = pt[0] - 1;
-      ptmin[1] = pt[1] - 1;
-      ptmax[0] = pt[0] + 1;
-      ptmax[1] = pt[1] + 1;
-      const_cast<BoundingBoxType *>(this->GetBounds())->SetMinimum(ptmin);
-      const_cast<BoundingBoxType *>(this->GetBounds())->SetMaximum(ptmax);
-      ++it;
-      while (it != end)
-        {
-
-        PointType pt2 = this->GetIndexToWorldTransform()->TransformPoint((*it).GetPosition());
-        const_cast<BoundingBoxType *>(this->GetBounds())->ConsiderPoint(pt2);
-        ++it;
-        }
-
-      }
-    }
-
-  return true;
-}
-
-/** Test whether a point is inside or outside the object
-*  For computational speed purposes, it is faster if the method does not
-*  check the name of the class and the current depth */
-template<unsigned int VDimension>
-bool
-LineSpatialObject<VDimension>
-::IsInside(const PointType& point) const
-{
-  typename PointListType::const_iterator it1 = m_Points.begin();
-  typename PointListType::const_iterator end = m_Points.end();
-  typename PointListType::const_iterator it2 = it1 + 1;
-  if (!this->GetIndexToWorldTransform()->GetInverse(const_cast<TransformType *>(this->GetInternalInverseTransform())))
-    {
-    return false;
-    }
-
-  PointType transformedPoint = this->GetInternalInverseTransform()->TransformPoint(point);
-
-  if (this->GetBounds()->IsInside(transformedPoint))
-    {
-    while (it2 != end)
-      {
-      if ((*it1).GetPosition()[0] < (*it2).GetPosition()[0])
-        {
-        if (transformedPoint[1] ==
-            (int) ((*it1).GetPosition()[1] +
-                   (((*it2).GetPosition()[1] -
-                     (*it1).GetPosition()[1]) /
-                    ((*it2).GetPosition()[0] -
-                     (*it1).GetPosition()[0])) * (transformedPoint[0] - (*it1).GetPosition()[0])) &&
-            transformedPoint[0] >= (*it1).GetPosition()[0] && transformedPoint[0] <= (*it2).GetPosition()[0])
-          {
-          return true;
-          }
-        }
-      else
-        {
-        if (transformedPoint[1] ==
-            (int) ((((*it2).GetPosition()[1] -
-                     (*it1).GetPosition()[1]) /
-                    ((*it1).GetPosition()[0] -
-                     (*it2).GetPosition()[0])) *
-                   ((*it1).GetPosition()[0] - transformedPoint[0]) + (*it1).GetPosition()[1]) &&
-            transformedPoint[0] >= (*it2).GetPosition()[0] && transformedPoint[0] <= (*it1).GetPosition()[0])
-          {
-          return true;
-          }
-        }
-      if ((*it1).GetPosition()[1] < (*it2).GetPosition()[1])
-        {
-        if (transformedPoint[0] ==
-            (int) ((((*it2).GetPosition()[0] -
-                     (*it1).GetPosition()[0]) /
-                    ((*it2).GetPosition()[1] -
-                     (*it1).GetPosition()[1])) *
-                   (transformedPoint[1] - (*it1).GetPosition()[1]) + (*it1).GetPosition()[0]) &&
-            transformedPoint[1] >= (*it1).GetPosition()[1] && transformedPoint[1] <= (*it2).GetPosition()[1])
-          {
-          return true;
-          }
-        }
-      else
-        {
-        if (transformedPoint[0] ==
-            (int) ((((*it2).GetPosition()[0] -
-                     (*it1).GetPosition()[0]) /
-                    ((*it1).GetPosition()[1] -
-                     (*it2).GetPosition()[1])) *
-                   ((*it1).GetPosition()[1] - transformedPoint[1]) + (*it1).GetPosition()[0]) &&
-            transformedPoint[1] >= (*it2).GetPosition()[1] && transformedPoint[1] <= (*it1).GetPosition()[1])
-          {
-          return true;
-          }
-        }
-      it1++;
-      ++it2;
-      }
-
-    }
-  return false;
-}
-
-/** Check if a given point is inside a line
-*  return True only if the point is in the point list */
-template<unsigned int VDimension>
-bool
-LineSpatialObject<VDimension>
-::IsInside(const PointType& point, unsigned int depth, char * name) const
-{
-  // otbMsgDevMacro( "Checking the point [" << point << "] is on the Line" );
-
-  if (name == nullptr)
-    {
-    if (IsInside(point))
-      {
-      return true;
-      }
-    }
-  else if (strstr(typeid(Self).name(), name))
-    {
-    if (IsInside(point))
-      {
-      return true;
-      }
-    }
-  return Superclass::IsInside(point, depth, name);
-}
-
-/** Returns true if the line is evaluable at the requested point,
-*  false otherwise. */
-template<unsigned int VDimension>
-bool
-LineSpatialObject<VDimension>
-::IsEvaluableAt(const PointType& point, unsigned int depth, char * name) const
-{
-  // otbMsgDevMacro( "Checking if the tube is evaluable at " << point );
-  return IsInside(point, depth, name);
-}
-
-/** Returns the value of the line at that point.
-* Currently this function returns a binary value,
-* but it might want to return a degree of membership
-* in case of fuzzy Lines. */
-template<unsigned int VDimension>
-bool
-LineSpatialObject<VDimension>
-::ValueAt(const PointType& point, double& value, unsigned int depth,
-          char * name) const
-{
-  // otbMsgDevMacro( "Getting the value of the tube at " << point );
-
-  if (IsInside(point, 0, name))
-    {
-    value = this->GetDefaultInsideValue();
-    return true;
-    }
-  else
-    {
-    if (Superclass::IsEvaluableAt(point, depth, name))
-      {
-      Superclass::ValueAt(point, value, depth, name);
-      return true;
-      }
-    else
-      {
-      value = this->GetDefaultOutsideValue();
-      return false;
-      }
-    }
-  return false;
-}
-} // end namespace otb
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbLineSpatialObjectList.h b/Modules/Core/SpatialObjects/include/otbLineSpatialObjectList.h
deleted file mode 100644
index e0e1e7790a9257f40c2670bfab14b3dfe066b5a1..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbLineSpatialObjectList.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLineSpatialObjectList_h
-#define otbLineSpatialObjectList_h
-
-
-#include "itkDataObject.h"
-#include "itkLineSpatialObject.h"
-
-#include <list>
-
-namespace otb
-{
-/** \class LineSpatialObjectList
- * \brief TODO
- *
- * \ingroup OTBSpatialObjects
- */
-
-class ITK_EXPORT LineSpatialObjectList :        public std::list<itk::LineSpatialObject<2>::Pointer>,
-  public itk::DataObject
-
-{
-public:
-  /** Standard class typedefs. */
-  typedef LineSpatialObjectList Self;
-  typedef itk::DataObject       Superclass;
-
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(LineSpatialObjectList, itk::DataObject);
-
-  /** Some convenient typedefs. */
-  typedef itk::LineSpatialObject<2> LineType;
-
-protected:
-  LineSpatialObjectList() {};
-  ~LineSpatialObjectList() override {}
-
-private:
-  LineSpatialObjectList(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-};
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbLineSpatialObjectListToPointSetFilter.h b/Modules/Core/SpatialObjects/include/otbLineSpatialObjectListToPointSetFilter.h
deleted file mode 100644
index df4f95ba78eee398db62eba603031988944252d2..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbLineSpatialObjectListToPointSetFilter.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLineSpatialObjectListToPointSetFilter_h
-#define otbLineSpatialObjectListToPointSetFilter_h
-
-
-#include "itkProcessObject.h"
-#include "otbLineSpatialObjectList.h"
-
-namespace otb
-{
-/** \class LineSpatialObjectListToPointSetFilter
- *  \brief Base class for all process objects that output PointSets And use LineSpatialObjectList
- *         as input.
- *
- *
- *
- * \ingroup OTBSpatialObjects
- */
-
-template <class TLinesList, class TPointSet>
-class ITK_EXPORT LineSpatialObjectListToPointSetFilter : public itk::ProcessObject
-{
-public:
-
-  /** Standard class typedefs. */
-  typedef LineSpatialObjectListToPointSetFilter Self;
-  typedef itk::ProcessObject                    Superclass;
-  typedef itk::SmartPointer<Self>               Pointer;
-  typedef itk::SmartPointer<const Self>         ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(LineSpatialObjectListToPointSetFilter, itk::ProcessObject);
-
-  /** Some convenient typedefs. */
-  typedef TLinesList                       LinesListType;
-  typedef typename LinesListType::LineType LineType;
-
-  /** typedef support for output*/
-  typedef TPointSet PointSetType;
-
-  typedef itk::ProcessObject ProcessObjectType;
-
-  /** Set/Get the input image */
-  using Superclass::SetInput;
-  virtual void SetInput(const LinesListType *list);
-  virtual const LinesListType* GetInput(void);
-
-  /** Set/Get the list of LineSpatialObject of this process object.  */
-  using Superclass::SetOutput;
-  virtual void SetOutput(const PointSetType *pointSet);
-  virtual PointSetType* GetOutput(void);
-
-protected:
-  LineSpatialObjectListToPointSetFilter();
-  ~LineSpatialObjectListToPointSetFilter() override {}
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-  LineSpatialObjectListToPointSetFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-};
-
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbLineSpatialObjectListToPointSetFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbLineSpatialObjectListToPointSetFilter.hxx b/Modules/Core/SpatialObjects/include/otbLineSpatialObjectListToPointSetFilter.hxx
deleted file mode 100644
index 0f1bc79ebf5d627253222d0a7b13e0c1e9f4e21b..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbLineSpatialObjectListToPointSetFilter.hxx
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLineSpatialObjectListToPointSetFilter_hxx
-#define otbLineSpatialObjectListToPointSetFilter_hxx
-
-#include "otbLineSpatialObjectListToPointSetFilter.h"
-
-namespace otb
-{
-
-/**
- *
- */
-template<class TLinesList, class TPointSet>
-LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>::LineSpatialObjectListToPointSetFilter()
-{
-  this->SetNumberOfRequiredInputs(1);
-  this->SetNumberOfRequiredOutputs(1);
-
-  this->SetNthOutput(0, PointSetType::New());
-
-}
-
-template<class TLinesList, class TPointSet>
-void
-LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>
-::SetInput(const LinesListType *list)
-{
-  this->itk::ProcessObject::SetNthInput(0,
-                                        const_cast<LinesListType  *>(list));
-}
-
-template<class TLinesList, class TPointSet>
-const typename LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>::LinesListType*
-LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>
-::GetInput(void)
-{
-  return static_cast<const LinesListType *>
-           (this->itk::ProcessObject::GetInput(0));
-}
-
-template<class TLinesList, class TPointSet>
-void
-LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>
-::SetOutput(const PointSetType *pointSet)
-{
-  this->ProcessObjectType::SetNthOutput(0,
-                                        const_cast<PointSetType *>(pointSet));
-}
-
-template<class TLinesList, class TPointSet>
-typename LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>::PointSetType*
-LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>
-::GetOutput(void)
-{
-  return static_cast<PointSetType *>
-           (this->ProcessObjectType::GetOutput(0));
-}
-
-/**
- *
- */
-
-template<class TLinesList, class TPointSet>
-void
-LineSpatialObjectListToPointSetFilter<TLinesList, TPointSet>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbSpatialObjectSource.h b/Modules/Core/SpatialObjects/include/otbSpatialObjectSource.h
deleted file mode 100644
index 9c15b4c57c2bc365135db7dd79353c058d08511e..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbSpatialObjectSource.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbSpatialObjectSource_h
-#define otbSpatialObjectSource_h
-
-#include "otbMacro.h"
-#include "itkProcessObject.h"
-
-namespace otb
-{
-/**
- * \class SpatialObjectSource
- * \brief Base class for filters producing a SpatialObject as output.
- * \ingroup DataSources
- *
- * \ingroup OTBSpatialObjects
- */
-template <class TSpatialObject>
-class ITK_EXPORT SpatialObjectSource
-  : public itk::ProcessObject
-{
-public:
-  /** Standard typedefs */
-  typedef SpatialObjectSource           Self;
-  typedef itk::ProcessObject            Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Creation through the object factory */
-  itkNewMacro(Self);
-
-  /** Runtime information */
-  itkTypeMacro(SpatialObjectSource, itk::ProcessObject);
-
-  /** Template parameters typedefs */
-  typedef TSpatialObject                      SpatialObjectType;
-  typedef typename SpatialObjectType::Pointer SpatialObjectPointerType;
-
-  /** Data object pointer */
-  typedef itk::DataObject::Pointer DataObjectPointer;
-
-  /**
-   * Get the output spatial object.
-   * \return The output spatial object.
-   */
-  virtual SpatialObjectType * GetOutput(void);
-
-protected:
-  /** Constructor */
-  SpatialObjectSource();
-  /** Destructor */
-  ~SpatialObjectSource() override {}
-  /** PrintSelf method */
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-  SpatialObjectSource(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-};
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbSpatialObjectSource.hxx"
-#endif
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbSpatialObjectSource.hxx b/Modules/Core/SpatialObjects/include/otbSpatialObjectSource.hxx
deleted file mode 100644
index 9082ee2f6051d4afd35ad41a616dddab68f6fdb1..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbSpatialObjectSource.hxx
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbSpatialObjectSource_hxx
-#define otbSpatialObjectSource_hxx
-
-#include "otbSpatialObjectSource.h"
-
-namespace otb
-{
-/**
- * Constructor.
- */
-template <class TSpatialObject>
-SpatialObjectSource<TSpatialObject>
-::SpatialObjectSource()
-{
-  this->Superclass::SetNumberOfRequiredOutputs(1);
-  this->Superclass::SetNthOutput(0, TSpatialObject::New().GetPointer());
-}
-/**
- * Get the output image list
- * \return The image list produced.
- */
-template <class TSpatialObject>
-typename SpatialObjectSource<TSpatialObject>::SpatialObjectType *
-SpatialObjectSource<TSpatialObject>
-::GetOutput(void)
-{
-  if (this->GetNumberOfOutputs() < 1)
-    {
-    return nullptr;
-    }
-  return static_cast<SpatialObjectType *> (this->ProcessObject::GetOutput(0));
-}
-/**
- * PrintSelf Method
- */
-template<class TSpatialObject>
-void
-SpatialObjectSource<TSpatialObject>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-} // end namespace otb
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.h b/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.h
deleted file mode 100644
index 71cab8ace54a7fe7d359189c6bebaa0c4c2c10b9..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbSpatialObjectToImageDrawingFilter_h
-#define otbSpatialObjectToImageDrawingFilter_h
-
-#include "itkImageSource.h"
-#include "itkConceptChecking.h"
-#include "itkSpatialObject.h"
-
-namespace otb
-{
-
-/** \class SpatialObjectToImageDrawingFilter
- * \brief Base class for filters that take a SpatialObject
- *        as input and produce an image as output.
- *  By default, if the user does not specify the size of the output image,
- *  the maximum size of the object's bounding box is used.
- *  The spacing of the image is given by the spacing of the input
- *  Spatial object.
- *
- * \ingroup OTBSpatialObjects
- */
-template <class TInputSpatialObject, class TOutputImage>
-class ITK_EXPORT SpatialObjectToImageDrawingFilter : public itk::ImageSource<TOutputImage>
-{
-public:
-  /** Standard class typedefs. */
-  typedef SpatialObjectToImageDrawingFilter     Self;
-  typedef itk::ImageSource<TOutputImage>        Superclass;
-  typedef itk::SmartPointer<Self>               Pointer;
-  typedef itk::SmartPointer<const Self>         ConstPointer;
-  typedef typename TOutputImage::SizeType       SizeType;
-  typedef typename TOutputImage::PointType      PointType;
-  typedef TOutputImage                          OutputImageType;
-  typedef typename OutputImageType::Pointer     OutputImagePointer;
-  typedef typename OutputImageType::ValueType   ValueType;
-  typedef typename OutputImageType::SpacingType SpacingType;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(SpatialObjectToImageDrawingFilter, itk::ImageSource);
-
-  /** Superclass typedefs. */
-  typedef typename Superclass::OutputImageRegionType OutputImageRegionType;
-
-  /** Some convenient typedefs. */
-  typedef TInputSpatialObject                            InputSpatialObjectType;
-  typedef typename InputSpatialObjectType::Pointer       InputSpatialObjectPointer;
-  typedef typename InputSpatialObjectType::ConstPointer  InputSpatialObjectConstPointer;
-  typedef typename TInputSpatialObject::ChildrenListType ChildrenListType;
-
-  /** ImageDimension constants */
-  itkStaticConstMacro(ObjectDimension, unsigned int,
-                      InputSpatialObjectType::ObjectDimension);
-  itkStaticConstMacro(OutputImageDimension, unsigned int,
-                      TOutputImage::ImageDimension);
-
-  /** Set/Get the image input of this process object.  */
-  using Superclass::SetInput;
-  virtual void SetInput(const InputSpatialObjectType *object);
-  virtual void SetInput(unsigned int, const InputSpatialObjectType * object);
-  const InputSpatialObjectType * GetInput(void);
-  const InputSpatialObjectType * GetInput(unsigned int idx);
-
-  /** Spacing (size of a pixel) of the output image. The
-   * spacing is the geometric distance between image samples.
-   * It is stored internally as double, but may be set from
-   * float. \sa GetSpacing() */
-  virtual void SetSpacing(const SpacingType& spacing);
-  virtual void SetSpacing(const double* spacing);
-  virtual void SetSpacing(const float* spacing);
-  virtual const double* GetSpacing() const;
-
-  /** Set/Get the value for pixels inside the spatial object.
-  * By default, this filter will return an image
-  * that contains values from the spatial object specified as input.
-  * If this "inside" value is changed to a non-null value,
-  * the output produced by this filter will be a mask with inside/outside values
-  * specified by the user. */
-  itkSetMacro(InsideValue, ValueType);
-  itkGetMacro(InsideValue, ValueType);
-
-  /** Set/Get the value for pixels outside the spatial object.
-  * By default, this filter will return an image
-  * that contains values from the spatial object specified as input.
-  * If this "outside" value is changed to a non-null value,
-  * the output produced by this filter will be a mask with inside/outside values
-  * specified by the user. */
-  itkSetMacro(OutsideValue, ValueType);
-  itkGetMacro(OutsideValue, ValueType);
-
-  /** The origin of the output image. The origin is the geometric
-   * coordinates of the index (0, 0, ..., 0).  It is stored internally
-   * as double but may be set from float.
-   * \sa GetOrigin() */
-  virtual void SetOrigin(const PointType& origin);
-  virtual void SetOrigin(const double* origin);
-  virtual void SetOrigin(const float* origin);
-  virtual const double * GetOrigin() const;
-
-  /** The spatial object being transformed can be part of a hierarchy.
-   * How deep in the hierarchy should we descend in generating the
-   * image?  A ChildrenDepth of 0 means to only include the object
-   * itself. */
-  itkSetMacro(ChildrenDepth, unsigned int);
-  itkGetMacro(ChildrenDepth, unsigned int);
-
-  /** Set/Get Size */
-  itkSetMacro(Size, SizeType);
-  itkGetMacro(Size, SizeType);
-
-  /** If UseObjectValue is set to true, then the filter uses
-   *  the ValueAt() function instead of IsInside() */
-  itkSetMacro(UseObjectValue, bool);
-  itkGetMacro(UseObjectValue, bool);
-
-  typedef itk::SpatialObject<InputSpatialObjectType::ObjectDimension> SpatialObjectType;
-  typedef typename SpatialObjectType::ChildrenListType*               ChildrenType;
-  typedef typename SpatialObjectType::ChildrenListType::iterator      IteratorType;
-
-protected:
-  SpatialObjectToImageDrawingFilter();
-  ~SpatialObjectToImageDrawingFilter() override;
-
-  void GenerateOutputInformation() override; // do nothing
-  void GenerateData() override;
-
-  SizeType     m_Size;
-  double       m_Spacing[OutputImageDimension];
-  double       m_Origin[OutputImageDimension];
-  unsigned int m_ChildrenDepth;
-  ValueType    m_InsideValue;
-  ValueType    m_OutsideValue;
-  bool         m_UseObjectValue;
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-  SpatialObjectToImageDrawingFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-};
-
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbSpatialObjectToImageDrawingFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.hxx b/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.hxx
deleted file mode 100644
index 873cd8123a0504216f1806f632e7c9b8e8bd63bc..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.hxx
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbSpatialObjectToImageDrawingFilter_hxx
-#define otbSpatialObjectToImageDrawingFilter_hxx
-
-#include "otbSpatialObjectToImageDrawingFilter.h"
-#include "itkImageRegionIteratorWithIndex.h"
-
-namespace otb
-{
-
-/** Constructor */
-template <class TInputSpatialObject, class TOutputImage>
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SpatialObjectToImageDrawingFilter()
-{
-  this->SetNumberOfRequiredInputs(1);
-  m_ChildrenDepth = 1;
-  m_Size.Fill(0);
-
-  for (unsigned int i = 0; i < OutputImageDimension; ++i)
-    {
-    m_Spacing[i] = 1.0;
-    m_Origin[i] = 0.;
-    }
-
-  m_InsideValue = 0;
-  m_OutsideValue = 0;
-  m_UseObjectValue = false;
-}
-
-/** Destructor */
-template <class TInputSpatialObject, class TOutputImage>
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::~SpatialObjectToImageDrawingFilter()
-{
-}
-
-/** Set the Input SpatialObject */
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetInput(const InputSpatialObjectType *input)
-{
-
-  // Process object is not const-correct so the const_cast is required here
-  this->itk::ProcessObject::SetNthInput(0,
-                                        const_cast<InputSpatialObjectType *>(input));
-}
-
-/** Connect one of the operands  */
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetInput(unsigned int index, const TInputSpatialObject * object)
-{
-  // Process object is not const-correct so the const_cast is required here
-  this->itk::ProcessObject::SetNthInput(index,
-                                        const_cast<TInputSpatialObject *>(object));
-}
-
-/** Get the input Spatial Object */
-template <class TInputSpatialObject, class TOutputImage>
-const typename SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>::InputSpatialObjectType *
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::GetInput(void)
-{
-  if (this->GetNumberOfInputs() < 1)
-    {
-    return nullptr;
-    }
-
-  return static_cast<const TInputSpatialObject *>
-           (this->itk::ProcessObject::GetInput(0));
-}
-
-/** Get the input Spatial Object */
-template <class TInputSpatialObject, class TOutputImage>
-const typename SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>::InputSpatialObjectType *
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::GetInput(unsigned int idx)
-{
-  return static_cast<const TInputSpatialObject *>
-           (this->itk::ProcessObject::GetInput(idx));
-}
-
-//----------------------------------------------------------------------------
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetSpacing(const SpacingType& spacing)
-{
-  unsigned int i;
-  for (i = 0; i < TOutputImage::ImageDimension; ++i)
-    {
-    if ((double) spacing[i] != m_Spacing[i])
-      {
-      break;
-      }
-    }
-  if (i < TOutputImage::ImageDimension)
-    {
-    for (i = 0; i < TOutputImage::ImageDimension; ++i)
-      {
-      m_Spacing[i] = spacing[i];
-      }
-    this->Modified();
-    }
-}
-
-//----------------------------------------------------------------------------
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetSpacing(const double* spacing)
-{
-  unsigned int i;
-  for (i = 0; i < OutputImageDimension; ++i)
-    {
-    if (spacing[i] != m_Spacing[i])
-      {
-      break;
-      }
-    }
-  if (i < OutputImageDimension)
-    {
-    for (i = 0; i < OutputImageDimension; ++i)
-      {
-      m_Spacing[i] = spacing[i];
-      }
-    }
-}
-
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetSpacing(const float* spacing)
-{
-  unsigned int i;
-  for (i = 0; i < OutputImageDimension; ++i)
-    {
-    if ((double) spacing[i] != m_Spacing[i])
-      {
-      break;
-      }
-    }
-  if (i < OutputImageDimension)
-    {
-    for (i = 0; i < OutputImageDimension; ++i)
-      {
-      m_Spacing[i] = spacing[i];
-      }
-    }
-}
-
-template <class TInputSpatialObject, class TOutputImage>
-const double *
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::GetSpacing() const
-{
-  return m_Spacing;
-}
-
-//----------------------------------------------------------------------------
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetOrigin(const PointType& origin)
-{
-  unsigned int i;
-  for (i = 0; i < TOutputImage::ImageDimension; ++i)
-    {
-    if ((double) origin[i] != m_Origin[i])
-      {
-      break;
-      }
-    }
-  if (i < TOutputImage::ImageDimension)
-    {
-    for (i = 0; i < TOutputImage::ImageDimension; ++i)
-      {
-      m_Origin[i] = origin[i];
-      }
-    this->Modified();
-    }
-}
-
-//----------------------------------------------------------------------------
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetOrigin(const double* origin)
-{
-  unsigned int i;
-  for (i = 0; i < OutputImageDimension; ++i)
-    {
-    if (origin[i] != m_Origin[i])
-      {
-      break;
-      }
-    }
-  if (i < OutputImageDimension)
-    {
-    for (i = 0; i < OutputImageDimension; ++i)
-      {
-      m_Origin[i] = origin[i];
-      }
-    this->Modified();
-    }
-}
-
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::SetOrigin(const float* origin)
-{
-  unsigned int i;
-  for (i = 0; i < OutputImageDimension; ++i)
-    {
-    if ((double) origin[i] != m_Origin[i])
-      {
-      break;
-      }
-    }
-  if (i < OutputImageDimension)
-    {
-    for (i = 0; i < OutputImageDimension; ++i)
-      {
-      m_Origin[i] = origin[i];
-      }
-    this->Modified();
-    }
-}
-
-template <class TInputSpatialObject, class TOutputImage>
-const double *
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::GetOrigin() const
-{
-  return m_Origin;
-}
-
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::GenerateOutputInformation()
-{
-  const InputSpatialObjectType * InputObject  = this->GetInput();
-  OutputImagePointer             OutputImage = this->GetOutput();
-
-  unsigned int i;
-  // Generate the image
-  SizeType size;
-  double   origine[ObjectDimension];
-  InputObject->ComputeBoundingBox();
-  bool originspecified = false;
-  if (!strcmp(InputObject->GetNameOfClass(), "GroupSpatialObject"))
-    {
-    ChildrenType children;
-    children = InputObject->GetChildren(0);
-    IteratorType iter = children->begin();
-    IteratorType end = children->end();
-    double       minimum[ObjectDimension];
-
-    (*iter)->ComputeBoundingBox();
-    for (i = 0; i < ObjectDimension; ++i)
-      {
-      minimum[i] = (*iter)->GetBoundingBox()->GetMinimum()[i];
-      }
-
-    while (iter != end)
-      {
-      (*iter)->ComputeBoundingBox();
-      for (i = 0; i < ObjectDimension; ++i)
-        {
-        if ((*iter)->GetBoundingBox()->GetMinimum()[i] < minimum[i])
-          {
-          minimum[i] = (*iter)->GetBoundingBox()->GetMinimum()[i];
-          }
-        }
-      ++iter;
-      }
-
-    for (i = 0; i < ObjectDimension; ++i)
-      {
-      size[i] = (long unsigned int) (InputObject->GetBoundingBox()->GetMaximum()[i] - minimum[i]) + 1;
-      origine[i] = (long int) minimum[i];
-      originspecified = true;
-      }
-
-    itkDebugMacro(
-      << "minx= " << minimum[0] << ", miny= " << minimum[0] << ", maxx= " <<
-      InputObject->GetBoundingBox()->GetMaximum()[0] << ", maxy= " << InputObject->GetBoundingBox()->GetMaximum()[1]);
-    }
-  else
-    {
-
-    for (i = 0; i < ObjectDimension; ++i)
-      {
-      size[i] = (long int) (InputObject->GetBoundingBox()->GetMaximum()[i]
-                            - InputObject->GetBoundingBox()->GetMinimum()[i]);
-      }
-    }
-
-  typename OutputImageType::IndexType index;
-  index.Fill(0);
-  typename OutputImageType::RegionType region;
-
-  // If the size of the output has been explicitly specified, the filter
-  // will set the output size to the explicit size, otherwise the size from the spatial
-  // object's bounding box will be used as default.
-
-  bool specified = false;
-  for (i = 0; i < OutputImageDimension; ++i)
-    {
-    if (m_Size[i] != 0)
-      {
-      specified = true;
-      break;
-      }
-    }
-
-  if (specified)
-    {
-    region.SetSize(m_Size);
-    }
-  else
-    {
-    region.SetSize (size);
-    m_Size = size;
-    }
-  region.SetIndex(index);
-
-  OutputImage->SetLargestPossibleRegion(region);
-  specified = false;
-  for (i = 0; i < OutputImageDimension; ++i)
-    {
-    if (m_Spacing[i] != 0)
-      {
-      specified = true;
-      break;
-      }
-    }
-
-  if (specified)
-    {
-    OutputImage->SetSignedSpacing(this->m_Spacing);           // set spacing
-    }
-  else
-    {
-    OutputImage->SetSignedSpacing(InputObject->GetIndexToObjectTransform()->GetScaleComponent());     // set spacing
-    m_Spacing[0] = InputObject->GetIndexToObjectTransform()->GetScaleComponent()[0];
-    m_Spacing[1] = InputObject->GetIndexToObjectTransform()->GetScaleComponent()[1];
-    }
-
-  if (originspecified)
-    {
-    origine[0] += 0.5 * m_Spacing[0];
-    origine[1] += 0.5 * m_Spacing[1];
-    OutputImage->SetOrigin(origine);     //   and origin
-    m_Origin[0] = OutputImage->GetOrigin()[0];
-    m_Origin[1] = OutputImage->GetOrigin()[1];
-
-    }
-  else OutputImage->SetOrigin(m_Origin);
-}
-
-//----------------------------------------------------------------------------
-
-/** Update */
-template <class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::GenerateData(void)
-{
-  itkDebugMacro(<< "SpatialObjectToImageDrawingFilter::Update() called");
-
-  // Get the input and output pointers
-  const InputSpatialObjectType * InputObject  = this->GetInput();
-  OutputImagePointer             OutputImage = this->GetOutput();
-
-  typename OutputImageType::RegionType region = OutputImage->GetLargestPossibleRegion();
-  OutputImage->SetBufferedRegion(region);             // set the region
-  OutputImage->SetRequestedRegion(region);            //
-
-  OutputImage->Allocate();   // allocate the image
-
-  typedef itk::ImageRegionIteratorWithIndex<OutputImageType> myIteratorType;
-
-  myIteratorType it(OutputImage, region);
-
-  itk::Point<double, ObjectDimension> point;
-
-  while (!it.IsAtEnd())
-    {
-
-    // ValueAt requires the point to be in physical coordinate i.e
-    for (unsigned int i = 0; i < ObjectDimension; ++i)
-      {
-      point[i] = (int) (it.GetIndex()[i] * m_Spacing[i]) + m_Origin[i];
-      }
-    double val = 0;
-
-    InputObject->ValueAt(point, val, 99999);
-    if (m_InsideValue != 0 ||  m_OutsideValue != 0)
-      {
-      if (val)
-        {
-        if (m_UseObjectValue)
-          {
-          it.Set(static_cast<ValueType>(val));
-          }
-        else
-          {
-          it.Set(m_InsideValue);
-          }
-        }
-      else
-        {
-        it.Set(m_OutsideValue);
-        }
-      }
-    else
-      {
-      it.Set(static_cast<ValueType>(val));
-      }
-    ++it;
-    }
-
-  itkDebugMacro(<< "SpatialObjectToImageDrawingFilter::Update() finished");
-
-} // end update function
-
-template<class TInputSpatialObject, class TOutputImage>
-void
-SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-  os << indent << "Size : " << m_Size << std::endl;
-  os << indent << "Children depth : " << m_ChildrenDepth << std::endl;
-  os << indent << "Inside Value : " << m_InsideValue << std::endl;
-  os << indent << "Outside Value : " << m_OutsideValue << std::endl;
-  if (m_UseObjectValue)
-    {
-    os << indent << "Using Object Value : ON" << std::endl;
-    }
-  else
-    {
-    os << indent << "Using Object Value : OFF" << std::endl;
-    }
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Core/SpatialObjects/otb-module.cmake b/Modules/Core/SpatialObjects/otb-module.cmake
deleted file mode 100644
index a7bf9767e6f963552e1f238c3be36858cf3a6979..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/otb-module.cmake
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
-#
-# This file is part of Orfeo Toolbox
-#
-#     https://www.orfeo-toolbox.org/
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-set(DOCUMENTATION "Geometric shapes are represented in OTB using the ITK
-spatial object hierarchy. These classes are intended to support modelling of anatomical
-structures in ITK. OTB uses them in order to model cartographic elements. Using
-a common basic interface, the spatial objects are capable of representing regions
-of space in a variety of different ways. For example: mesh structures, image
-masks, and implicit equations may be used as the underlying representation scheme.
-Spatial objects are a natural data structure for communicating the results of
-segmentation methods and for introducing geometrical priors in both segmentation and
-registration methods.")
-
-otb_module(OTBSpatialObjects
-  DEPENDS
-    OTBCommon
-    OTBITK
-
-  TEST_DEPENDS
-    OTBTestKernel
-    OTBImageIO
-    OTBImageBase
-
-  DESCRIPTION
-    "${DOCUMENTATION}"
-)
diff --git a/Modules/Core/SpatialObjects/test/CMakeLists.txt b/Modules/Core/SpatialObjects/test/CMakeLists.txt
deleted file mode 100644
index ceddc82d0993b7a73c9b69ad4fa23c35d0e7e46e..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/test/CMakeLists.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
-#
-# This file is part of Orfeo Toolbox
-#
-#     https://www.orfeo-toolbox.org/
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-otb_module_test()
-
-set(OTBSpatialObjectsTests
-otbSpatialObjectsTestDriver.cxx
-otbSpatialObjectToImageDrawingFilter.cxx
-otbDrawLineSpatialObject.cxx
-otbLineSpatialObjectList.cxx
-otbDrawLineSpatialObjectList.cxx
-)
-
-add_executable(otbSpatialObjectsTestDriver ${OTBSpatialObjectsTests})
-target_link_libraries(otbSpatialObjectsTestDriver ${OTBSpatialObjects-Test_LIBRARIES})
-otb_module_target_label(otbSpatialObjectsTestDriver)
-
-# Tests Declaration
-otb_add_test(NAME bfTvSpatialObjectToImageDrawingFilterWithoutInputImage COMMAND otbSpatialObjectsTestDriver
-  --compare-image ${NOTOL}
-  ${BASELINE}/bfTvSpatialObjectDrawingNoInput.png
-  ${TEMP}/bfTvSpatialObjectDrawingNoInput.png
-  otbSpatialObjectToImageDrawingFilter
-  ${TEMP}/bfTvSpatialObjectDrawingNoInput.png
-  100
-  50
-  )
-
-
-otb_add_test(NAME coTuDrawLineSpatialObject COMMAND otbSpatialObjectsTestDriver
-  otbDrawLineSpatialObject
-  ${INPUTDATA}/ImageLineDir.bsq
-  ${TEMP}/coFiltreDrawLine_ImageLineDir.png 10. 22. 38. 42.)
-
-otb_add_test(NAME coTuLineSpatialObjectList COMMAND otbSpatialObjectsTestDriver
-  otbLineSpatialObjectList
-  )
-
-otb_add_test(NAME coTuDrawLineSpatialObjectList COMMAND otbSpatialObjectsTestDriver
-  otbDrawLineSpatialObjectList
-  ${INPUTDATA}/ImageLineDir.bsq
-  ${TEMP}/coFiltreDrawLineList_ImageLineDir.png )
diff --git a/Modules/Core/SpatialObjects/test/otbDrawLineSpatialObject.cxx b/Modules/Core/SpatialObjects/test/otbDrawLineSpatialObject.cxx
deleted file mode 100644
index cd0b8010bad369f9deb8c2ce214d59d192c16a55..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/test/otbDrawLineSpatialObject.cxx
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-#include "itkMacro.h"
-#include <iostream>
-#include <list>
-
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-
-#include "otbDrawLineSpatialObjectFilter.h"
-
-int otbDrawLineSpatialObject(int itkNotUsed(argc), char * argv[])
-{
-  const char * inputFilename  = argv[1];
-  const char * outputFilename = argv[2];
-
-  // two points to represent a straight line
-  double Ux((double) ::atof(argv[3]));
-  double Uy((double) ::atof(argv[4]));
-  double Vx((double) ::atof(argv[5]));
-  double Vy((double) ::atof(argv[6]));
-
-  typedef double        InputPixelType;
-  typedef unsigned char OutputPixelType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<InputPixelType,  Dimension> InputImageType;
-  typedef otb::Image<OutputPixelType, Dimension> OutputImageType;
-
-  typedef otb::DrawLineSpatialObjectFilter<InputImageType, OutputImageType> FilterType;
-
-  FilterType::Pointer filter = FilterType::New();
-
-  typedef otb::ImageFileReader<InputImageType>  ReaderType;
-  typedef otb::ImageFileWriter<OutputImageType> WriterType;
-
-  ReaderType::Pointer reader = ReaderType::New();
-  WriterType::Pointer writer = WriterType::New();
-
-  reader->SetFileName(inputFilename);
-
-  writer->SetFileName(outputFilename);
-
-  // Definition of the line
-  typedef itk::LineSpatialObject<2> LineType;
-  LineType::PointListType list;
-  LineType::LinePointType point;
-
-  point.SetPosition(Ux, Uy);
-  list.push_back(point);
-  point.SetPosition(Vx, Vy);
-  list.push_back(point);
-
-  LineType::Pointer line = LineType::New();
-  line->SetId(0);
-  line->SetPoints(list);
-  line->ComputeBoundingBox();
-
-  filter->SetValue(static_cast<OutputPixelType>(245));
-  filter->SetInputLine(line);
-  filter->SetInput(reader->GetOutput());
-
-  writer->SetInput(filter->GetOutput());
-  writer->Update();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Core/SpatialObjects/test/otbDrawLineSpatialObjectList.cxx b/Modules/Core/SpatialObjects/test/otbDrawLineSpatialObjectList.cxx
deleted file mode 100644
index c43c46d12b1f038b3c548dafedfbc45fff93b871..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/test/otbDrawLineSpatialObjectList.cxx
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-#include "itkMacro.h"
-
-#include <iostream>
-#include <list>
-
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-
-#include "otbDrawLineSpatialObjectListFilter.h"
-
-int otbDrawLineSpatialObjectList(int itkNotUsed(argc), char * argv[])
-{
-  const char * inputFilename  = argv[1];
-  const char * outputFilename = argv[2];
-
-  typedef double        InputPixelType;
-  typedef unsigned char OutputPixelType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<InputPixelType,  Dimension> InputImageType;
-  typedef otb::Image<OutputPixelType, Dimension> OutputImageType;
-
-  typedef otb::DrawLineSpatialObjectListFilter<InputImageType, OutputImageType> FilterType;
-
-  FilterType::Pointer filter = FilterType::New();
-
-  typedef otb::ImageFileReader<InputImageType>  ReaderType;
-  typedef otb::ImageFileWriter<OutputImageType> WriterType;
-
-  ReaderType::Pointer reader = ReaderType::New();
-  WriterType::Pointer writer = WriterType::New();
-
-  reader->SetFileName(inputFilename);
-  writer->SetFileName(outputFilename);
-
-  typedef otb::LineSpatialObjectList LinesListType;
-  typedef LinesListType::LineType    LineType;
-  LinesListType::Pointer list = LinesListType::New();
-
-  LineType::PointListType pointList;
-  LineType::LinePointType point;
-
-  // Definition of the first line
-  double Ux, Uy, Vx, Vy;
-  Ux = 10.;
-  Uy = 12.;
-  Vx = 35.;
-  Vy = 29.;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line = LineType::New();
-  line->SetId(0);
-  line->SetPoints(pointList);
-  line->ComputeBoundingBox();
-
-  list->push_back(line);
-
-  pointList.clear();
-
-  // Definition of a second line
-  Ux = 8.;
-  Uy = 7.;
-  Vx = 8.;
-  Vy = 46.;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line2 = LineType::New();
-  line2->SetId(0);
-  line2->SetPoints(pointList);
-  line2->ComputeBoundingBox();
-
-  list->push_back(line2);
-
-  pointList.clear();
-
-  // Definition of a third line
-  Ux = 52.;
-  Uy = 15.;
-  Vx = 22.;
-  Vy = 38.;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line3 = LineType::New();
-  line3->SetId(0);
-  line3->SetPoints(pointList);
-  line3->ComputeBoundingBox();
-
-  list->push_back(line3);
-
-  /*        LinesListType::const_iterator it;
-      std::cout<<list.size()<<std::endl;
-      for (it=list.begin(); it!=list.end(); ++it)
-      std::cout<< (*it) <<std::endl; */
-
-  filter->SetInputLineSpatialObjectList(list);
-
-  filter->SetInput(reader->GetOutput());
-  writer->SetInput(filter->GetOutput());
-
-  writer->Update();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Core/SpatialObjects/test/otbLineSpatialObjectList.cxx b/Modules/Core/SpatialObjects/test/otbLineSpatialObjectList.cxx
deleted file mode 100644
index d04d0c0c7555d9ea95e447c554bb0940c6685fc8..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/test/otbLineSpatialObjectList.cxx
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "itkMacro.h"
-
-#include "otbLineSpatialObjectList.h"
-#include <list>
-
-int otbLineSpatialObjectList(int itkNotUsed(argc), char * itkNotUsed(argv) [])
-{
-  typedef otb::LineSpatialObjectList                         LineSpatialObjectListType;
-  typedef LineSpatialObjectListType::LineType                LineSpatialObjecType;
-  typedef LineSpatialObjectListType::LineType::PointListType PointListType;
-  typedef LineSpatialObjectListType::const_iterator          LineSpatialObjectListConstIterator;
-
-  LineSpatialObjectListType::Pointer listLines = LineSpatialObjectListType::New();
-  for (int i = 0; i < 10; ++i)
-    {
-    LineSpatialObjecType::Pointer lLine = LineSpatialObjecType::New();
-    listLines->push_back(lLine);
-    }
-
-  LineSpatialObjectListConstIterator lIter;
-  lIter = listLines->begin();
-  while (lIter != listLines->end())
-    {
-    LineSpatialObjecType::Pointer lLine = (*lIter);
-    PointListType                 lPoints = lLine->GetPoints();
-    lIter++;
-    }
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Core/SpatialObjects/test/otbSpatialObjectToImageDrawingFilter.cxx b/Modules/Core/SpatialObjects/test/otbSpatialObjectToImageDrawingFilter.cxx
deleted file mode 100644
index ff491d146f367b317eb67bbb6800444bd533e5d7..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/test/otbSpatialObjectToImageDrawingFilter.cxx
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "itkMacro.h"
-
-#include "otbSpatialObjectToImageDrawingFilter.h"
-#include "itkEllipseSpatialObject.h"
-#include "otbImageFileWriter.h"
-#include "otbImage.h"
-
-int otbSpatialObjectToImageDrawingFilter(int itkNotUsed(argc), char * argv[])
-{
-  const char *       outputFilename = argv[1];
-  const double       radiusx = atof(argv[2]);
-  const double       radiusy = atof(argv[3]);
-  const unsigned int Dimension = 2;
-  typedef unsigned char                                                        PixelType;
-  typedef otb::Image<PixelType, Dimension>                                     ImageType;
-  typedef otb::ImageFileWriter<ImageType>                                      WriterType;
-  typedef itk::EllipseSpatialObject<Dimension>                                 SpatialObjectType;
-  typedef otb::SpatialObjectToImageDrawingFilter<SpatialObjectType, ImageType> SpatialObjectToImageDrawingFilterType;
-  // Instantiating object
-  SpatialObjectToImageDrawingFilterType::Pointer filter = SpatialObjectToImageDrawingFilterType::New();
-  WriterType::Pointer                            writer = WriterType::New();
-
-  SpatialObjectType::Pointer   ellipse = SpatialObjectType::New();
-  SpatialObjectType::ArrayType radius;
-  radius[0] = radiusx;
-  radius[1] = radiusy;
-
-  ellipse->SetRadius(radius);
-
-  ImageType::PointType origin;
-  origin[0] = -radiusx;
-  origin[1] = -radiusy;
-  filter->SetInput(ellipse);
-  filter->SetOrigin(origin);
-  filter->SetInsideValue(255);
-  filter->SetOutsideValue(0);
-
-  writer->SetInput(filter->GetOutput());
-  writer->SetFileName(outputFilename);
-  writer->Update();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Core/SpatialObjects/test/otbSpatialObjectsTestDriver.cxx b/Modules/Core/SpatialObjects/test/otbSpatialObjectsTestDriver.cxx
deleted file mode 100644
index 9f015fb3f5005318b72e4e5ec38aae9f847c10eb..0000000000000000000000000000000000000000
--- a/Modules/Core/SpatialObjects/test/otbSpatialObjectsTestDriver.cxx
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbTestMain.h"
-
-void RegisterTests()
-{
-  REGISTER_TEST(otbSpatialObjectToImageDrawingFilter);
-  REGISTER_TEST(otbDrawLineSpatialObject);
-  REGISTER_TEST(otbLineSpatialObjectList);
-  REGISTER_TEST(otbDrawLineSpatialObjectList);
-}
diff --git a/Modules/Core/Transform/include/otbGenericMapProjection.hxx b/Modules/Core/Transform/include/otbGenericMapProjection.hxx
index 3f2f092abb6ef75a7a50416b0eba74de90ac2504..6cb2fd375434345ae4f6a5775d8ccfe204ab5bf3 100644
--- a/Modules/Core/Transform/include/otbGenericMapProjection.hxx
+++ b/Modules/Core/Transform/include/otbGenericMapProjection.hxx
@@ -70,6 +70,11 @@ GenericMapProjection<TDirectionOfMapping, TScalarType, NInputDimensions, NOutput
   SpatialReference wgs84 = SpatialReference::FromWGS84();
   SpatialReference wktSpatialReference = SpatialReference::FromDescription(projectionRefWkt);
 
+#if GDAL_VERSION_NUM >= 3000000
+  wgs84.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
+  wktSpatialReference.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
+#endif
+  
   if(DirectionOfMapping == TransformDirection::INVERSE)
     {
     std::unique_ptr<CoordinateTransformation> newMapProjection(new CoordinateTransformation(wktSpatialReference,wgs84));
diff --git a/Modules/Core/Transform/test/otbGenericMapProjection.cxx b/Modules/Core/Transform/test/otbGenericMapProjection.cxx
index aab5d3a818114695593068d4580023bf1866803e..70b56b81d596ff2065bf6cf5177b91254929dd36 100644
--- a/Modules/Core/Transform/test/otbGenericMapProjection.cxx
+++ b/Modules/Core/Transform/test/otbGenericMapProjection.cxx
@@ -23,7 +23,7 @@
 #include <iomanip>
 
 #include "otbGenericMapProjection.h"
-
+#include "ogr_spatialref.h"
 int otbGenericMapProjection(int itkNotUsed(argc), char* argv[])
 {
   const char *  outFileName = argv[1];
@@ -35,11 +35,19 @@ int otbGenericMapProjection(int itkNotUsed(argc), char* argv[])
   /** Test the ability to instantiate a projection from a string*/
   std::string projectionRefWkt =
     "PROJCS[\"UTM Zone 31, Northern Hemisphere\", GEOGCS[\"WGS 84\", DATUM[\"WGS_1984\", SPHEROID[\"WGS 84\", 6378137, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], TOWGS84[0, 0, 0, 0, 0, 0, 0], AUTHORITY[\"EPSG\",\"6326\"]], PRIMEM[\"Greenwich\", 0, AUTHORITY[\"EPSG\",\"8901\"]], UNIT[\"degree\", 0.0174532925199433, AUTHORITY[\"EPSG\",\"9108\"]], AXIS[\"Lat\", NORTH], AXIS[\"Long\", EAST], AUTHORITY[\"EPSG\",\"4326\"]], PROJECTION[\"Transverse_Mercator\"], PARAMETER[\"latitude_of_origin\", 0], PARAMETER[\"central_meridian\", 3], PARAMETER[\"scale_factor\", 0.9996], PARAMETER[\"false_easting\", 500000], PARAMETER[\"false_northing\", 0], UNIT[\"Meter\", 1]]";
-
+  auto baselineSpatialReference = otb::SpatialReference::FromDescription(projectionRefWkt);
+  
   typedef otb::GenericMapProjection<otb::TransformDirection::FORWARD> GenericMapProjection;
   GenericMapProjection::Pointer genericMapProjection = GenericMapProjection::New();
   genericMapProjection->SetWkt(projectionRefWkt);
-  file << genericMapProjection->GetWkt() << std::endl << std::endl;
+
+  auto testSpatialReferenceForward = otb::SpatialReference::FromDescription(genericMapProjection->GetWkt());
+
+  if (testSpatialReferenceForward!=baselineSpatialReference)
+  {
+    std::cerr << "The spatial reference used in the forward test is different from the input spatial reference" << std::endl;
+    return EXIT_FAILURE;
+  }
 
   itk::Point<double, 2> point;
   point[0] = 1.44;
@@ -52,7 +60,14 @@ int otbGenericMapProjection(int itkNotUsed(argc), char* argv[])
   typedef otb::GenericMapProjection<otb::TransformDirection::INVERSE> GenericMapProjectionInverse;
   GenericMapProjectionInverse::Pointer genericMapProjectionInverse = GenericMapProjectionInverse::New();
   genericMapProjectionInverse->SetWkt(projectionRefWkt);
-  file << genericMapProjectionInverse->GetWkt() << std::endl << std::endl;
+
+  auto testSpatialReferenceReverse = otb::SpatialReference::FromDescription(genericMapProjectionInverse->GetWkt());
+
+  if (testSpatialReferenceForward!=baselineSpatialReference)
+  {
+    std::cerr << "The spatial reference used in the reverse test is different from the input spatial reference" << std::endl;
+    return EXIT_FAILURE;
+  }
 
   point[0] = 374100.8;
   point[1] = 4829184.8;
diff --git a/Modules/Feature/Corner/include/otbLineSpatialObjectListToRightAnglePointSetFilter.h b/Modules/Feature/Corner/include/otbLineSpatialObjectListToRightAnglePointSetFilter.h
deleted file mode 100644
index 901b4a4d9e69b2456f0edef626064bc22451c605..0000000000000000000000000000000000000000
--- a/Modules/Feature/Corner/include/otbLineSpatialObjectListToRightAnglePointSetFilter.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLineSpatialObjectListToRightAnglePointSetFilter_h
-#define otbLineSpatialObjectListToRightAnglePointSetFilter_h
-
-#include "itkPointSet.h"
-#include "otbLineSpatialObjectListToPointSetFilter.h"
-#include "otbMath.h"
-#include "itkVariableSizeMatrix.h"
-
-namespace otb
-{
-
-/** \class LineSpatialObjectListToRightAnglePointSetFilter
- * \brief TODO
- *
- * \ingroup OTBCorner
- */
-
-template <class TImage, class TLinesList, class TPointSet>
-class ITK_EXPORT LineSpatialObjectListToRightAnglePointSetFilter
-  : public otb::LineSpatialObjectListToPointSetFilter <TLinesList, TPointSet>
-{
-
-public:
-
-  /** Standard class typedefs. */
-  typedef LineSpatialObjectListToRightAnglePointSetFilter               Self;
-  typedef LineSpatialObjectListToPointSetFilter <TLinesList, TPointSet> Superclass;
-  typedef itk::SmartPointer<Self>                                       Pointer;
-  typedef itk::SmartPointer<const Self>                                 ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(LineSpatialObjectListToRightAnglePointSetFilter, LineSpatialObjectListToPointSetFilter);
-
-  /** Typedef support for ProcessObject*/
-  typedef itk::ProcessObject ProcessObjectType;
-
-  /** Template parameters typedefs*/
-  typedef TLinesList                            InputLinesListType;
-  typedef typename InputLinesListType::LineType LineType;
-  typedef std::vector<LineType*>                VectorLineType;
-  //typedef typename LineType::PointListType            InputPointListType;
-  typedef typename InputLinesListType::const_iterator InputLinesListTypeIterator;
-
-  /**  Typdedef for The input image  :
-   *   (ONLY USED FOR THE LINE ITERATOR -> To check if the index is inside the region)
-   */
-  typedef TImage                             InputImageType;
-  typedef typename InputImageType::IndexType InputIndexType;
-
-  /** Typedef support for output PointSet*/
-  typedef TPointSet                              OutputPointSetType;
-  typedef typename OutputPointSetType::PointType PointType;
-  typedef typename OutputPointSetType::Pointer   OutputPointSetPointerType;
-
-  /** Typedef Support  for Checking couple of segments used*/
-  typedef itk::VariableSizeMatrix<unsigned int> checkMatrixType;
-
-  /**
-   *  Public Methods :
-   *       Get the Input Image & Get The input Image
-   */
-  virtual InputImageType* GetInputImage();
-
-  virtual void SetInputImage(InputImageType *);
-
-  /** Set/Get the thresholds*/
-  itkGetMacro(ThresholdDistance, double);
-  itkSetMacro(ThresholdDistance, double);
-
-  itkGetMacro(ThresholdAngle, double);
-  itkSetMacro(ThresholdAngle, double);
-
-protected:
-
-  /**
-   * Without the GenerateOutputInformation below it does not work
-   * Because the ProcessObject class do a static_cast to allow memory and copy
-   * the output (here a pointset). It works fine with images but with pointsets
-   * no size is specified ...
-   * the aim of the GenerateOutputInformation below is to avoid the guilty static_cast
-   *
-   */
-
-  void GenerateOutputInformation() override{}
-
-  /**
-   * Constructor.
-   */
-  LineSpatialObjectListToRightAnglePointSetFilter();
-  /**
-   * Destructor.
-   */
-  ~LineSpatialObjectListToRightAnglePointSetFilter() override{}
-  /**
-   * Standard PrintSelf method.
-   */
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-  /**
-   * Main computation method.
-   */
-  void  GenerateData() override;
-  /**
-   * Angle computation
-   */
-  virtual double ComputeAngleFormedBySegments(LineType * lineDst, LineType * lineSrc);
-  /**
-   *  When we find a right angle, one compute the coordinate of the segments intersection
-   */
-  virtual PointType ComputeAngleRightCoordinate(LineType * lineDst, LineType * lineSrc);
-  /**
-   * AddRightAngleToPointSet
-   */
-  virtual void AddRightAngleToPointSet(PointType rAngle, LineType * LineDst, LineType* LineCur);
-  /**
-   * Compute the orienation of a segment
-   */
-  virtual double ComputeOrientation(LineType* line);
-  /**
-   * Distance From a point rAngle to a segment line
-   */
-  virtual double ComputeDistanceFromPointToSegment(PointType rAngle, LineType * line);
-
-private:
-
-  LineSpatialObjectListToRightAnglePointSetFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-  /** Smart pointer on the output PointSet*/
-  OutputPointSetPointerType m_OutputPointSet;
-
-  double m_ThresholdDistance;
-  double m_ThresholdAngle;
-
-};
-}
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbLineSpatialObjectListToRightAnglePointSetFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Feature/Corner/include/otbLineSpatialObjectListToRightAnglePointSetFilter.hxx b/Modules/Feature/Corner/include/otbLineSpatialObjectListToRightAnglePointSetFilter.hxx
deleted file mode 100644
index dedbbc966f787aff6e06696125820387a6c3bb8e..0000000000000000000000000000000000000000
--- a/Modules/Feature/Corner/include/otbLineSpatialObjectListToRightAnglePointSetFilter.hxx
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLineSpatialObjectListToRightAnglePointSetFilter_hxx
-#define otbLineSpatialObjectListToRightAnglePointSetFilter_hxx
-
-#include "otbLineSpatialObjectListToRightAnglePointSetFilter.h"
-#include "itkLineIterator.h"
-#include "itkMatrix.h"
-#include "vnl/vnl_math.h"
-
-namespace otb
-{
-
-/**
- *
- */
-template <class TImage, class TLinesList, class TPointSet>
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::LineSpatialObjectListToRightAnglePointSetFilter()
-{
-  this->SetNumberOfRequiredInputs(2);
-  this->SetNumberOfRequiredOutputs(1);
-
-  m_ThresholdDistance = 20.;
-  m_ThresholdAngle = CONST_PI / 30.;  //36 cause we want 6 degrees threshold
-}
-
-/**
- * Method : Set The Input Image
- */
-template <class TImage, class TLinesList, class TPointSet>
-void
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::SetInputImage(InputImageType * inputImage)
-{
-  this->itk::ProcessObject::SetNthInput(1,
-                                        const_cast<InputImageType *>(inputImage));
-}
-
-/**
-* Method : Get The Input Image
-*/
-template <class TImage, class TLinesList, class TPointSet>
-typename LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::InputImageType *
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::GetInputImage()
-{
-  return static_cast<InputImageType *>
-           (this->ProcessObjectType::GetInput(1));
-}
-
-/**
- * Method : GenerateData()
- */
-template <class TImage, class TLinesList, class TPointSet>
-void
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::GenerateData()
-{
-  unsigned int counterTest = 0, counterCur = 0;
-
-  /** Output*/
-  m_OutputPointSet = this->GetOutput();
-
-  /** Get The input Lines*/
-  typename InputLinesListType::Pointer inputLinesList = const_cast<InputLinesListType *>(this->GetInput());
-
-  /** Instancition of Checking availability Matrix*/
-  unsigned int numberOfLines = inputLinesList->size();
-  checkMatrixType              segmentsUsedMatrix(numberOfLines, numberOfLines);
-  segmentsUsedMatrix.Fill(0);
-
-  /** Loop to get all the lines in the listLine */
-  InputLinesListTypeIterator itLinesListTest  = inputLinesList->begin();               /** Current tested Line */
-
-  while (itLinesListTest != inputLinesList->end())
-    {
-    counterCur = 0;
-    InputLinesListTypeIterator itLinesListCur   = inputLinesList->begin();                 /** Line tested with with current Line*/
-    InputLinesListTypeIterator itLinesListCurEnd   = inputLinesList->end();
-
-    while (itLinesListCur != itLinesListCurEnd)
-      {
-      /** Check If segments are already computed */
-      if (segmentsUsedMatrix[counterTest][counterCur] == 0 && segmentsUsedMatrix[counterCur][counterTest] == 0)
-        {
-        /** Set the segments to USED (== 1)*/
-        segmentsUsedMatrix[counterTest][counterCur] = 1;
-        segmentsUsedMatrix[counterCur][counterTest] = 1;
-
-        /** Compute the angle formed by the two segments */
-        double Angle = this->ComputeAngleFormedBySegments(*itLinesListTest, *itLinesListCur);
-
-        /** Check if the angle is a right one */
-        if (std::abs(Angle - CONST_PI_2) <= m_ThresholdAngle)
-          {
-          /** Right angle coordinate*/
-          PointType RightAngleCoordinate;
-          RightAngleCoordinate = this->ComputeAngleRightCoordinate(*itLinesListTest, *itLinesListCur);
-
-          /** Compute the distance between the two segments and the right angle formed by this segments*/
-          double dist1 = this->ComputeDistanceFromPointToSegment(RightAngleCoordinate, *itLinesListTest);
-          double dist2 = this->ComputeDistanceFromPointToSegment(RightAngleCoordinate, *itLinesListCur);
-
-          /** Use Pythagore to compute the distance between the two segments*/
-          double SegmentDistance = std::sqrt(dist1 * dist1 + dist2 * dist2);
-
-//                 if(this->ComputeDistanceFromPointToSegment(RightAngleCoordinate, *itLinesListTest) <m_ThresholdDistance &&
-//                    this->ComputeDistanceFromPointToSegment(RightAngleCoordinate, *itLinesListCur) <m_ThresholdDistance)
-          if (SegmentDistance < m_ThresholdDistance)
-            {
-            /** If Right Angle & not so far from segments:  Add it to the pointSet*/
-            this->AddRightAngleToPointSet(RightAngleCoordinate, *itLinesListTest, *itLinesListCur);
-            }
-          }
-        }
-      ++counterCur;
-      ++itLinesListCur;
-      }
-    ++counterTest;
-    ++itLinesListTest;
-    }
-}
-
-/**
- * Method : Compute Distance between a point and a segment
- *
- */
-template <class TImage, class TLinesList, class TPointSet>
-double
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::ComputeDistanceFromPointToSegment(PointType rAngle, LineType * line)
-{
-  /** Extract Indexes from the Dst line to instantiate the line iterator*/
-  typename LineType::PointListType&                pointsListDst = line->GetPoints();
-  typename LineType::PointListType::const_iterator itPointsDst = pointsListDst.begin();
-  double                                           X1 = (*itPointsDst).GetPosition()[0]; //xq1
-  double                                           Y1 = (*itPointsDst).GetPosition()[1]; //yq1
-  ++itPointsDst;
-  double X2 = (*itPointsDst).GetPosition()[0];  //xq2
-  double Y2 = (*itPointsDst).GetPosition()[1];  //yq2
-
-  double dist1 = std::sqrt((X1 - rAngle[0]) * (X1 - rAngle[0]) + (Y1 - rAngle[1]) * (Y1 - rAngle[1]));
-  double dist2 = std::sqrt((X2 - rAngle[0]) * (X2 - rAngle[0]) + (Y2 - rAngle[1]) * (Y2 - rAngle[1]));
-
-  return std::min(dist1, dist2);
-}
-
-/**
- * Method : Compute Angle formed by the two segments
- *
- */
-template <class TImage, class TLinesList, class TPointSet>
-double
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::ComputeAngleFormedBySegments(LineType * lineDst, LineType * lineSrc)
-{
-  double oriDst = this->ComputeOrientation(lineDst);
-  double oriSrc = this->ComputeOrientation(lineSrc);
-
-  return std::abs(oriDst  - oriSrc);
-}
-
-/**
- * Method : ComputeDistanceBetweenSegments
- */
-template <class TImage, class TLinesList, class TPointSet>
-double
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::ComputeOrientation(LineType * line)
-{
-  typename LineType::PointListType&                pointsList = line->GetPoints();
-  typename LineType::PointListType::const_iterator itPoints = pointsList.begin();
-  double                                           Xp1 = (*itPoints).GetPosition()[0];
-  double                                           Yp1 = (*itPoints).GetPosition()[1];
-
-  ++itPoints;
-  double Xp2 = (*itPoints).GetPosition()[0];
-  double Yp2 = (*itPoints).GetPosition()[1];
-
-  //Compute the orientation
-  double dx = Xp1 - Xp2;
-  double dy = Yp1 - Yp2;
-  double orientation = std::atan2(dy, dx);
-  if (orientation < 0) orientation += CONST_PI;
-
-  return orientation;
-}
-
-/**
- * Method : ComputeDistanceBetweenSegments
- */
-template <class TImage, class TLinesList, class TPointSet>
-typename LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::PointType
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::ComputeAngleRightCoordinate(LineType * lineDst, LineType * lineSrc)
-{
-  PointType P;
-
-  /** ----- */
-  typename LineType::PointListType&                pointsList = lineSrc->GetPoints();
-  typename LineType::PointListType::const_iterator itPoints = pointsList.begin();
-
-  double Xp1 = (*itPoints).GetPosition()[0];
-  double Yp1 = (*itPoints).GetPosition()[1];
-  ++itPoints;
-  double Xp2 = (*itPoints).GetPosition()[0];
-  double Yp2 = (*itPoints).GetPosition()[1];
-
-  /** Extract Indexes from the Dst line to instantiate the line iterator*/
-  typename LineType::PointListType&                pointsListDst = lineDst->GetPoints();
-  typename LineType::PointListType::const_iterator itPointsDst = pointsListDst.begin();
-
-  double Xq1 = (*itPointsDst).GetPosition()[0];  //xq1
-  double Yq1 = (*itPointsDst).GetPosition()[1];  //yq1
-  ++itPointsDst;
-  double Xq2 = (*itPointsDst).GetPosition()[0];  //xq2
-  double Yq2 = (*itPointsDst).GetPosition()[1];  //yq2
-
-  /** Compute the equation of the lines A and B  which are support of the segments Src & Dst*/
-  // - Line 1 : slope and origin
-  double originA = 0., slopeA = 0.;
-  double originB = 0., slopeB = 0.;
-  double LengthSegmentAy = 0., lengthSegmentBy = 0.;
-
-  /** Equation of the first Line*/
-  if (std::abs(Xp2 - Xp1) < 1e-10) Xp2 = 0.0001;
-
-  if (Xp1 < Xp2) LengthSegmentAy = Yp2 - Yp1;
-  else LengthSegmentAy = Yp1 - Yp2;
-
-  slopeA = LengthSegmentAy / (Xp2 - Xp1);
-  originA = Yp1 - (slopeA * Xp1);
-
-  /** Equation of the second Line*/
-  if (std::abs(Xq2 - Xq1) < 1e-10) Xq2 = 0.0001;
-
-  if (Xq1 < Xq2) lengthSegmentBy = Yq2 - Yq1;
-  else lengthSegmentBy = Yq1 - Yq2;
-
-  slopeB = lengthSegmentBy / (Xq2 - Xq1);
-  originB = Yq1 - (slopeB * Xq1);
-
-  /** Avoid the case of parallel lines*/
-  double denum = 0.;
-  if (std::abs(slopeA - slopeB) < 1e-5) denum = 0.001;
-  else denum = slopeA - slopeB;
-
-  /** Compute the coordinate of the intersection point Y =AX+B*/
-  P[0] =  (originB - originA) / denum;
-  P[1] =  slopeA * static_cast<double>(P[0]) + originA;
-
-  return P;
-}
-
-/**
- * AddRightAngleToPointSet
- */
-template <class TImage, class TLinesList, class TPointSet>
-void
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::AddRightAngleToPointSet(PointType rAngle, LineType * LineDst, LineType* LineCur)
-{
-  unsigned int CurrentPos = m_OutputPointSet->GetNumberOfPoints();
-
-  m_OutputPointSet->SetPoint(CurrentPos, rAngle);
-  VectorLineType vectorLine;
-  vectorLine.push_back(LineDst);
-  vectorLine.push_back(LineCur);
-  m_OutputPointSet->SetPointData(CurrentPos, vectorLine);
-}
-
-/**
- * Standard "PrintSelf" method
- */
-template <class TImage, class TLinesList, class TPointSet>
-void
-LineSpatialObjectListToRightAnglePointSetFilter<TImage, TLinesList, TPointSet>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Feature/Corner/otb-module.cmake b/Modules/Feature/Corner/otb-module.cmake
index a9c8fc1d7627d90f341b0736c17831376ebfd9fc..147865d4342ccf726173e85c138007328d6b1fbc 100644
--- a/Modules/Feature/Corner/otb-module.cmake
+++ b/Modules/Feature/Corner/otb-module.cmake
@@ -27,7 +27,6 @@ otb_module(OTBCorner
     OTBVectorDataBase
     OTBITK
     OTBDescriptors
-    OTBSpatialObjects
     OTBVectorDataManipulation
     OTBPointSet
     OTBImageManipulation
diff --git a/Modules/Feature/Corner/test/CMakeLists.txt b/Modules/Feature/Corner/test/CMakeLists.txt
index 3e203c0f8145da40e27a886897ab1c537aac8ae6..a3ca01d0e8a1a1bc99e78c1f2b61b6d99f23e300 100644
--- a/Modules/Feature/Corner/test/CMakeLists.txt
+++ b/Modules/Feature/Corner/test/CMakeLists.txt
@@ -22,9 +22,7 @@ otb_module_test()
 
 set(OTBCornerTests
 otbCornerTestDriver.cxx
-otbLineSpatialObjectListToRightAnglePointSetFilter.cxx
 otbVectorDataToRightAngleVectorDataFilter.cxx
-otbLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii.cxx
 otbHarrisImage.cxx
 otbHarrisToPointSet.cxx
 )
@@ -35,15 +33,6 @@ otb_module_target_label(otbCornerTestDriver)
 
 # Tests Declaration
 
-otb_add_test(NAME feTvLineSpatialObjectListToRightAnglePointSetFilter COMMAND otbCornerTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvLineSpatialObjectListToRightAnglePointSetFilterOutputAscii.txt
-  ${TEMP}/feTvLineSpatialObjectListToRightAnglePointSetFilterOutputAscii.txt
-  otbLineSpatialObjectListToRightAnglePointSetFilter
-  ${INPUTDATA}/carre.png
-  ${TEMP}/feTvLineSpatialObjectListToRightAnglePointSetFilterOutputAscii.txt
-  )
-
 otb_add_test(NAME feTvVectorDataToRightAngleVectorDataFilter COMMAND otbCornerTestDriver
   --compare-ogr ${EPSILON_8}
   ${BASELINE_FILES}/feTvVectorDataToRightAngleVectorDataFilterOutput.shp
@@ -53,15 +42,6 @@ otb_add_test(NAME feTvVectorDataToRightAngleVectorDataFilter COMMAND otbCornerTe
   ${TEMP}/feTvVectorDataToRightAngleVectorDataFilterOutput.shp  #output text file
   )
 
-otb_add_test(NAME feTvLineSpatialObjectListToRightAnglePointSetFilterBySteps COMMAND otbCornerTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvLineSpatialObjectListToRightAnglePointSetFilterOutputAscii.txt
-  ${TEMP}/feTvLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii.txt
-  otbLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii
-  ${INPUTDATA}/carre.png
-  ${TEMP}/feTvLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii.txt
-  )
-
 otb_add_test(NAME feTvHarrisImage COMMAND otbCornerTestDriver
   --compare-image ${NOTOL}  ${BASELINE}/feHarrisImage.png
   ${TEMP}/feHarrisImage.png
diff --git a/Modules/Feature/Corner/test/otbCornerTestDriver.cxx b/Modules/Feature/Corner/test/otbCornerTestDriver.cxx
index 563056610d890357a97e646a9525ed1f0b76e5c4..216d2b09de346392ae50d3e51cb19dee80db9dc1 100644
--- a/Modules/Feature/Corner/test/otbCornerTestDriver.cxx
+++ b/Modules/Feature/Corner/test/otbCornerTestDriver.cxx
@@ -22,9 +22,7 @@
 
 void RegisterTests()
 {
-  REGISTER_TEST(otbLineSpatialObjectListToRightAnglePointSetFilter);
   REGISTER_TEST(otbVectorDataToRightAngleVectorDataFilter);
-  REGISTER_TEST(otbLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii);
   REGISTER_TEST(otbHarrisImage);
   REGISTER_TEST(otbHarrisToPointSet);
 }
diff --git a/Modules/Feature/Corner/test/otbLineSpatialObjectListToRightAnglePointSetFilter.cxx b/Modules/Feature/Corner/test/otbLineSpatialObjectListToRightAnglePointSetFilter.cxx
deleted file mode 100644
index a2387f903257b3bf469ac3ddd53f817f67c1cf74..0000000000000000000000000000000000000000
--- a/Modules/Feature/Corner/test/otbLineSpatialObjectListToRightAnglePointSetFilter.cxx
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "otbImage.h"
-#include "otbLineSpatialObjectListToRightAnglePointSetFilter.h"
-#include "otbLineSpatialObjectList.h"
-
-#include "otbImageFileReader.h"
-
-#include <iostream>
-#include <fstream>
-
-int otbLineSpatialObjectListToRightAnglePointSetFilter(int itkNotUsed(argc), char * argv[])
-{
-  const char * infname   = argv[1];
-  const char * outfname  = argv[2];
-
-  const unsigned int Dimension = 2;
-  typedef float PixelType;
-
-  /** Typedefs */
-  typedef otb::Image<PixelType, Dimension>      ImageType;
-  typedef otb::ImageFileReader<ImageType>       ReaderType;
-  typedef otb::LineSpatialObjectList            LinesListType;
-  typedef LinesListType::LineType               LineType;
-  typedef std::vector<LineType*>                VectorLines;
-  typedef itk::PointSet<VectorLines, Dimension> PointSetType;
-  typedef otb::LineSpatialObjectListToRightAnglePointSetFilter<ImageType, LinesListType,
-      PointSetType>    RightAngleFilterType;
-
-  /** Creatop, of an instance of the filters */
-  RightAngleFilterType::Pointer rightAngleFilter  = RightAngleFilterType::New();
-  ReaderType::Pointer           reader            = ReaderType::New();
-  PointSetType::Pointer         segmentOrtho      = PointSetType::New();
-
-  /** Creation of  lines */
-  LinesListType::Pointer  list = LinesListType::New();
-  LineType::PointListType pointList;
-  LineType::LinePointType point;
-
-  // Definition of the first line
-  float Ux, Uy, Vx, Vy;
-  Ux = 31.7;
-  Uy = 11.1;
-  Vx = 31.7;
-  Vy = 25.1;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line = LineType::New();
-  line->SetId(0);
-  line->SetPoints(pointList);
-  line->ComputeBoundingBox();
-
-  list->push_back(line);
-
-  pointList.clear();
-
-  // Definition of a second line
-  Ux = 10.1;
-  Uy = 10.7;
-  Vx = 30.1;
-  Vy = 10.6;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line2 = LineType::New();
-  line2->SetId(0);
-  line2->SetPoints(pointList);
-  line2->ComputeBoundingBox();
-
-  list->push_back(line2);
-
-  pointList.clear();
-
-  // Definition of a third line
-  Ux = 20.1;
-  Uy = 7.1;
-  Vx = 40.5;
-  Vy = 17.1;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line3 = LineType::New();
-  line3->SetId(0);
-  line3->SetPoints(pointList);
-  line3->ComputeBoundingBox();
-
-  list->push_back(line3);
-
-  // Begin the process
-  reader->SetFileName(infname);
-
-  rightAngleFilter->SetInputImage(reader->GetOutput());
-  rightAngleFilter->SetInput(list);
-  rightAngleFilter->Update();
-
-  /** Writing The result in the outfile*/
-  std::ofstream outfile(outfname);
-  outfile << "Number of right angles detected  " << rightAngleFilter->GetOutput()->GetNumberOfPoints() << std::endl;
-
-  /** Draw the orthogonal segments */
-  segmentOrtho = rightAngleFilter->GetOutput();
-  PointSetType::PointType pRight;
-
-  for (unsigned int i = 0; i < segmentOrtho->GetNumberOfPoints(); ++i)
-    {
-    segmentOrtho->GetPoint(i, &pRight);
-    outfile << " Right Angle found in point : " <<  pRight << std::endl;
-    }
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Corner/test/otbLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii.cxx b/Modules/Feature/Corner/test/otbLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii.cxx
deleted file mode 100644
index c019d966ef4984c1c8f6d7109c6c7ed71cb0e2b8..0000000000000000000000000000000000000000
--- a/Modules/Feature/Corner/test/otbLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii.cxx
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "otbImage.h"
-#include "otbLineSpatialObjectListToRightAnglePointSetFilter.h"
-#include "otbDrawLineSpatialObjectListFilter.h"
-
-#include "otbImageFileReader.h"
-
-#include <iostream>
-#include <fstream>
-
-int otbLineSpatialObjectListToRightAnglePointSetFilterByStepsOutputAscii(int itkNotUsed(argc), char * argv[])
-{
-  const char * infname   = argv[1];
-  const char * outfname  = argv[2];
-
-  const unsigned int Dimension = 2;
-  typedef float PixelType;
-
-  /** Typedefs */
-  typedef otb::Image<PixelType, Dimension>               ImageType;
-  typedef otb::ImageFileReader<ImageType>                ReaderType;
-  typedef otb::LineSpatialObjectList                     LinesListType;
-  typedef LinesListType::LineType                        LineType;
-  typedef std::vector<LineType*>                         VectorLines;
-  typedef itk::PointSet<VectorLines, Dimension>          PointSetType;
-  typedef otb::LineSpatialObjectListToRightAnglePointSetFilter<ImageType, LinesListType,
-      PointSetType>    RightAngleFilterType;
-
-  /** Creatop, of an instance of the filters */
-  RightAngleFilterType::Pointer rightAngleFilter  = RightAngleFilterType::New();
-  ReaderType::Pointer           reader            = ReaderType::New();
-  PointSetType::Pointer         segmentOrtho      = PointSetType::New();
-
-/** Creation of  lines */
-  LinesListType::Pointer  list = LinesListType::New();
-  LineType::PointListType pointList;
-  LineType::LinePointType point;
-
-  // Definition of the first line
-  float Ux, Uy, Vx, Vy;
-  Ux = 31.7;
-  Uy = 11.1;
-  Vx = 31.7;
-  Vy = 25.1;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line = LineType::New();
-  line->SetId(0);
-  line->SetPoints(pointList);
-  line->ComputeBoundingBox();
-
-  list->push_back(line);
-
-  pointList.clear();
-
-  // Definition of a second line
-  Ux = 10.1;
-  Uy = 10.7;
-  Vx = 30.1;
-  Vy = 10.6;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line2 = LineType::New();
-  line2->SetId(0);
-  line2->SetPoints(pointList);
-  line2->ComputeBoundingBox();
-
-  list->push_back(line2);
-
-  pointList.clear();
-
-  // Definition of a third line
-  Ux = 20.1;
-  Uy = 7.1;
-  Vx = 40.5;
-  Vy = 17.1;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line3 = LineType::New();
-  line3->SetId(0);
-  line3->SetPoints(pointList);
-  line3->ComputeBoundingBox();
-
-  list->push_back(line3);
-
-  // Begin the process
-  reader->SetFileName(infname);
-
-  rightAngleFilter->SetInputImage(reader->GetOutput());
-  rightAngleFilter->SetInput(list);
-  rightAngleFilter->Update();
-
-  std::cout << "Number of right angles detected  " << rightAngleFilter->GetOutput()->GetNumberOfPoints() << std::endl;
-
-  /** Print the right angles coordinate in the output file*/
-  segmentOrtho = rightAngleFilter->GetOutput();
-  PointSetType::PointType pRight;
-  VectorLines             outputVectorLines;
-  LinesListType::Pointer  outputLinesList = LinesListType::New();
-
-  std::ofstream outfile(outfname);
-  outfile << "Number of right angles detected  " << rightAngleFilter->GetOutput()->GetNumberOfPoints() << std::endl;
-
-  for (unsigned int i = 0; i < segmentOrtho->GetNumberOfPoints(); ++i)
-    {
-    segmentOrtho->GetPoint(i, &pRight);
-    outfile << " Right Angle found in point : " <<  pRight << std::endl;
-
-    /** Example To extract The coordinate of the segment (Just for example)*/
-    segmentOrtho->GetPointData(i, &outputVectorLines);
-    outputLinesList->push_back(outputVectorLines[0]);
-    outputLinesList->push_back(outputVectorLines[1]);
-    }
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Edge/CMakeLists.txt b/Modules/Feature/Edge/CMakeLists.txt
index ce7bdc154ca8bb9b4498cff008e90c08b1d37ca4..92c4040ae6226c975ac8bb34977ee1910c00776a 100644
--- a/Modules/Feature/Edge/CMakeLists.txt
+++ b/Modules/Feature/Edge/CMakeLists.txt
@@ -19,7 +19,4 @@
 #
 
 project(OTBEdge)
-
-set(OTBEdge_LIBRARIES OTBEdge)
-
 otb_module_impl()
diff --git a/Modules/Feature/Edge/include/otbExtractSegmentsImageFilter.h b/Modules/Feature/Edge/include/otbExtractSegmentsImageFilter.h
deleted file mode 100644
index 1711aee9af6e5349f280f5f2e165e7f13db829a7..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/include/otbExtractSegmentsImageFilter.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbExtractSegmentsImageFilter_h
-#define otbExtractSegmentsImageFilter_h
-
-
-#include "otbPixelSuppressionByDirectionImageFilter.h"
-#include "otbLocalHoughFilter.h"
-#include "otbFillGapsFilter.h"
-#include "otbDrawLineSpatialObjectListFilter.h"
-#include "itkRescaleIntensityImageFilter.h"
-
-
-namespace otb
-{
-
-/** \class ExtractSegmentsImageFilter
- *
- * This class implements a composite filter that generate an image of segments
- * primitives. It combines four filters :
- *   - otb::PixelSuppressionByDirectionImageFilter
- *   - otb::LocalHoughFilter
- *   - otb::FillGapsFilter
- *   - otb::DrawLineSpatialObjectListFilter
- *
- *
- * \ingroup OTBEdge
- */
-
-template <class TInputImage,
-    class TOutputImage>
-class ITK_EXPORT ExtractSegmentsImageFilter :
-  public itk::ImageToImageFilter<TInputImage, TOutputImage>
-{
-public:
-
-  itkStaticConstMacro(InputImageDimension,
-                      unsigned int,
-                      TInputImage::ImageDimension);
-  itkStaticConstMacro(OutputImageDimension,
-                      unsigned int,
-                      TOutputImage::ImageDimension);
-
-  typedef TInputImage  InputImageType;
-  typedef TOutputImage OutputImageType;
-
-  typedef TInputImage PSOutputImageType;
-
-  typedef ExtractSegmentsImageFilter                               Self;
-  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
-  typedef itk::SmartPointer<Self>                                  Pointer;
-  typedef itk::SmartPointer<const Self>                            ConstPointer;
-
-  itkNewMacro(Self);
-
-  itkTypeMacro(ExtractSegmentsImageFilter, itk::ImageToImageFilter);
-
-  typedef typename InputImageType::PixelType InputPixelType;
-  typedef typename InputImageType::SizeType  SizeType;
-
-  typedef typename OutputImageType::PixelType OutputPixelType;
-
-  /** Definition of the list of lines. */
-  typedef LineSpatialObjectList LinesListType;
-
-  /** Set/Get the radius of the region of the pixel suppression by direction image filter. */
-  void SetPixelSuppressionRadius(SizeType Radius);
-  const SizeType GetPixelSuppressionRadius();
-
-  /** Set/Get Angular Accuracy on the direction of the central pixel for
-      the pixel suppression by direction image filter. */
-  void SetPixelSuppressionAngularBeam(float AngularBeam);
-  float GetPixelSuppressionAngularBeam();
-
-  /** Set/Get the radius used to define the region of local hough filter. */
-  void SetLocalHoughRadius(SizeType Radius);
-  const SizeType GetLocalHoughRadius();
-
-  /** Set/Get the number of lines we are looking for in the local hough filter. */
-  void SetLocalHoughNumberOfLines(unsigned int Radius);
-  unsigned int GetLocalHoughNumberOfLines();
-
-  /** Set/Get the radius of the disc to remove from the accumulator
-   *  for each line found */
-  void SetLocalHoughDiscRadius(float DiscRadius);
-  float GetLocalHoughDiscRadius();
-
-  /** Set/Get the variance of the gaussian bluring for the accumulator */
-  void SetLocalHoughVariance(float Variance);
-  float GetLocalHoughVariance();
-
-  /** Set/Get the radius between two segments in the fill gaps filter. */
-  void SetFillGapsRadius(float Radius);
-  float GetFillGapsRadius();
-
-  /** Set/Get Angular Beam between two segments in the fill gaps filter. */
-  void SetFillGapsAngularBeam(float AngularBeam);
-  float GetFillGapsAngularBeam();
-
-  /** Set/Get the image input of this filter.  */
-  void SetInputImage(const InputImageType *image);
-  const InputImageType * GetInputImage();
-
-  /** Set/Get the image direction of this filter.  */
-  void SetInputImageDirection(const InputImageType *image);
-  const InputImageType * GetInputImageDirection();
-
-  /** Set/Get the value of the drawed line*/
-  itkGetMacro(LineValue, typename OutputImageType::PixelType);
-  itkSetMacro(LineValue, typename OutputImageType::PixelType);
-
-protected:
-  ExtractSegmentsImageFilter();
-  ~ExtractSegmentsImageFilter() override {}
-
-  typedef PixelSuppressionByDirectionImageFilter<InputImageType, PSOutputImageType> PixelSuppressionType;
-  typedef LocalHoughFilter<InputImageType>                                          LocalHoughType;
-  typedef FillGapsFilter                                                            FillGapsType;
-  typedef DrawLineSpatialObjectListFilter<InputImageType, OutputImageType>          DrawLineListType;
-  typedef  itk::RescaleIntensityImageFilter<TInputImage, TInputImage>               RescaleType;
-  void GenerateData() override;
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-  ExtractSegmentsImageFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-  typename OutputImageType::PixelType m_LineValue;
-
-  typename PixelSuppressionType::Pointer m_PixelSuppression;
-  typename LocalHoughType::Pointer m_LocalHough;
-  typename FillGapsType::Pointer m_FillGaps;
-  typename DrawLineListType::Pointer m_DrawLineList;
-  typename RescaleType::Pointer m_Rescaler;
-};
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbExtractSegmentsImageFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Feature/Edge/include/otbExtractSegmentsImageFilter.hxx b/Modules/Feature/Edge/include/otbExtractSegmentsImageFilter.hxx
deleted file mode 100644
index b9127118e129151b7235705be22d2b82801bfcee..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/include/otbExtractSegmentsImageFilter.hxx
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbExtractSegmentsImageFilter_hxx
-#define otbExtractSegmentsImageFilter_hxx
-
-#include "otbExtractSegmentsImageFilter.h"
-
-namespace otb
-{
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::ExtractSegmentsImageFilter()
-{
-  this->SetNumberOfRequiredInputs(2);
-  this->SetNumberOfRequiredOutputs(1);
-
-  m_PixelSuppression     = PixelSuppressionType::New();
-  m_LocalHough      = LocalHoughType::New();
-  m_FillGaps         = FillGapsType::New();
-  m_DrawLineList         = DrawLineListType::New();
-  m_Rescaler             = RescaleType::New();
-
-  m_LineValue = static_cast<typename OutputImageType::PixelType>(255.);
-}
-
-/**
- * Set/Get image input
- */
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetInputImage(const InputImageType *image)
-{
-  this->SetInput(0, image);
-}
-
-template <class TInputImage, class TOutputImage>
-const typename ExtractSegmentsImageFilter<TInputImage, TOutputImage>::InputImageType *
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetInputImage()
-{
-  return static_cast<const InputImageType *>
-           (this->GetInput(0));
-}
-
-/**
- * Set/Get image direction input
- */
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetInputImageDirection(const InputImageType *image)
-{
-  this->SetInput(1, image);
-}
-
-template <class TInputImage, class TOutputImage>
-const typename ExtractSegmentsImageFilter<TInputImage, TOutputImage>::InputImageType *
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetInputImageDirection()
-{
-  return static_cast<const InputImageType *>
-           (this->GetInput(1));
-}
-
-/**
- * Set/Get PixelSuppressionyDirectionImageFilter parameters
- */
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetPixelSuppressionRadius(SizeType Radius)
-{
-  m_PixelSuppression->SetRadius(Radius);
-}
-
-template <class TInputImage, class TOutputImage>
-const typename ExtractSegmentsImageFilter<TInputImage, TOutputImage>::SizeType
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetPixelSuppressionRadius()
-{
-  return (m_PixelSuppression->GetRadius());
-}
-
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetPixelSuppressionAngularBeam(float AngularBeam)
-{
-  m_PixelSuppression->SetAngularBeam(AngularBeam);
-}
-
-template <class TInputImage, class TOutputImage>
-float
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetPixelSuppressionAngularBeam()
-{
-  return (m_PixelSuppression->GetAngularBeam());
-}
-
-/**
- * Set/Get LocalHoughFilter parameters
- */
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetLocalHoughRadius(SizeType Radius)
-{
-  m_LocalHough->SetRadius(Radius);
-}
-
-template <class TInputImage, class TOutputImage>
-const typename ExtractSegmentsImageFilter<TInputImage, TOutputImage>::SizeType
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetLocalHoughRadius()
-{
-  return (m_LocalHough->GetRadius());
-}
-
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetLocalHoughNumberOfLines(unsigned int NumberOfLines)
-{
-  m_LocalHough->SetNumberOfLines(NumberOfLines);
-}
-
-template <class TInputImage, class TOutputImage>
-unsigned int
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetLocalHoughNumberOfLines()
-{
-  return (m_LocalHough->GetNumberOfLines());
-}
-
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetLocalHoughDiscRadius(float DiscRadius)
-{
-  m_LocalHough->SetDiscRadius(DiscRadius);
-}
-
-template <class TInputImage, class TOutputImage>
-float
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetLocalHoughDiscRadius()
-{
-  return (m_LocalHough->GetDiscRadius());
-}
-
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetLocalHoughVariance(float Variance)
-{
-  m_LocalHough->SetVariance(Variance);
-}
-
-template <class TInputImage, class TOutputImage>
-float
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetLocalHoughVariance()
-{
-  return (m_LocalHough->GetVariance());
-}
-
-/**
- * Set/Get FillGapsFilter parameters
- */
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetFillGapsRadius(float Radius)
-{
-  m_FillGaps->SetRadius(Radius);
-}
-
-template <class TInputImage, class TOutputImage>
-float
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetFillGapsRadius()
-{
-  return (m_FillGaps->GetRadius());
-}
-
-template <class TInputImage, class TOutputImage>
-void ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::SetFillGapsAngularBeam(float AngularBeam)
-{
-  m_FillGaps->SetAngularBeam(AngularBeam);
-}
-
-template <class TInputImage, class TOutputImage>
-float
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GetFillGapsAngularBeam()
-{
-  return (m_FillGaps->GetAngularBeam());
-}
-
-template <class TInputImage, class TOutputImage>
-void
-ExtractSegmentsImageFilter<TInputImage, TOutputImage>
-::GenerateData()
-{
-
-  m_PixelSuppression->SetInputImage(this->GetInputImage());
-  m_PixelSuppression->SetInputImageDirection(this->GetInputImageDirection());
-
-  m_Rescaler->SetInput(m_PixelSuppression->GetOutput());
-
-  m_LocalHough->SetInput(m_Rescaler->GetOutput());
-
-  m_FillGaps->SetInput (m_LocalHough->GetOutput());
-
-  m_DrawLineList->SetInput(this->GetInputImage());
-  m_DrawLineList->SetInputLineSpatialObjectList(m_FillGaps->GetOutput());
-  m_DrawLineList->SetValue(m_LineValue);
-
-  m_DrawLineList->GraftOutput(this->GetOutput());
-  m_DrawLineList->Update();
-  this->GraftOutput(m_DrawLineList->GetOutput());
-
-}
-
-/**
- * Standard "PrintSelf" method
- */
-template <class TInputImage, class TOutput>
-void
-ExtractSegmentsImageFilter<TInputImage, TOutput>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-  /*  os << indent << "Length: " << m_LengthLine << std::endl;
-    os << indent << "Width: " << m_WidthLine << std::endl; */
-
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Feature/Edge/include/otbFillGapsFilter.h b/Modules/Feature/Edge/include/otbFillGapsFilter.h
deleted file mode 100644
index f9af00605de1a9f09db1a2e20b1f3f2a5ca15ad1..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/include/otbFillGapsFilter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbFillGapsFilter_h
-#define otbFillGapsFilter_h
-
-
-#include "itkProcessObject.h"
-#include "otbLineSpatialObjectList.h"
-
-namespace otb
-{
-/** \class FillGapsFilter
- * \brief To be documented
- *
- * \ingroup OTBEdge
- */
-class ITK_EXPORT FillGapsFilter : public itk::ProcessObject
-{
-
-public:
-  /** Standard class typedefs. */
-  typedef FillGapsFilter                Self;
-  typedef itk::ProcessObject            Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(FillGapsFilter, itk::ProcessObject);
-
-  /** Some convenient typedefs. */
-  typedef LineSpatialObjectList                LineSpatialObjectListType;
-  typedef LineSpatialObjectListType::Pointer   LineSpatialObjectListPointer;
-  typedef LineSpatialObjectListType::LineType  LineSpatialObjectType;
-  typedef LineSpatialObjectType::PointListType PointListType;
-  typedef LineSpatialObjectType::LinePointType PointType;
-
-  typedef itk::ProcessObject ProcessObjectType;
-
-  using Superclass::SetInput;
-  void SetInput(const LineSpatialObjectListType * input);
-  const LineSpatialObjectListType * GetInput();
-
-  LineSpatialObjectListType * GetOutput();
-
-  itkSetMacro(AngularBeam, double);
-  itkGetConstReferenceMacro(AngularBeam, double);
-  itkSetMacro(Radius, double);
-  itkGetConstReferenceMacro(Radius, double);
-
-protected:
-  FillGapsFilter();
-
-  ~FillGapsFilter() override {}
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-  void GenerateData() override;
-
-private:
-  FillGapsFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-  double m_AngularBeam;
-  double m_Radius;
-
-};
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.h b/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.h
deleted file mode 100644
index 5f61fc4843c0f0dc6ae0ac9ca479876fcfe789d7..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbHoughTransform2DLinesImageFilter_h
-#define otbHoughTransform2DLinesImageFilter_h
-
-
-#include "itkImageToImageFilter.h"
-#include "otbImage.h"
-#include "itkLineSpatialObject.h"
-
-namespace otb
-{
-
-/**
- * \class HoughTransform2DLinesImageFilter
- * \brief Performs the Hough Transform to find 2D straight lines
- *        in a 2D image.
- *
- * This filter derives from ImageToImageFilter
- * The input is an image, and all pixels above some threshold are those
- * to be extracted. The output is the image of the accumulator.
- * GetLines() returns a list of LinesSpatialObjects
- *
- * Lines are parameterized in the form: R = x*std::cos(Teta)+y*std::sin(Teta)
- * where R is the perpendicular distance from the origin and Teta
- * the angle with the normal.
- *
- * The output is the accumulator array:
- *    -The first dimension (X) represents the distance R from the origin
- *     to the line. This is the distance axis. Its size depends on the size
- *     of the diagonal of the input image.
- *
- *    -The second dimension (Y) represents the angle between the X axis
- *     and the normal to the line. This is the angle axis. Its size depends
- *     on the AngleAxisSize parameter (500 by default) and its bounds can be
- *     set with the AngleAxisMinimum and AngleAxisMaximum parameters
- *     (-PI and +PI by default).
- *
- * \ingroup ImageFeatureExtraction
- * \sa LineSpatialObject
- *
- *
- * \ingroup OTBEdge
- * */
-
-template<typename TInputPixelType, typename TOutputPixelType>
-class ITK_EXPORT HoughTransform2DLinesImageFilter :
-  public itk::ImageToImageFilter< Image<TInputPixelType, 2>, Image<TOutputPixelType, 2> >
-{
-public:
-
-  /** Standard "Self" typedef. */
-  typedef HoughTransform2DLinesImageFilter Self;
-
-  /** Input Image typedef */
-  typedef otb::Image<TInputPixelType, 2>        InputImageType;
-  typedef typename InputImageType::Pointer      InputImagePointer;
-  typedef typename InputImageType::ConstPointer InputImageConstPointer;
-
-  /** Output Image typedef */
-  typedef otb::Image<TOutputPixelType, 2>   OutputImageType;
-  typedef typename OutputImageType::Pointer OutputImagePointer;
-
-  /** Smart pointer typedef support. */
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Line typedef */
-  typedef itk::LineSpatialObject<2>  LineType;
-  typedef typename LineType::Pointer LinePointer;
-  typedef std::list<LinePointer>     LinesListType;
-  typedef LineType::LinePointType    LinePointType;
-
-  /** Standard "Superclass" typedef. */
-  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
-
-  /** Image index typedef */
-  typedef typename InputImageType::IndexType IndexType;
-
-  /** Image pixel value typedef */
-  typedef typename InputImageType::PixelType PixelType;
-
-  /** Typedef to describe the output image region type. */
-  typedef typename InputImageType::RegionType OutputImageRegionType;
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(HoughTransform2DLinesImageFilter, ImageToImageFilter);
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Method for evaluating the implicit function over the image. */
-  void GenerateData() override;
-
-  /** Accessors for the threshold above which the filter should consider
-      the point as a valid point */
-  itkSetMacro(Threshold, float);
-  itkGetMacro(Threshold, float);
-
-  /** Accessors for the parameters of the angle axis.
-      The Hough space describes (in the angle direction)
-      [AngleAxisMinimum, AngleAxisMaximum[ with AngleAxisSize values */
-  /** Accessors for the size of the angle axis */
-  itkSetMacro(AngleAxisSize, unsigned int);
-  itkGetMacro(AngleAxisSize, unsigned int);
-
-  /** Accessors for the minimum of the angle axis */
-  itkSetMacro(AngleAxisMinimum, double);
-  itkGetMacro(AngleAxisMinimum, double);
-
-  /** Accessors for the maximum of the angle axis */
-  itkSetMacro(AngleAxisMaximum, double);
-  itkGetMacro(AngleAxisMaximum, double);
-
-  /** Accessors for the parameters of the distance axis.
-      The Hough space describes (in the distance direction)
-      [DistanceAxisMinimum, DistanceAxisMaximum[ with DistanceAxisSize values */
-  /** Accessors for the actual size of the Distance axis */
-  itkSetMacro(DistanceAxisSize, unsigned int);
-  itkGetMacro(DistanceAxisSize, unsigned int);
-
-  /** Accessors for the maximum size of the Distance axis */
-  itkGetMacro(DistanceAxisMaximumSize, unsigned int);
-
-  /** Accessors for the minimum of the Distance axis */
-  itkSetMacro(DistanceAxisMinimum, double);
-  itkGetMacro(DistanceAxisMinimum, double);
-
-  /** Accessors for the maximum of the Distance axis */
-  itkSetMacro(DistanceAxisMaximum, double);
-  itkGetMacro(DistanceAxisMaximum, double);
-
-  /** Set/Get the number of lines to extract */
-  itkSetMacro(NumberOfLines, unsigned int);
-  itkGetMacro(NumberOfLines, unsigned int);
-
-  /** Set/Get the radius of the disc to remove from the accumulator
-   *  for each line found */
-  itkSetMacro(DiscRadius, float);
-  itkGetMacro(DiscRadius, float);
-
-  /** Set/Get the variance of the gaussian bluring for the accumulator */
-  itkSetMacro(Variance, float);
-  itkGetMacro(Variance, float);
-
-  /** Simplify the accumulator */
-  void Simplify(void);
-
-  /** Get the Simplified accumulator */
-  itkGetObjectMacro(SimplifyAccumulator, OutputImageType);
-
-  /** Get the list of lines. This recomputes the lines */
-  LinesListType& GetLines(unsigned int n = 0);
-
-#ifdef ITK_USE_CONCEPT_CHECKING
-  /** Begin concept checking */
-  itkConceptMacro(IntConvertibleToOutputCheck,
-                  (itk::Concept::Convertible<int, TOutputPixelType>));
-  itkConceptMacro(InputGreaterThanFloatCheck,
-                  (itk::Concept::GreaterThanComparable<PixelType, float>));
-  itkConceptMacro(OutputPlusIntCheck,
-                  (itk::Concept::AdditiveOperators<TOutputPixelType, int>));
-  /** End concept checking */
-#endif
-
-protected:
-
-  HoughTransform2DLinesImageFilter();
-  ~HoughTransform2DLinesImageFilter() override {}
-
-  HoughTransform2DLinesImageFilter(const Self &) {}
-  void operator =(const Self&) {}
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-  /** HoughTransform2DLinesImageFilter needs the entire input. Therefore
-   * it must provide an implementation GenerateInputRequestedRegion().
-   * \sa ProcessObject::GenerateInputRequestedRegion(). */
-  void GenerateInputRequestedRegion() override;
-
-  /** HoughTransform2DLinesImageFilter's output is the accumulator
-   * array.  The size of the output is a function of the size of the
-   * input and of the angle and distance axis sizes. Since this output
-   * has a different size than the input, it must provide an implementation
-   * of GenerateOutputInformation.
-   * \sa ProcessObject::GenerateOutputRequestedRegion() */
-  void GenerateOutputInformation() override;
-
-  /** HoughTransform2DLinesImageFilter must produce the entire output */
-  void EnlargeOutputRequestedRegion(itk::DataObject *output) override;
-
-  int GetAngleIndex(double);
-
-  double GetAngleValue(int);
-
-  int GetDistanceIndex(double);
-
-  double GetDistanceValue(int);
-
-private:
-
-  unsigned int       m_AngleAxisSize;
-  double             m_AngleAxisMinimum;
-  double             m_AngleAxisMaximum;
-  double             m_AngleAxisIncrement;
-  unsigned int       m_DistanceAxisSize;
-  unsigned int       m_DistanceAxisMaximumSize;
-  double             m_DistanceAxisMinimum;
-  double             m_DistanceAxisMaximum;
-  double             m_DistanceAxisIncrement;
-  float              m_Threshold;
-  OutputImagePointer m_SimplifyAccumulator;
-  LinesListType      m_LinesList;
-  unsigned int       m_NumberOfLines;
-  float              m_DiscRadius;
-  float              m_Variance;
-  unsigned long      m_OldModifiedTime;
-  unsigned long      m_OldNumberOfLines;
-};
-
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbHoughTransform2DLinesImageFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.hxx b/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.hxx
deleted file mode 100644
index 0f7af0bfc1dcf815b90f79af2a91257ed259fc65..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.hxx
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbHoughTransform2DLinesImageFilter_hxx
-#define otbHoughTransform2DLinesImageFilter_hxx
-
-#include "otbHoughTransform2DLinesImageFilter.h"
-#include "itkUnaryFunctorImageFilter.h"
-#include "itkImageRegionIteratorWithIndex.h"
-#include "itkDiscreteGaussianImageFilter.h"
-#include "itkMinimumMaximumImageCalculator.h"
-#include "itkCastImageFilter.h"
-
-namespace otb
-{
-
-/** Constructor */
-template<typename TInputPixelType, typename TOutputPixelType>
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::HoughTransform2DLinesImageFilter()
-{
-  const double nPI = 4.0 * std::atan(1.0);
-
-  m_Threshold = 0; // by default
-
-  m_AngleAxisSize = 500;
-  m_AngleAxisMinimum = -nPI;
-  m_AngleAxisMaximum = nPI;
-
-  m_DistanceAxisSize = -1;
-  m_DistanceAxisMinimum = -100;
-  m_DistanceAxisMaximum = 100;
-
-  m_NumberOfLines = 1;
-  m_DiscRadius = 10;
-  m_Variance = 5;
-  m_OldModifiedTime = 0;
-  m_OldNumberOfLines = 0;
-  m_SimplifyAccumulator = nullptr;
-}
-
-template<typename TInputPixelType, typename TOutputPixelType>
-void
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::EnlargeOutputRequestedRegion(itk::DataObject *output)
-{
-  // call the superclass' implementation of this method
-  Superclass::EnlargeOutputRequestedRegion(output);
-
-  output->SetRequestedRegionToLargestPossibleRegion();
-}
-
-template<typename TInputPixelType, typename TOutputPixelType>
-void
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GenerateOutputInformation()
-{
-  // call the superclass' implementation of this method
-  Superclass::GenerateOutputInformation();
-
-  // get pointers to the input and output
-  InputImageConstPointer input  = this->GetInput();
-  OutputImagePointer     output = this->GetOutput();
-
-  if (!input || !output)
-    {
-    return;
-    }
-
-  // Compute the size of the output image
-  if (m_DistanceAxisSize + 1 == 0)
-    {
-    double inputSize0 = input->GetLargestPossibleRegion().GetSize()[0];
-    double inputSize1 = input->GetLargestPossibleRegion().GetSize()[1];
-    double inputDiagonalSize = sqrt(inputSize0 * inputSize0 + inputSize1 * inputSize1);
-    m_DistanceAxisSize = (long unsigned int) inputDiagonalSize;
-    }
-
-  itk::Size<2> size;
-  size[0] = (long unsigned int) m_DistanceAxisSize;
-  size[1] = (long unsigned int) m_AngleAxisSize;
-
-  typename InputImageType::RegionType region;
-  region.SetSize(size);
-  region.SetIndex(input->GetLargestPossibleRegion().GetIndex());
-
-  output->SetLargestPossibleRegion(region);
-}
-
-template<typename TInputPixelType, typename TOutputPixelType>
-void
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GenerateInputRequestedRegion()
-{
-  Superclass::GenerateInputRequestedRegion();
-  if (this->GetInput())
-    {
-    InputImagePointer image = const_cast<InputImageType *>(this->GetInput());
-    image->SetRequestedRegionToLargestPossibleRegion();
-    }
-}
-
-/** Generate the accumulator image */
-template<typename TInputPixelType, typename TOutputPixelType>
-void
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GenerateData()
-{
-  itkDebugMacro(<< "HoughTransform2DLinesImageFilter called");
-
-  m_AngleAxisIncrement = (m_AngleAxisMaximum - m_AngleAxisMinimum) / m_AngleAxisSize;
-  m_DistanceAxisIncrement = (m_DistanceAxisMaximum - m_DistanceAxisMinimum) / m_DistanceAxisSize;
-
-  // Get the input and output pointers
-  InputImageConstPointer inputImage  = this->GetInput(0);
-  OutputImagePointer     outputImage = this->GetOutput(0);
-
-  // Allocate the output
-  this->AllocateOutputs();
-  outputImage->FillBuffer(0);
-
-  itk::ImageRegionConstIteratorWithIndex<InputImageType>  image_it(inputImage,  inputImage->GetRequestedRegion());
-  image_it.GoToBegin();
-
-  itk::Index<2> index;
-
-// Pre-computation of trigonometric lines
-  unsigned int nbAngles = static_cast<unsigned long int>(m_AngleAxisSize);
-  std::vector<double> cosAngle(nbAngles, 0.);
-  std::vector<double> sinAngle(nbAngles, 0.);
-
-  //const double nPI = 4.0 * std::atan( 1.0 ); Unused in this method
-  for (unsigned int indexAngle = 0; indexAngle < nbAngles; indexAngle++)
-    {
-    double angle = this->GetAngleValue(indexAngle);
-    cosAngle[indexAngle] = std::cos(angle);
-    sinAngle[indexAngle] = std::sin(angle);
-    }
-
-  while (!image_it.IsAtEnd())
-    {
-    if (image_it.Get() > m_Threshold)
-      {
-      for (unsigned int indexAngle = 0; indexAngle < nbAngles; indexAngle++)
-        {
-        double       r = image_it.GetIndex()[0] * cosAngle[indexAngle] + image_it.GetIndex()[1] * sinAngle[indexAngle];
-        unsigned int indexR = this->GetDistanceIndex(r);
-        index[0] = indexR; // m_R
-        index[1] = indexAngle; // m_Theta
-        if (outputImage->GetBufferedRegion().IsInside(index))
-          {
-          outputImage->SetPixel(index, outputImage->GetPixel(index) + image_it.Get());
-          }
-        }
-      }
-    ++image_it;
-    }
-}
-
-/** Simplify the accumulator
- * Do the same iteration process as the Update() method but find the maximum
- * along the curve and then remove the curve */
-template<typename TInputPixelType, typename TOutputPixelType>
-void
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::Simplify(void)
-{
-  // Get the input and output pointers
-  InputImageConstPointer inputImage = this->GetInput(0);
-  OutputImagePointer     outputImage = this->GetOutput(0);
-
-  if (!inputImage || !outputImage)
-    {
-    itkExceptionMacro("Update() must be called before Simplify().");
-    }
-
-  /** Allocate the simplify accumulator */
-  m_SimplifyAccumulator = OutputImageType::New();
-  m_SimplifyAccumulator->SetRegions(outputImage->GetLargestPossibleRegion());
-  m_SimplifyAccumulator->SetOrigin(inputImage->GetOrigin());
-  m_SimplifyAccumulator->SetSignedSpacing(inputImage->GetSignedSpacing());
-  m_SimplifyAccumulator->Allocate();
-  m_SimplifyAccumulator->FillBuffer(0);
-
-  itk::Index<2>                       index;
-  itk::Index<2>                       maxIndex;
-  typename OutputImageType::PixelType value;
-  typename OutputImageType::PixelType valuemax;
-
-  itk::ImageRegionConstIteratorWithIndex<InputImageType>  image_it(inputImage,  inputImage->GetRequestedRegion());
-  image_it.GoToBegin();
-
-  while (!image_it.IsAtEnd())
-    {
-    if (image_it.Get() > m_Threshold)
-      {
-      // Look for maximum along the curve and remove the curve at the same time
-      valuemax = -1;
-      maxIndex[0] = 0;
-      maxIndex[1] = 0;
-      for (double angle = m_AngleAxisMinimum; angle < m_AngleAxisMaximum; angle += m_AngleAxisIncrement)
-        {
-        index[0] = (long int) (image_it.GetIndex()[0] * std::cos(angle) + image_it.GetIndex()[1] * std::sin(angle)); // m_R
-        index[1] = (long int) (this->GetAngleIndex(angle)); // m_Theta
-
-        if (outputImage->GetBufferedRegion().IsInside(index))
-          {
-          value = outputImage->GetPixel(index);
-          if (value > valuemax)
-            {
-            valuemax = value;
-            maxIndex = index;
-            }
-          }
-        }
-      m_SimplifyAccumulator->SetPixel(maxIndex, m_SimplifyAccumulator->GetPixel(maxIndex) + 1);
-      }
-    ++image_it;
-    }
-
-  itk::ImageRegionConstIteratorWithIndex<OutputImageType>  accusimple_it(m_SimplifyAccumulator,
-                                                                         m_SimplifyAccumulator->GetRequestedRegion());
-  itk::ImageRegionIteratorWithIndex<OutputImageType>       accu_it(outputImage,  outputImage->GetRequestedRegion());
-
-  accusimple_it.GoToBegin();
-  accu_it.GoToBegin();
-
-  while (!accusimple_it.IsAtEnd())
-    {
-    accu_it.Set(accusimple_it.Get());
-    ++accu_it;
-    ++accusimple_it;
-    }
-
-}
-
-/** Get the list of lines. This recomputes the lines */
-template<typename TInputPixelType, typename TOutputPixelType>
-typename HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>::LinesListType&
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GetLines(unsigned int n)
-{
-  if ((this->GetMTime() == m_OldModifiedTime) && (n == m_OldNumberOfLines)) // if the filter has not been updated
-    {
-    return m_LinesList;
-    }
-
-  m_LinesList.clear();
-
-  /** Blur the accumulator in order to find the maximum */
-  typedef float                                 InternalImagePixelType;
-  typedef itk::Image<InternalImagePixelType, 2> InternalImageType;
-
-  OutputImagePointer outputImage = this->GetOutput(0);
-
-  if (!outputImage)
-    {
-    itkExceptionMacro("Update() must be called before GetLines().");
-    }
-
-  /** Convert the accumulator output image type to internal image type*/
-  typedef itk::CastImageFilter<OutputImageType, InternalImageType> CastImageFilterType;
-
-  typename CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New();
-  castImageFilter->SetInput(outputImage);
-
-  typedef itk::DiscreteGaussianImageFilter<InternalImageType, InternalImageType> GaussianFilterType;
-  typename GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
-
-  gaussianFilter->SetInput(castImageFilter->GetOutput()); // the output is the accumulator image
-  double variance[2];
-  variance[0] = m_Variance;
-  variance[1] = m_Variance;
-  gaussianFilter->SetVariance(variance);
-  gaussianFilter->Update();
-  InternalImageType::Pointer postProcessImage = gaussianFilter->GetOutput();
-
-  typedef itk::MinimumMaximumImageCalculator<InternalImageType> MinMaxCalculatorType;
-  typename MinMaxCalculatorType::Pointer minMaxCalculator = MinMaxCalculatorType::New();
-  itk::ImageRegionIterator<InternalImageType>
-  it_input(postProcessImage, postProcessImage->GetLargestPossibleRegion());
-
-  const double nPI = 4.0 * std::atan(1.0);
-
-  itk::Index<2> index;
-
-  unsigned int lines = 0;
-  bool         found;
-
-  // Find maxima
-  do
-    {
-    minMaxCalculator->SetImage(postProcessImage);
-    minMaxCalculator->ComputeMaximum();
-    InternalImageType::PixelType max = minMaxCalculator->GetMaximum();
-
-    found = false;
-    for (it_input.GoToBegin(); !it_input.IsAtEnd(); ++it_input)
-      {
-      if (it_input.Get() == max)
-        {
-        // Create the line
-        LineType::PointListType list; // insert two points per line
-
-        double radius = this->GetDistanceValue(it_input.GetIndex()[0]);
-        double teta   = this->GetAngleValue(it_input.GetIndex()[1]);
-        double Vx = radius * std::cos(teta);
-        double Vy = radius * std::sin(teta);
-        double norm = std::sqrt(Vx * Vx + Vy * Vy);
-        double VxNorm = Vx / norm;
-        double VyNorm = Vy / norm;
-
-        if ((teta <= 0) || (teta >= nPI / 2))
-          {
-          if (teta >= nPI / 2)
-            {
-            VyNorm = -VyNorm;
-            VxNorm = -VxNorm;
-            }
-
-          LinePointType p;
-          p.SetPosition(Vx, Vy);
-          list.push_back(p);
-          p.SetPosition(Vx - VyNorm * 5, Vy + VxNorm * 5);
-          list.push_back(p);
-          }
-        else // if teta>0
-          {
-          LinePointType p;
-          p.SetPosition(Vx, Vy);
-          list.push_back(p);
-          p.SetPosition(Vx - VyNorm * 5, Vy + VxNorm * 5);
-          list.push_back(p);
-          } // end if(teta>0)
-
-        // Create a Line Spatial Object
-        LinePointer Line = LineType::New();
-        Line->SetId(lines);
-        Line->SetPoints(list);
-        Line->ComputeBoundingBox();
-
-        m_LinesList.push_back(Line);
-
-        // Remove a black disc from the hough space domain
-        for (double angle = m_AngleAxisMinimum; angle <= m_AngleAxisMaximum; angle += m_AngleAxisIncrement)
-          {
-          for (double length = 0; length < m_DiscRadius; length += 1)
-            {
-            index[0] = (long int) (it_input.GetIndex()[0] + length * std::cos(angle));
-            index[1] = (long int) (it_input.GetIndex()[1] + length * std::sin(angle));
-            if (postProcessImage->GetBufferedRegion().IsInside(index))
-              {
-              postProcessImage->SetPixel(index, 0);
-              }
-            }
-          }
-        minMaxCalculator->SetImage(postProcessImage);
-        minMaxCalculator->ComputeMaximum();
-        max = minMaxCalculator->GetMaximum();
-
-        ++lines;
-        found = true;
-        if (lines == m_NumberOfLines) break;
-        }
-      }
-    }
-  while ((lines < m_NumberOfLines) && (found));
-
-  m_OldModifiedTime = this->GetMTime();
-  m_OldNumberOfLines = m_LinesList.size();
-  return m_LinesList;
-}
-
-/** Print Self information */
-template<typename TInputPixelType, typename TOutputPixelType>
-void
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-
-  os << "Threshold: " << m_Threshold << std::endl;
-  os << "Angle axis size: " << m_AngleAxisSize << std::endl;
-  os << "Angle axis minimum: " << m_AngleAxisMinimum << std::endl;
-  os << "Angle axis maximum: " << m_AngleAxisMaximum << std::endl;
-  os << "Number Of Lines: " << m_NumberOfLines << std::endl;
-  os << "Disc Radius: " << m_DiscRadius << std::endl;
-  os << "Accumulator blur variance: " << m_Variance << std::endl;
-  os << "Simplify Accumulator" << m_SimplifyAccumulator << std::endl;
-}
-
-/** Computes angle index from angle value */
-template<typename TInputPixelType, typename TOutputPixelType>
-int
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GetAngleIndex(double angle)
-{
-  int indexAngle = static_cast<int>((angle - m_AngleAxisMinimum) / m_AngleAxisIncrement);
-  return indexAngle;
-}
-
-/** Computes angle value from angle index */
-template<typename TInputPixelType, typename TOutputPixelType>
-double
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GetAngleValue(int indexAngle)
-{
-  double angle = m_AngleAxisMinimum + indexAngle * m_AngleAxisIncrement;
-  return angle;
-}
-
-/** Computes distance index from distance value */
-template<typename TInputPixelType, typename TOutputPixelType>
-int
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GetDistanceIndex(double distance)
-{
-  int indexDistance = static_cast<int>((distance - m_DistanceAxisMinimum) / m_DistanceAxisIncrement);
-  return indexDistance;
-}
-
-/** Computes distance value from distance index */
-template<typename TInputPixelType, typename TOutputPixelType>
-double
-HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
-::GetDistanceValue(int indexDistance)
-{
-  double distance = m_DistanceAxisMinimum + indexDistance * m_DistanceAxisIncrement;
-  return distance;
-}
-
-} // end namespace
-
-#endif
diff --git a/Modules/Feature/Edge/include/otbLocalHoughFilter.h b/Modules/Feature/Edge/include/otbLocalHoughFilter.h
deleted file mode 100644
index 42a2327ad75de8d1191970f7de146c883847390f..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/include/otbLocalHoughFilter.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLocalHoughFilter_h
-#define otbLocalHoughFilter_h
-
-#include "itkUnaryFunctorImageFilter.h"
-#include "itkHoughTransform2DLinesImageFilter.h"
-
-#include "otbImageToLineSpatialObjectListFilter.h"
-#include "otbExtractROI.h"
-
-namespace otb
-{
-/** \class LocalHoughFilter
- * \brief Application of Hough filter on a nxm pixel tiling of the image.
- *
- * This class implements a filter that applies the hough transform on nxm
- * pixel tiling of the image. The Hough filter is used to find straight
- * lines in a 2-dimensional image. It detects the best line in each tile
- * and suppresses dubious line detection due to small local structures.
- *
- * Input parameters are : the tile radius, the number of lines we are
- * looking for, the variance of the accumulator blurring (default = 5) and
- * the radius of the disc to remove from the accumulator (default = 10).
- *
- *
- * \ingroup OTBEdge
- */
-
-template <class TInputImage>
-class ITK_EXPORT LocalHoughFilter : public ImageToLineSpatialObjectListFilter<TInputImage>
-{
-public:
-
-  /** Standard class typedefs. */
-  typedef LocalHoughFilter                                Self;
-  typedef ImageToLineSpatialObjectListFilter<TInputImage> Superclass;
-  typedef itk::SmartPointer<Self>                         Pointer;
-  typedef itk::SmartPointer<const Self>                   ConstPointer;
-
-  /** Method for management of the "object factory". */
-  itkNewMacro(Self);
-
-  /** Return the name of the class. */
-  itkTypeMacro(LocalHoughFilter, ImageToLineSpatialObjectListFilter);
-
-  /** Definition of the list of lines. */
-  typedef typename Superclass::LinesListType     LinesListType;
-  typedef typename LinesListType::const_iterator LineIterator;
-
-  typedef typename LinesListType::LineType LineType;
-  typedef typename LineType::Pointer       LinePointer;
-
-  typedef typename LineType::PointListType PointListType;
-  typedef typename LineType::LinePointType LinePointType;
-
-  /**   Extract dimensions as well of the images of entry of exit. */
-  itkStaticConstMacro(InputImageDimension,
-                      unsigned int,
-                      TInputImage::ImageDimension);
-
-  typedef TInputImage InputImageType;
-
-  //------------------------------------------------------------
-  typedef  unsigned char                  OutputPixelType;
-  typedef  otb::Image<OutputPixelType, 2> OutputImageType;
-  //-----------------------------------------------
-
-  /** Definition of the pixel type of the input and output images */
-  typedef typename InputImageType::PixelType InputPixelType;
-  typedef   float                            AccumulatorPixelType;
-
-  typedef typename InputImageType::RegionType InputImageRegionType;
-
-  /** Definition of the size of the images. */
-  typedef typename InputImageType::SizeType SizeType;
-
-  typedef typename InputImageType::RegionType::IndexType IndexType;
-
-  /** Typedefs to define the extract ROI filter. */
-  typedef ExtractROI<InputPixelType, InputPixelType> ROIFilterType;
-
-  /** Set the radius of the local region where to apply the Hough filter. */
-  itkSetMacro(Radius, SizeType);
-
-  /** Get the radius of the local region. */
-  itkGetConstReferenceMacro(Radius, SizeType);
-
-  /** Set the radius of the overlap of the local region where to apply the Hough filter. */
-  itkSetMacro(Overlap, SizeType);
-
-  /** Get the radius of the overlap. */
-  itkGetConstReferenceMacro(Overlap, SizeType);
-
-  /** Set the number of lines we are looking for. */
-  itkSetMacro(NumberOfLines, unsigned int);
-
-  /** Get the number of lines we are looking for. */
-  itkGetConstReferenceMacro(NumberOfLines, unsigned int);
-
-  /** Set/Get the radius of the disc to remove from the accumulator
-   *  for each line found */
-  itkSetMacro(DiscRadius, float);
-  itkGetMacro(DiscRadius, float);
-
-  /** Set/Get the variance of the gaussian bluring for the accumulator */
-  itkSetMacro(Variance, float);
-  itkGetMacro(Variance, float);
-
-  itkSetMacro(Threshold, float);
-  itkGetMacro(Threshold, float);
-
-protected:
-  LocalHoughFilter();
-  ~LocalHoughFilter() override {}
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-  /** Definition of the Hough Filter. */
-  typedef itk::HoughTransform2DLinesImageFilter<InputPixelType, AccumulatorPixelType> HoughFilterType;
-
-  void GenerateData() override;
-
-private:
-  LocalHoughFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-  /** Radius used to define the local region. */
-  SizeType m_Radius;
-
-  /** Radius used to define the overlap of local regions. */
-  SizeType m_Overlap;
-
-  /** Parameter of the Hough filter : number of lines we are looking for. */
-  unsigned int m_NumberOfLines;
-
-  /** Variance of the accumulator blurring (default = 5). */
-  float m_Variance;
-
-  /** Radius of the disc to remove from the accumulator (default = 10). */
-  float m_DiscRadius;
-
-  /** Threshold abouve which a pixel is consedered as valid */
-  float m_Threshold;
-
-  LinePointer LinePointResearch(LineIterator itLines, InputImageType *localImage, IndexType origin);
-
-};
-
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbLocalHoughFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Feature/Edge/include/otbLocalHoughFilter.hxx b/Modules/Feature/Edge/include/otbLocalHoughFilter.hxx
deleted file mode 100644
index c3813ae207b487b79de1c09a9d81602d302d42ea..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/include/otbLocalHoughFilter.hxx
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef otbLocalHoughFilter_hxx
-#define otbLocalHoughFilter_hxx
-
-#include "otbLocalHoughFilter.h"
-#include "otbImage.h"
-
-namespace otb
-{
-
-/**
- *
- */
-template <class TInputImage>
-LocalHoughFilter<TInputImage>::LocalHoughFilter() : ImageToLineSpatialObjectListFilter<TInputImage>(),
-  m_NumberOfLines(1),
-  m_Variance(5),
-  m_DiscRadius(10),
-  m_Threshold(0)
-{
-  m_Radius.Fill(20);
-  m_Overlap.Fill(0);
-}
-
-template <class TInputImage>
-typename LocalHoughFilter<TInputImage>::LinePointer
-LocalHoughFilter<TInputImage>::
-LinePointResearch(LineIterator itLines, InputImageType *image, IndexType origin)
-{
-
-  // Get the list of points which consists of two points to represent a
-  // straight line
-  PointListType&                         pointsList = (*itLines)->GetPoints();
-  typename PointListType::const_iterator itPoints = pointsList.begin();
-
-  double u[2];
-  u[0] = (*itPoints).GetPosition()[0];
-  u[1] = (*itPoints).GetPosition()[1];
-  ++itPoints;
-  double v[2];
-  v[0] = u[0] - (*itPoints).GetPosition()[0];
-  v[1] = u[1] - (*itPoints).GetPosition()[1];
-
-  double norm = std::sqrt(v[0] * v[0] + v[1] * v[1]);
-  v[0] /= norm;
-  v[1] /= norm;
-
-  typename InputImageType::RegionType region = image->GetLargestPossibleRegion();
-
-  PointListType ptList;
-  LinePointType point;
-
-  typename InputImageType::IndexType localIndex;
-  typename InputImageType::IndexType previousIndex;
-  typename InputImageType::IndexType nextIndex;
-
-  // The diagonal is the largest distance between two edges of image
-  itk::Size<2> size = region.GetSize();
-  float        diag = std::sqrt((float) (size[0] * size[0] + size[1] * size[1]));
-
-  // Loop on the largest distance to be sure to cover all the image
-  // whatever the position of the origin u
-  for (int i = static_cast<int>(-diag); i < static_cast<int>(diag); ++i)
-    {
-
-    previousIndex[0] = static_cast<long>(u[0] + (i - 1) * v[0]);
-    previousIndex[1] = static_cast<long>(u[1] + (i - 1) * v[1]);
-
-    localIndex[0] = static_cast<long>(u[0] + i * v[0]);
-    localIndex[1] = static_cast<long>(u[1] + i * v[1]);
-
-    nextIndex[0] = static_cast<long>(u[0] + (i + 1) * v[0]);
-    nextIndex[1] = static_cast<long>(u[1] + (i + 1) * v[1]);
-
-    // Check if the local index is inside the image and the previous
-    // index is outside or if the local index is inside the image and
-    // the next index is outside
-
-    if (((region.IsInside(localIndex)) && (!region.IsInside(previousIndex))) ||
-        ((region.IsInside(localIndex)) && (!region.IsInside(nextIndex))))
-      {
-
-      point.SetPosition(localIndex[0] + origin[0], localIndex[1] + origin[1]);
-      ptList.push_back(point);
-
-      }
-
-    }
-
-  // Check if the line is well defined by two points
-  LinePointer line = LineType::New();
-
-  if (ptList.size() == 2)
-    {
-    line->SetId(0);
-    line->SetPoints(ptList);
-    line->ComputeBoundingBox();
-    }
-
-  ptList.clear();
-
-  return (line);
-
-}
-
-template <class TInputImage>
-void
-LocalHoughFilter<TInputImage>
-::GenerateData()
-{
-
-  typename InputImageType::ConstPointer input  = this->GetInput();
-
-  typename LinesListType::Pointer list;
-  list = this->GetOutput();
-
-  typename ROIFilterType::Pointer ROIfilter = ROIFilterType::New();
-
-  typename HoughFilterType::LinesListType lines;
-
-  typename HoughFilterType::Pointer houghFilter = HoughFilterType::New();
-
-  // Get image size
-  itk::Size<2> size = input->GetLargestPossibleRegion().GetSize();
-
-  // Loop on the input image
-
-  // Direction X
-  // x and y must be < size in order to avoid 0-sized regions
-  for (unsigned long x = 0; x < size[0] - 1; x += (m_Radius[0] - m_Overlap[0]))
-    {
-
-    // Initialize the extract ROI filter in the direction X
-    ROIfilter->SetStartX(x);
-
-    // Number of pixels of the local region
-    if ((x + m_Radius[0]) < size[0]) ROIfilter->SetSizeX(m_Radius[0]);
-    else ROIfilter->SetSizeX(size[0] - x - 1);
-
-    // Direction Y
-    for (unsigned long y = 0; y < size[1] - 1; y += (m_Radius[1] - m_Overlap[1]))
-      {
-
-      // Initialize the extract ROI filter in the direction Y
-      ROIfilter->SetStartY(y);
-
-      if ((y + m_Radius[1]) < size[1]) ROIfilter->SetSizeY(m_Radius[1]);
-      else ROIfilter->SetSizeY(size[1] - y - 1);
-
-      // Extract the local region of the input image
-      ROIfilter->SetInput(this->GetInput());
-
-      // ----------------------------------------------------
-      // Create a copy of the extract ROI filter output image
-      // ----------------------------------------------------
-
-      typename InputImageType::Pointer localImage = InputImageType::New();
-      typename InputImageType::Pointer filterImage = InputImageType::New();
-
-      ROIfilter->UpdateLargestPossibleRegion();
-      ROIfilter->Update();
-
-      filterImage = ROIfilter->GetOutput();
-
-      // Create a new image from the extracted region. The starting
-      // index is the corner of the newly generated image (0, 0)
-
-      typename InputImageType::RegionType region;
-
-      IndexType index;
-
-      index[0] = 0;
-      index[1] = 0;
-
-      region.SetSize(filterImage->GetLargestPossibleRegion().GetSize());
-      region.SetIndex(index);
-      localImage->SetRegions(region);
-      localImage->SetOrigin(filterImage->GetOrigin());
-      localImage->SetSignedSpacing(filterImage->GetSignedSpacing());
-      localImage->Allocate();
-
-      typedef itk::ImageRegionIteratorWithIndex<InputImageType>      LocalIteratorType;
-      typedef itk::ImageRegionConstIteratorWithIndex<InputImageType> FilterIteratorType;
-
-      LocalIteratorType    localIt(localImage, localImage->GetRequestedRegion());
-      FilterIteratorType   filterIt(filterImage,  filterImage->GetRequestedRegion());
-
-      localIt.GoToBegin();
-      filterIt.GoToBegin();
-
-      // Copy the filter image in the new local image
-      for (localIt.GoToBegin(); !localIt.IsAtEnd(); ++localIt, ++filterIt)
-        localIt.Set(static_cast<InputPixelType>(filterIt.Get()));
-
-      // -------------------------------
-      // Application of Hough filter
-      // -------------------------------
-
-      houghFilter->SetInput(localImage);
-      houghFilter->SetNumberOfLines(m_NumberOfLines);
-      houghFilter->SetVariance(m_Variance);
-      houghFilter->SetDiscRadius(m_DiscRadius);
-      houghFilter->SetThreshold(m_Threshold);
-
-      houghFilter->Modified();
-
-      houghFilter->Update();
-
-      // ---------------------------------------
-      // Get the list of LineSpatialObject lines
-      // ---------------------------------------
-      #if ITK_VERSION_MAJOR < 4 || (ITK_VERSION_MAJOR == 4 && ITK_VERSION_MINOR <= 12)
-      lines = houghFilter->GetLines(m_NumberOfLines);
-      #else
-      lines = houghFilter->GetLines();
-      #endif
-
-      LineIterator itLines = lines.begin();
-
-      // Loop on the lines of hough filter list
-      while (itLines != lines.end())
-        {
-
-        LinePointer line = LineType::New();
-
-        IndexType origin;
-
-        origin[0] = x;
-        origin[1] = y;
-
-        // Call the private method that researchs the two points
-        // used to define a line
-        line = LinePointResearch(itLines, localImage, origin);
-
-        if (line->GetNumberOfPoints() != 0) list->push_back(line);
-
-        ++itLines;
-
-        }
-
-      lines.clear();
-
-      } // end of loop in y direction
-
-    } // end of loop in x direction
-
-}
-
-template <class TInputImage>
-void
-LocalHoughFilter<TInputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Feature/Edge/otb-module.cmake b/Modules/Feature/Edge/otb-module.cmake
index 3760ff5d237e3548ca74c8c6f4a4ab02c153fbcd..31ea006ba4da45b1090df9b78c79820b3cf6d2a4 100644
--- a/Modules/Feature/Edge/otb-module.cmake
+++ b/Modules/Feature/Edge/otb-module.cmake
@@ -32,7 +32,6 @@ otb_module(OTBEdge
     OTBObjectList
     OTBPath
     OTBProjection
-    OTBSpatialObjects
     OTBStreaming
     OTBVectorDataBase
 
diff --git a/Modules/Feature/Edge/src/otbFillGapsFilter.cxx b/Modules/Feature/Edge/src/otbFillGapsFilter.cxx
deleted file mode 100644
index 63bbb863b52a0cf252bc92e0322802d3abd07973..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/src/otbFillGapsFilter.cxx
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "otbFillGapsFilter.h"
-
-namespace otb
-{
-
-/**
- * Constructor
- */
-
-FillGapsFilter::FillGapsFilter()
-{
-  this->ProcessObjectType::SetNumberOfRequiredInputs(1);
-  this->ProcessObjectType::SetNumberOfRequiredOutputs(1);
-
-  LineSpatialObjectListPointer output = LineSpatialObjectListType::New();
-
-  this->ProcessObjectType::SetNthOutput(0, output);
-
-  m_Radius      =  4.0;
-  m_AngularBeam =  1.0;
-}
-
-void
-FillGapsFilter
-::SetInput(const LineSpatialObjectListType * input)
-{
-  this->ProcessObjectType::SetNthInput(0,
-                                       const_cast<LineSpatialObjectListType *>(input));
-}
-
-const FillGapsFilter::LineSpatialObjectListType *
-FillGapsFilter
-::GetInput(void)
-{
-  return static_cast<const LineSpatialObjectListType *>
-         (this->ProcessObjectType::GetInput(0));
-}
-
-FillGapsFilter::LineSpatialObjectListType *
-FillGapsFilter
-::GetOutput(void)
-{
-  return static_cast<LineSpatialObjectListType *>
-         (this->ProcessObjectType::GetOutput(0));
-}
-
-/**
- *
- */
-
-void
-FillGapsFilter
-::GenerateData()
-{
-  // Get the LineSpatialObject
-
-  const LineSpatialObjectList * inputLine = this->GetInput();
-  LineSpatialObjectList *       outputLine = this->GetOutput();
-
-  // Get the list of points which consists of two points to represent a
-  // straight line
-
-  LineSpatialObjectListType::const_iterator itLineListA    = inputLine->begin();
-  LineSpatialObjectListType::const_iterator itLineListAEnd  = inputLine->end();
-  LineSpatialObjectListType::const_iterator itLineListB;
-  LineSpatialObjectListType::const_iterator itLineListBEnd  = inputLine->end();
-
-  double x1(0.), y1(0.), x2(0.), y2(0.), x3(0.), y3(0.), x4(0.), y4(0.);
-  double xTemp(0.), yTemp(0.);
-  double R13(0.), R14(0.), R23(0.), R24(0.);
-  double CosTheta(0.);
-
-  PointListType::const_iterator itPoints;
-
-  CosTheta = std::cos(m_AngularBeam);
-  --itLineListAEnd;
-
-  while (itLineListA != itLineListAEnd)
-    {
-    itLineListB = itLineListA;
-    ++itLineListB;
-
-    PointListType& pointsList = (*itLineListA)->GetPoints();
-    itPoints = pointsList.begin();
-
-    x1 = (*itPoints).GetPosition()[0];
-    y1 = (*itPoints).GetPosition()[1];
-
-    ++itPoints;
-    x2 = (*itPoints).GetPosition()[0];
-    y2 = (*itPoints).GetPosition()[1];
-
-    PointType     point;
-    PointListType pointList;
-
-    point.SetPosition(x1, y1);
-    pointList.push_back(point);
-    point.SetPosition(x2, y2);
-    pointList.push_back(point);
-
-    LineSpatialObjectType::Pointer line = LineSpatialObjectType::New();
-    line->SetId(0);
-    line->SetPoints(pointList);
-    line->ComputeBoundingBox();
-    outputLine->push_back(line);
-
-    while (itLineListB != itLineListBEnd)
-      {
-
-      pointsList = (*itLineListB)->GetPoints();
-      itPoints = pointsList.begin();
-
-      x3 = (*itPoints).GetPosition()[0];
-      y3 = (*itPoints).GetPosition()[1];
-
-      ++itPoints;
-      x4 = (*itPoints).GetPosition()[0];
-      y4 = (*itPoints).GetPosition()[1];
-
-      // Calculate the radius for each point of each line
-
-      R13 = std::sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3));
-      R14 = std::sqrt((x1 - x4) * (x1 - x4) + (y1 - y4) * (y1 - y4));
-      R23 = std::sqrt((x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3));
-      R24 = std::sqrt((x2 - x4) * (x2 - x4) + (y2 - y4) * (y2 - y4));
-
-      double Rmin = m_Radius;
-
-      // Test the lower Radius
-      if (R13 < Rmin) Rmin = R13;
-      if (R14 < Rmin) Rmin = R14;
-      if (R23 < Rmin) Rmin = R23;
-      if (R24 < Rmin) Rmin = R24;
-
-      if (Rmin < m_Radius)
-        {
-        // Sort Points such as the radius of P2 and P3 is the smallest one.
-        if (Rmin == R24)
-          {
-          xTemp = x3;
-          yTemp = y3;
-          x3    = x4;
-          y3    = y4;
-          x4    = xTemp;
-          y4    = yTemp;
-          }
-        if (Rmin == R13)
-          {
-          xTemp = x1;
-          yTemp = y1;
-          x1    = x2;
-          y1    = y2;
-          x2    = xTemp;
-          y2    = yTemp;
-          }
-        if (Rmin == R14)
-          {
-          xTemp = x3;
-          yTemp = y3;
-          x3    = x4;
-          y3    = y4;
-          x4    = xTemp;
-          y4    = yTemp;
-          xTemp = x1;
-          yTemp = y1;
-          x1    = x2;
-          y1    = y2;
-          x2    = xTemp;
-          y2    = yTemp;
-          }
-
-        //Estimate the norm each line
-        /*  double Norm12, Norm23, Norm34;
-          Norm12 = std::sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
-          Norm23 = std::sqrt( (x2-x3)*(x2-x3) + (y2-y3)*(y2-y3) );
-          Norm34 = std::sqrt( (x3-x4)*(x3-x4) + (y3-y4)*(y3-y4) );
-          */
-        double Angle12_23, Angle12_34, Angle23_34;
-        //Estimate the angle between lines 12-23 and lines 12-34
-        /*Angle12_23 = (x2-x1)*(x3-x2) + (y2-y1)*(y3-y2);
-        Angle12_23 = Angle12_23 / Norm12 / Norm23;
-
-        Angle12_34 = (x2-x1)*(x4-x3) + (y2-y1)*(y4-y3);
-        Angle12_34 = Angle12_34 / Norm12 / Norm34; */
-
-        Angle12_23 = std::cos(std::atan2((y2 - y1), (x2 - x1)) - std::atan2((y3 - y2), (x3 - x2)));
-        Angle12_34 = std::cos(std::atan2((y2 - y1), (x2 - x1)) - std::atan2((y4 - y3), (x4 - x3)));
-        Angle23_34 = std::cos(std::atan2((y3 - y2), (x3 - x2)) - std::atan2((y4 - y3), (x4 - x3)));
-
-        if ((Angle12_23 > CosTheta) && (Angle12_34 > CosTheta) && (Angle23_34 > CosTheta))
-          {
-
-          // Store 23-segment
-          PointType     ppoint;
-          PointListType ppointList;
-
-          ppoint.SetPosition(x2, y2);
-          ppointList.push_back(ppoint);
-          ppoint.SetPosition(x3, y3);
-          ppointList.push_back(ppoint);
-
-          LineSpatialObjectType::Pointer lline = LineSpatialObjectType::New();
-          lline->SetId(0);
-          lline->SetPoints(ppointList);
-          lline->ComputeBoundingBox();
-          outputLine->push_back(lline);
-
-          ppointList.clear();
-
-          }
-        } // if(Rmin < m_Radius)
-
-      ++itLineListB;
-      } // while(itLineListB != itLineListBEnd)
-    ++itLineListA;
-    }
-
-  // Insert the last element
-
-  PointType     point;
-  PointListType pointList;
-
-  point.SetPosition(x3, y3);
-  pointList.push_back(point);
-  point.SetPosition(x4, y4);
-  pointList.push_back(point);
-
-  LineSpatialObjectType::Pointer line = LineSpatialObjectType::New();
-  line->SetId(0);
-  line->SetPoints(pointList);
-  line->ComputeBoundingBox();
-  outputLine->push_back(line);
-
-  pointList.clear();
-
-}
-
-/**
- *
- */
-
-void
-FillGapsFilter
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-} // end namespace otb
diff --git a/Modules/Feature/Edge/test/CMakeLists.txt b/Modules/Feature/Edge/test/CMakeLists.txt
index 171dbfe4c705dfb54e101cc0c9697fcad5cb3fd7..a3c10fe256025eb17f31fe680f2ddf020ac90e15 100644
--- a/Modules/Feature/Edge/test/CMakeLists.txt
+++ b/Modules/Feature/Edge/test/CMakeLists.txt
@@ -25,16 +25,12 @@ otbEdgeTestDriver.cxx
 otbEdgeDetectorImageFilter.cxx
 otbHorizontalSobelVectorImageFilter.cxx
 otbAsymmetricFusionOfLineDetector.cxx
-otbLocalHoughDraw.cxx
 otbAssociativeSymmetricalSum.cxx
 otbPersistentVectorizationFilter.cxx
 otbEdgeDensityImageFilter.cxx
 otbLineCorrelationDetector.cxx
 otbSobelVectorImageFilter.cxx
-otbHoughTransform2DLinesImageTest.cxx
 otbPixelSuppressionByDirection.cxx
-otbLocalHough.cxx
-otbExtractSegments.cxx
 otbLineRatioDetector.cxx
 otbTouziEdgeDetectorDirection.cxx
 otbVerticalSobelVectorImageFilter.cxx
@@ -43,7 +39,6 @@ otbTouziEdgeDetector.cxx
 otbLineRatioDetectorLinear.cxx
 otbLineSegmentDetector.cxx
 otbLineCorrelationDetectorLinear.cxx
-otbFillGapsFilter.cxx
 )
 
 add_executable(otbEdgeTestDriver ${OTBEdgeTests})
@@ -79,31 +74,6 @@ otb_add_test(NAME feTvAsymmetricFusionOfLineDetector COMMAND otbEdgeTestDriver
   ${TEMP}/feFiltreAsymmetricFusion_amst_2_3.tif
   2 3)
 
-
-otb_add_test(NAME feTvLocalHoughDrawBis COMMAND otbEdgeTestDriver
-  --compare-image ${EPSILON_8}  ${BASELINE}/feFiltreLocalHoughDraw_Line_20_10_2.png
-  ${TEMP}/feFiltreLocalHoughDraw_Line_20_10_2.png
-  otbLocalHoughDraw
-  ${INPUTDATA}/Line.png
-  ${TEMP}/feFiltreLocalHoughDraw_Line_20_10_2.png
-  20 10 2)
-
-otb_add_test(NAME feTvLocalHoughDraw2 COMMAND otbEdgeTestDriver
-  --compare-image ${EPSILON_8}  ${BASELINE}/feFilterLocalHoughDraw_amst_20_20_1.png
-  ${TEMP}/feFilterLocalHoughDraw_amst_20_20_1.png
-  otbLocalHoughDraw
-  ${INPUTDATA}/amst.png
-  ${TEMP}/feFilterLocalHoughDraw_amst_20_20_1.png
-  20 20 1)
-
-otb_add_test(NAME feTvLocalHoughDraw COMMAND otbEdgeTestDriver
-  --compare-image ${EPSILON_8}  ${BASELINE}/feFiltreLocalHoughDraw_ImageLine_20_20_2.tif
-  ${TEMP}/feFiltreLocalHoughDraw_ImageLine_20_20_2.tif
-  otbLocalHoughDraw
-  ${INPUTDATA}/ImageLine.bsq.hdr
-  ${TEMP}/feFiltreLocalHoughDraw_ImageLine_20_20_2.tif
-  20 20 1)
-
 otb_add_test(NAME feTvAssociativeSymmetricalSum COMMAND otbEdgeTestDriver
   --compare-image ${EPSILON_8}  ${BASELINE}/feFiltreASS_amst_2_3.tif
   ${TEMP}/feFiltreASS_amst_2_3.tif
@@ -112,9 +82,6 @@ otb_add_test(NAME feTvAssociativeSymmetricalSum COMMAND otbEdgeTestDriver
   ${BASELINE}/feFiltreLineCorrelationLinear_amst_2_3.tif
   ${TEMP}/feFiltreASS_amst_2_3.tif)
 
-
-
-
 otb_add_test(NAME bfTvPersistentVectorizationImageFilter COMMAND otbEdgeTestDriver
   --compare-ascii ${NOTOL}
   ${BASELINE_FILES}/bfTvPersistentVectorizationImageFilterOutput.txt
@@ -151,14 +118,6 @@ otb_add_test(NAME bfTvSobelVectorImageFilter COMMAND otbEdgeTestDriver
   ${INPUTDATA}/cupriteSubHsi.tif
   ${TEMP}/bfTvSobelVectorImageFilter.tif)
 
-otb_add_test(NAME feTvHoughTransform2DLinesImage COMMAND otbEdgeTestDriver
-  --compare-image ${EPSILON_8}
-  ${BASELINE}/feFilterHoughTransformDraw.tif
-  ${TEMP}/feFilterHoughTransformDraw.tif
-  otbHoughTransform2DLinesImageTest
-  ${TEMP}/feFilterHoughTransformDraw.tif
-  )
-
 otb_add_test(NAME feTvPixelSuppressionByDirection COMMAND otbEdgeTestDriver
   --compare-image ${NOTOL}  ${BASELINE}/feFiltrePixelSuppr_ImageLine_2_0_3.tif
   ${TEMP}/feFiltrePixelSuppr_ImageLine_2_0_3.tif
@@ -168,25 +127,6 @@ otb_add_test(NAME feTvPixelSuppressionByDirection COMMAND otbEdgeTestDriver
   ${TEMP}/feFiltrePixelSuppr_ImageLine_2_0_3.tif
   2 0.3)
 
-
-
-otb_add_test(NAME feTvLocalHough COMMAND otbEdgeTestDriver
-  --compare-ascii ${EPSILON_3}  ${BASELINE_FILES}/feTvLocaLHoughLinesDetected.txt
-  ${TEMP}/feTvLocaLHoughLinesDetected.txt
-  otbLocalHough
-  ${INPUTDATA}/ImageLine.bsq.hdr
-  ${TEMP}/feTvLocaLHoughLinesDetected.txt
-  20 20 1)
-
-otb_add_test(NAME feTvExtractSegments COMMAND otbEdgeTestDriver
-  --compare-image ${NOTOL}  ${BASELINE}/feFiltreExtractSegments_ImageLine.tif
-  ${TEMP}/feFiltreExtractSegments_ImageLine.tif
-  otbExtractSegments
-  ${INPUTDATA}/ImageLine_hd.bsq.hdr
-  ${INPUTDATA}/ImageLineDir.bsq.hdr
-  ${TEMP}/feFiltreExtractSegments_ImageLine.tif
-  10  0.3 10 10 3 10 0.5)
-
 otb_add_test(NAME feTvLineRatio COMMAND otbEdgeTestDriver
   --compare-image ${EPSILON_8}  ${BASELINE}/feFiltreLineRatio_amst_2_3.tif
   ${TEMP}/feFiltreLineRatio_amst_2_3.tif
@@ -283,11 +223,3 @@ otb_add_test(NAME feTvLineCorrelationLinear COMMAND otbEdgeTestDriver
   ${TEMP}/feFiltreLineCorrelationLinear_amst_2_3.tif
   ${TEMP}/feFiltreLineCorrelationLinear_amst_dir_2_3.tif
   2 3)
-
-otb_add_test(NAME feTvFillGapsFilter COMMAND otbEdgeTestDriver
-  --compare-image ${EPSILON_8}
-  ${BASELINE}/feTvFillGapfilter.png
-  ${TEMP}/feTvFillGapfilter.png
-  otbFillGapsFilter
-  ${INPUTDATA}/ImageLine.bsq.hdr
-  ${TEMP}/feTvFillGapfilter.png)
diff --git a/Modules/Feature/Edge/test/otbEdgeTestDriver.cxx b/Modules/Feature/Edge/test/otbEdgeTestDriver.cxx
index 626758efa17f5b8907f3d0f74751f154b5419e24..058cd6024fac4963eb1201a6198570c626d08c50 100644
--- a/Modules/Feature/Edge/test/otbEdgeTestDriver.cxx
+++ b/Modules/Feature/Edge/test/otbEdgeTestDriver.cxx
@@ -25,16 +25,12 @@ void RegisterTests()
   REGISTER_TEST(otbEdgeDetectorImageFilter);
   REGISTER_TEST(otbHorizontalSobelVectorImageFilterTest);
   REGISTER_TEST(otbAsymmetricFusionOfLineDetector);
-  REGISTER_TEST(otbLocalHoughDraw);
   REGISTER_TEST(otbAssociativeSymmetricalSum);
   REGISTER_TEST(otbPersistentVectorizationFilter);
   REGISTER_TEST(otbEdgeDensityImageFilter);
   REGISTER_TEST(otbLineCorrelationDetector);
   REGISTER_TEST(otbSobelVectorImageFilterTest);
-  REGISTER_TEST(otbHoughTransform2DLinesImageTest);
   REGISTER_TEST(otbPixelSuppressionByDirection);
-  REGISTER_TEST(otbLocalHough);
-  REGISTER_TEST(otbExtractSegments);
   REGISTER_TEST(otbLineRatioDetector);
   REGISTER_TEST(otbTouziEdgeDetectorDirection);
   REGISTER_TEST(otbVerticalSobelVectorImageFilterTest);
@@ -44,5 +40,4 @@ void RegisterTests()
   REGISTER_TEST(otbLineSegmentDetector);
   REGISTER_TEST(otbLineSegmentDetector_8b_16b_compare);
   REGISTER_TEST(otbLineCorrelationDetectorLinear);
-  REGISTER_TEST(otbFillGapsFilter);
 }
diff --git a/Modules/Feature/Edge/test/otbExtractSegments.cxx b/Modules/Feature/Edge/test/otbExtractSegments.cxx
deleted file mode 100644
index eb480f327bf4d709af841b58bd9c8658138b2adf..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/test/otbExtractSegments.cxx
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-#include "itkMacro.h"
-#include <iostream>
-
-#include "otbImage.h"
-#include "otbImageFileWriter.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "otbExtractSegmentsImageFilter.h"
-
-int otbExtractSegments(int itkNotUsed(argc), char * argv[])
-{
-  const char * inputFilename1  = argv[1];
-  const char * inputFilename2  = argv[2];
-  const char * outputFilename = argv[3];
-
-  unsigned int PixelSuppressionRadiusX((unsigned int) ::atoi(argv[4]));
-  float        PixelSuppressionAngularBeam((float) ::atof(argv[5]));
-
-  unsigned int LocalHoughRadiusX((unsigned int) ::atoi(argv[6]));
-  unsigned int LocalHoughRadiusY((unsigned int) ::atoi(argv[7]));
-  unsigned int LocalHoughNumberOfLines((unsigned int) ::atoi(argv[8]));
-
-  float FillGapsRadius((float) ::atof(argv[9]));
-  float FillGapsAngularBeam((float) ::atof(argv[10]));
-
-  typedef double InputPixelType;
-  typedef double OutputPixelType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<InputPixelType,  Dimension> InputImageType;
-  typedef otb::Image<OutputPixelType, Dimension> OutputImageType;
-
-  typedef otb::ImageFileReader<InputImageType>                               ReaderType1;
-  typedef otb::ImageFileReader<InputImageType>                               ReaderType2;
-  typedef otb::ImageFileWriter<OutputImageType>                              WriterType;
-  typedef itk::RescaleIntensityImageFilter<OutputImageType, OutputImageType> RescalerType;
-
-  typedef otb::ExtractSegmentsImageFilter<InputImageType, OutputImageType> FilterType;
-
-  FilterType::Pointer filter = FilterType::New();
-
-  // filter parameters
-
-  FilterType::SizeType PixelSuppressionRadius;
-  PixelSuppressionRadius[0] = PixelSuppressionRadiusX;
-  PixelSuppressionRadius[1] = PixelSuppressionRadiusX;
-
-  filter->SetPixelSuppressionRadius(PixelSuppressionRadius);
-  filter->SetPixelSuppressionAngularBeam(PixelSuppressionAngularBeam);
-
-  FilterType::SizeType LocalHoughRadius;
-  LocalHoughRadius[0] = LocalHoughRadiusX;
-  LocalHoughRadius[1] = LocalHoughRadiusY;
-
-  filter->SetLocalHoughRadius(LocalHoughRadius);
-  filter->SetLocalHoughNumberOfLines(LocalHoughNumberOfLines);
-
-  filter->SetFillGapsRadius(FillGapsRadius);
-  filter->SetFillGapsAngularBeam(FillGapsAngularBeam);
-
-  // Reader / Writer
-
-  ReaderType1::Pointer  reader1 = ReaderType1::New();
-  ReaderType2::Pointer  reader2 = ReaderType2::New();
-  WriterType::Pointer   writer = WriterType::New();
-  RescalerType::Pointer rescaler = RescalerType::New();
-
-  rescaler->SetOutputMinimum(0);
-  rescaler->SetOutputMaximum(255);
-
-  reader1->SetFileName(inputFilename1);
-  reader2->SetFileName(inputFilename2);
-  writer->SetFileName(outputFilename);
-
-  filter->SetInputImage(reader1->GetOutput());
-  filter->SetInputImageDirection(reader2->GetOutput());
-  rescaler->SetInput(filter->GetOutput());
-  writer->SetInput(rescaler->GetOutput());
-
-  writer->Update();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Edge/test/otbFillGapsFilter.cxx b/Modules/Feature/Edge/test/otbFillGapsFilter.cxx
deleted file mode 100644
index 17c7a0215874fea4924a656bb5c4e6e2045fda6d..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/test/otbFillGapsFilter.cxx
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-#include "itkMacro.h"
-#include "otbFillGapsFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "otbDrawLineSpatialObjectListFilter.h"
-
-int otbFillGapsFilter(int itkNotUsed(argc), char * argv[])
-{
-  const char * inputFilename  = argv[1];
-  const char * outputFilename = argv[2];
-
-  typedef double        InputPixelType;
-  typedef unsigned char OutputPixelType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<InputPixelType,  Dimension> InputImageType;
-  typedef otb::Image<OutputPixelType, Dimension> OutputImageType;
-
-  typedef otb::DrawLineSpatialObjectListFilter<InputImageType, OutputImageType> FilterType;
-
-  typedef otb::FillGapsFilter        FillGapsFilterType;
-  typedef otb::LineSpatialObjectList LinesListType;
-  typedef LinesListType::LineType    LineType;
-
-  FilterType::Pointer filter = FilterType::New();
-
-  typedef otb::ImageFileReader<InputImageType>  ReaderType;
-  typedef otb::ImageFileWriter<OutputImageType> WriterType;
-
-  ReaderType::Pointer reader = ReaderType::New();
-  WriterType::Pointer writer = WriterType::New();
-
-  reader->SetFileName(inputFilename);
-  writer->SetFileName(outputFilename);
-
-  FillGapsFilterType::Pointer fillgaps = FillGapsFilterType::New();
-
-  LinesListType::Pointer linesListBeforeFillGaps = LinesListType::New();
-  const LinesListType *  linesListAfterFillGaps;
-
-  LineType::PointListType pointList;
-  LineType::LinePointType point;
-
-  // Definition of the first line
-  double Ux, Uy, Vx, Vy;
-  Ux = 10.;
-  Uy = 10.;
-  Vx = 10.;
-  Vy = 20.;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line = LineType::New();
-  line->SetId(0);
-  line->SetPoints(pointList);
-  line->ComputeBoundingBox();
-
-  linesListBeforeFillGaps->push_back(line);
-
-  pointList.clear();
-
-  // Definition of a second line
-
-  Ux = 10.;
-  Uy = 30.;
-  Vx = 10.;
-  Vy = 50.;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line2 = LineType::New();
-  line2->SetId(0);
-  line2->SetPoints(pointList);
-  line2->ComputeBoundingBox();
-
-  linesListBeforeFillGaps->push_back(line2);
-
-  pointList.clear();
-
-  // Definition of a third line
-
-  Ux = 20.;
-  Uy = 50.;
-  Vx = 50.;
-  Vy = 50.;
-
-  point.SetPosition(Ux, Uy);
-  pointList.push_back(point);
-  point.SetPosition(Vx, Vy);
-  pointList.push_back(point);
-
-  LineType::Pointer line3 = LineType::New();
-  line3->SetId(0);
-  line3->SetPoints(pointList);
-  line3->ComputeBoundingBox();
-
-  linesListBeforeFillGaps->push_back(line3);
-
-  pointList.clear();
-  //  FillGapsFilter parameters
-
-  fillgaps->SetRadius(15.);
-  fillgaps->SetAngularBeam(1.0);  // Angle in Radian
-  fillgaps->SetInput(linesListBeforeFillGaps);
-  linesListAfterFillGaps = fillgaps->GetOutput();
-  fillgaps->Update();
-
-  filter->SetInputLineSpatialObjectList(linesListAfterFillGaps);
-  filter->SetInput(reader->GetOutput());
-  writer->SetInput(filter->GetOutput());
-
-  writer->Update();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Edge/test/otbHoughTransform2DLinesImageTest.cxx b/Modules/Feature/Edge/test/otbHoughTransform2DLinesImageTest.cxx
deleted file mode 100644
index 2a006452cef0fdf6fb6aa9f5367339dbfd6c7881..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/test/otbHoughTransform2DLinesImageTest.cxx
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 1999-2011 Insight Software Consortium
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "otbHoughTransform2DLinesImageFilter.h"
-#include "itkImageRegionIterator.h"
-#include "itkThresholdImageFilter.h"
-#include "itkMinimumMaximumImageCalculator.h"
-#include <itkGradientMagnitudeImageFilter.h>
-#include <itkDiscreteGaussianImageFilter.h>
-#include <itkCastImageFilter.h>
-
-#include <list>
-
-#include "otbImageFileWriter.h"
-
-/**
- * This program looks for straight lines whithin an image
- * It uses the ITK HoughTransform2DLinesImageFilter.
- * - Read the image.
- * - Apply a gradient and thresholding functions.
- * - Compute the accumulator by running the filter.
- * - Blur the accumulator.
- * - Find maxima in the accumulator.
- * - Display the results
- */
-
-/** Hough Point structure */
-struct houghPoint
-{
-  double radius;
-  double angle;
-};
-
-/** Main program */
-int otbHoughTransform2DLinesImageTest(int itkNotUsed(argc), char* argv[])
-{
-
-  const char * outputFilename =  argv[1];
-
-  /** Typedefs */
-  typedef   unsigned char                        PixelType;
-  typedef   double                               HoughSpacePixelType;
-  typedef   otb::Image<HoughSpacePixelType, 2>   HoughImageType;
-  typedef   otb::Image<PixelType, 2>             ImageType;
-  typedef   otb::ImageFileWriter<HoughImageType> WriterType;
-
-  itk::Index<2> m_Index;
-
-  /** Create a line image with one line */
-  std::cout << "Creating simulated image" << std::endl;
-  ImageType::Pointer    m_Image = ImageType::New();
-  ImageType::RegionType region;
-  ImageType::SizeType   size;
-  size.Fill(100);
-  ImageType::IndexType index;
-  index.Fill(0);
-  region.SetSize(size);
-  region.SetIndex(index);
-  m_Image->SetRegions(region);
-  m_Image->Allocate();
-  m_Image->FillBuffer(0);
-
-  /** Create a line */
-  float teta = 0.20; // radians
-  float radius = 50;
-
-  double Vx = radius * cos(teta);
-  double Vy = radius * sin(teta);
-
-  double norm = sqrt(Vx * Vx + Vy * Vy);
-  double VxNorm = Vx / norm;
-  double VyNorm = Vy / norm;
-
-  unsigned int maxval = size[0] * size[1];
-
-  const double nPI = 4.0 * std::atan(1.0);
-
-  for (unsigned int i = 0; i < maxval; i += 1)
-    {
-    m_Index[0] = (long int) (Vx - VyNorm * i);
-    m_Index[1] = (long int) (Vy + VxNorm * i);
-
-    if (((m_Index[0] < (long) size[0]) && (m_Index[0] >= 0))
-        && ((m_Index[1] < (long) size[1]) && (m_Index[1] >= 0))
-        )
-      {
-      m_Image->SetPixel(m_Index, 255);
-      }
-    }
-
-  /** Allocate Hough Space image (accumulator) */
-  std::cout << "Allocating Hough Space Image" << std::endl;
-  HoughImageType::Pointer m_HoughSpaceImage = HoughImageType::New();
-  m_HoughSpaceImage->SetRegions(region);
-  m_HoughSpaceImage->Allocate();
-
-  /** Apply gradient filter to the input image */
-  typedef itk::CastImageFilter<
-      ImageType,
-      HoughImageType>    CastingFilterType;
-
-  CastingFilterType::Pointer caster = CastingFilterType::New();
-  caster->SetInput(m_Image);
-
-  std::cout << "Applying gradient magnitude filter" << std::endl;
-  typedef itk::GradientMagnitudeImageFilter<HoughImageType, HoughImageType> GradientFilterType;
-  GradientFilterType::Pointer gradFilter =  GradientFilterType::New();
-  gradFilter->SetInput(caster->GetOutput());
-  gradFilter->Update();
-
-  /** Apply a threshold to the Grad(InputImage) */
-  std::cout << "Thresholding" << std::endl;
-  typedef itk::ThresholdImageFilter<HoughImageType> ThresholdFilterType;
-  ThresholdFilterType::Pointer threshFilter = ThresholdFilterType::New();
-  threshFilter->SetInput(gradFilter->GetOutput());
-  threshFilter->SetOutsideValue(0);
-  unsigned char thresh_below = 10;
-  unsigned char thresh_above = 200;
-  threshFilter->ThresholdOutside(thresh_below, thresh_above);
-  threshFilter->Update();
-
-  /** Define the HoughTransform filter */
-  typedef otb::HoughTransform2DLinesImageFilter<HoughSpacePixelType, HoughSpacePixelType> HoughTransformFilterType;
-
-  HoughTransformFilterType::Pointer houghFilter = HoughTransformFilterType::New();
-
-  houghFilter->SetInput(threshFilter->GetOutput());
-
-  houghFilter->SetThreshold(0.0f);
-  if (houghFilter->GetThreshold() != 0.0f)
-    {
-    std::cout << "Failure" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  //houghFilter->SetAngleResolution(500.0f);
-
-  houghFilter->SetDiscRadius(10.0f);
-  if (houghFilter->GetDiscRadius() != 10.0f)
-    {
-    std::cout << "Failure" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  houghFilter->SetVariance(10.0f);
-  if (houghFilter->GetVariance() != 10.0f)
-    {
-    std::cout << "Failure" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  houghFilter->Update();
-  houghFilter->Simplify();
-
-  HoughImageType::Pointer m_SimplifyAccumulator = houghFilter->GetSimplifyAccumulator();
-  HoughImageType::Pointer m_Accumulator = houghFilter->GetOutput();
-
-  WriterType::Pointer writer = WriterType::New();
-  writer->SetFileName(outputFilename);
-  writer->SetInput(m_Accumulator);
-  writer->Update();
-
-  /** Blur the accumulator in order to find the maximum */
-  HoughImageType::Pointer m_PostProcessImage = HoughImageType::New();
-  typedef itk::DiscreteGaussianImageFilter<HoughImageType, HoughImageType> GaussianFilterType;
-  GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
-  gaussianFilter->SetInput(m_Accumulator);
-  double variance[2];
-  variance[0] = 10;
-  variance[1] = 10;
-  gaussianFilter->SetVariance(variance);
-  gaussianFilter->SetMaximumError(.01f);
-  gaussianFilter->Update();
-  m_PostProcessImage = gaussianFilter->GetOutput();
-
-  typedef itk::MinimumMaximumImageCalculator<HoughImageType> MinMaxCalculatorType;
-  MinMaxCalculatorType::Pointer minMaxCalculator = MinMaxCalculatorType::New();
-
-  itk::ImageRegionIterator<HoughImageType> it_output(m_HoughSpaceImage, m_HoughSpaceImage->GetLargestPossibleRegion());
-  itk::ImageRegionIterator<HoughImageType> it_input(m_PostProcessImage, m_PostProcessImage->GetLargestPossibleRegion());
-
-  /** Set the number of lines we are looking for. */
-  unsigned int m_NumberOfLines = 1;
-  /** Each time we find a maximum we remove it by drawing a black disc
-      this define the size of this disc */
-  unsigned int m_HoughDiscRadius = 10;
-
-  unsigned int          lines = 0;
-  std::list<houghPoint> m_LinesList;
-
-  /** Find maxima */
-  do
-    {
-    minMaxCalculator->SetImage(m_PostProcessImage);
-    minMaxCalculator->ComputeMaximum();
-    HoughImageType::PixelType max = minMaxCalculator->GetMaximum();
-
-    for (it_input.GoToBegin(); !it_input.IsAtEnd(); ++it_input)
-      {
-      if (it_input.Get() == max)
-        {
-        houghPoint m_HoughPoint;
-        m_HoughPoint.radius = it_input.GetIndex()[0];
-        m_HoughPoint.angle  = ((it_input.GetIndex()[1]) * 2 * nPI / houghFilter->GetAngleAxisSize()) - nPI;
-
-        m_LinesList.push_back(m_HoughPoint);
-
-        // Remove a black disc from the hough space domain
-        for (double angle = 0; angle <= 2 * nPI; angle += nPI / 1000)
-          {
-          for (double length = 0; length < m_HoughDiscRadius; length += 1)
-            {
-            m_Index[0] = (long int) (it_input.GetIndex()[0] + length * cos(angle));
-            m_Index[1] = (long int) (it_input.GetIndex()[1] + length * sin(angle));
-            if (((m_Index[0] <= sqrt((double) 400 * 400 + 400 * 400)) && (m_Index[0] >= 0))
-                && ((m_Index[1] <= 500) && (m_Index[1] >= 0))
-                )
-              {
-              m_Accumulator->SetPixel(m_Index, 0);
-              }
-            }
-          }
-        minMaxCalculator->SetImage(m_Accumulator);
-        minMaxCalculator->ComputeMaximum();
-        max = minMaxCalculator->GetMaximum();
-
-        lines++;
-        if (lines == m_NumberOfLines) break;
-        }
-      }
-    }
-  while (lines < m_NumberOfLines);
-
-  std::list<houghPoint>::iterator it_list = m_LinesList.begin();
-
-  while (it_list != m_LinesList.end())
-    {
-    std::cout << "Angle = " << it_list->angle << " (expected " << teta << ")" << std::endl;
-    std::cout << "Radius = " << it_list->radius << " (expected " << radius << ")" << std::endl;
-
-    if (fabs(it_list->angle - teta) > 0.1)
-      {
-      std::cout << "Failure" << std::endl;
-      //return EXIT_FAILURE;
-      }
-    if (fabs(it_list->radius - radius) > 1.0)
-      {
-      std::cout << "Failure" << std::endl;
-      //return EXIT_FAILURE;
-      }
-    it_list++;
-    }
-
-  std::cout << "Printing Hough Fiter information:" << std::endl;
-  std::cout << houghFilter << std::endl;
-
-  std::cout << "Hough Transform Successful" << std::endl;
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Edge/test/otbLocalHough.cxx b/Modules/Feature/Edge/test/otbLocalHough.cxx
deleted file mode 100644
index 5704ab1f3db7c7a9b811aa1417455612540f83d8..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/test/otbLocalHough.cxx
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-#include "itkMacro.h"
-
-#include <iostream>
-
-#include "otbImageFileReader.h"
-
-#include "otbLocalHoughFilter.h"
-
-#include <iostream>
-#include <fstream>
-
-int otbLocalHough(int itkNotUsed(argc), char* argv[])
-{
-  const char * inputFilename  = argv[1];
-  const char * outfname  = argv[2];
-  unsigned int RadiusX((unsigned int) ::atoi(argv[3]));
-  unsigned int RadiusY((unsigned int) ::atoi(argv[4]));
-  unsigned int NumberOfLines((unsigned int) ::atoi(argv[5]));
-
-  typedef unsigned char InputPixelType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<InputPixelType,  Dimension> InputImageType;
-
-  typedef otb::LocalHoughFilter<InputImageType> FilterType;
-
-  FilterType::Pointer filter = FilterType::New();
-
-  typedef otb::ImageFileReader<InputImageType> ReaderType;
-
-  ReaderType::Pointer reader = ReaderType::New();
-
-  reader->SetFileName(inputFilename);
-  reader->Update();
-
-  FilterType::SizeType Radius;
-  Radius[0] = RadiusX;
-  Radius[1] = RadiusY;
-
-  typedef otb::LineSpatialObjectList LinesListType;
-  LinesListType::Pointer list = LinesListType::New();
-
-  filter->SetRadius(Radius);
-  filter->SetNumberOfLines(NumberOfLines);
-
-  filter->SetInput(reader->GetOutput());
-  filter->Update();
-
-  list = filter->GetOutput();
-
-  LinesListType::const_iterator itList;
-
-  std::ofstream outfile(outfname);
-  outfile << "size of the Line list " << list->size() << std::endl;
-
-  for (itList = list->begin(); itList != list->end(); itList++)
-    outfile << (*itList)->GetPoints()[0].GetPosition()  << " \t" << (*itList)->GetPoints()[1].GetPosition()   <<
-    std::endl;
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Edge/test/otbLocalHoughDraw.cxx b/Modules/Feature/Edge/test/otbLocalHoughDraw.cxx
deleted file mode 100644
index c7d1dae59f97dd32c6f3382b044023620f33638a..0000000000000000000000000000000000000000
--- a/Modules/Feature/Edge/test/otbLocalHoughDraw.cxx
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-#include "itkMacro.h"
-
-#include <iostream>
-#include <list>
-
-#include "otbImageFileWriter.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-
-#include "otbLocalHoughFilter.h"
-#include "otbDrawLineSpatialObjectListFilter.h"
-
-
-#include "itkRescaleIntensityImageFilter.h"
-
-int otbLocalHoughDraw(int itkNotUsed(argc), char* argv[])
-{
-  const char * inputFilename  = argv[1];
-  const char * outputFilename = argv[2];
-
-  unsigned int RadiusX((unsigned int) ::atoi(argv[3]));
-  unsigned int RadiusY((unsigned int) ::atoi(argv[4]));
-  unsigned int NumberOfLines((unsigned int) ::atoi(argv[5]));
-
-  typedef unsigned char InputPixelType;
-  typedef unsigned char OutputPixelType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<InputPixelType,  Dimension> InputImageType;
-  typedef otb::Image<OutputPixelType, Dimension> OutputImageType;
-
-  typedef otb::LocalHoughFilter<InputImageType> FilterType;
-  //typedef otb::ImageToLineSpatialObjectListFilter< InputImageType >   FilterType;
-
-  FilterType::Pointer filter = FilterType::New();
-
-  typedef otb::ImageFileReader<InputImageType>  ReaderType;
-  typedef otb::ImageFileWriter<OutputImageType> WriterType;
-
-  typedef itk::RescaleIntensityImageFilter<InputImageType> RescalerType;
-
-  ReaderType::Pointer   reader = ReaderType::New();
-  WriterType::Pointer   writer = WriterType::New();
-  RescalerType::Pointer rescaler = RescalerType::New();
-
-  reader->SetFileName(inputFilename);
-  reader->Update();
-
-  writer->SetFileName(outputFilename);
-
-  FilterType::SizeType Radius;
-  Radius[0] = RadiusX;
-  Radius[1] = RadiusY;
-
-  filter->SetRadius(Radius);
-  filter->SetNumberOfLines(NumberOfLines);
-
-  rescaler->SetInput(reader->GetOutput());
-  filter->SetInput(rescaler->GetOutput());
-  filter->Update();
-
-  typedef otb::DrawLineSpatialObjectListFilter<InputImageType, OutputImageType> DrawFilterType;
-
-  DrawFilterType::Pointer drawfilter = DrawFilterType::New();
-
-  drawfilter->SetInputLineSpatialObjectList(filter->GetOutput());
-
-  drawfilter->SetInput(reader->GetOutput());
-  writer->SetInput(drawfilter->GetOutput());
-
-  writer->Update();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Filtering/ChangeDetection/test/CMakeLists.txt b/Modules/Filtering/ChangeDetection/test/CMakeLists.txt
index 4996b057f7b7f15cd50ad55dd2ceae1cea6f4e40..5acae45eac4aec5efdae39344d4f9d540df8b485 100644
--- a/Modules/Filtering/ChangeDetection/test/CMakeLists.txt
+++ b/Modules/Filtering/ChangeDetection/test/CMakeLists.txt
@@ -119,7 +119,7 @@ otb_add_test(NAME cdTvKullbackLeiblerProfileImageFilter COMMAND otbChangeDetecti
   ${INPUTDATA}/GomaAvant.png
   ${INPUTDATA}/GomaApres.png
   ${TEMP}/cdTVKullbackLeiblerProfileImageFilterOutput.tif
-  5 51)
+  5 31)
 
 otb_add_test(NAME cdTvKullbackLeiblerDistanceImageFilter COMMAND otbChangeDetectionTestDriver
   --compare-image ${EPSILON_10}
diff --git a/Modules/Filtering/Convolution/test/CMakeLists.txt b/Modules/Filtering/Convolution/test/CMakeLists.txt
index cb04f053d5fea5e7019d0ffafd13182d9ccc71e9..3ac91e9978e91f393e221dfb1589f971bf3fa9de 100644
--- a/Modules/Filtering/Convolution/test/CMakeLists.txt
+++ b/Modules/Filtering/Convolution/test/CMakeLists.txt
@@ -44,6 +44,10 @@ otb_add_test(NAME bfTvConvolutionImageFilter COMMAND otbConvolutionTestDriver
   )
 
 if(ITK_USE_FFTWD)
+
+if(MSVC AND (CMAKE_SIZEOF_VOID_P EQUAL "4"))
+  message(WARNING "Disable bfTvOverlapSaveConvolutionImageFilter")
+else()
 otb_add_test(NAME bfTvOverlapSaveConvolutionImageFilter COMMAND otbConvolutionTestDriver
   --compare-image ${EPSILON_7}
   ${BASELINE}/bfTvConvolutionImageFilter.tif
@@ -52,16 +56,17 @@ otb_add_test(NAME bfTvOverlapSaveConvolutionImageFilter COMMAND otbConvolutionTe
   ${INPUTDATA}/QB_Suburb.png
   ${TEMP}/bfTvOverlapSaveConvolutionImageFilter.tif
   )
+endif()
 
 otb_add_test(NAME bfTvCompareOverlapSaveAndClassicalConvolutionWithGaborFilter COMMAND otbConvolutionTestDriver
   --compare-image ${EPSILON_7}
   ${TEMP}/bfTvCompareConvolutionOutput.tif
   ${TEMP}/bfTvCompareOSConvolutionoutput.tif
   otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter
-  ${INPUTDATA}/ROI_IKO_PAN_LesHalles_sub.tif
+  ${INPUTDATA}/QB_PAN_ROI_1000_100.tif
   ${TEMP}/bfTvCompareConvolutionOutput.tif
   ${TEMP}/bfTvCompareOSConvolutionoutput.tif
-  64 64 #Radius
+  32 32 #Radius
   0.02 0.025 # a b
   -45 # theta
   0.0125 0.0125 #u0 v0
diff --git a/Modules/Filtering/DimensionalityReduction/include/otbEstimateInnerProductPCAImageFilter.hxx b/Modules/Filtering/DimensionalityReduction/include/otbEstimateInnerProductPCAImageFilter.hxx
index 24cbb84debf8052f399583c6025488e58f4029a3..7f9d5d39f51012af6e1f83b6261571cb9a467ea1 100644
--- a/Modules/Filtering/DimensionalityReduction/include/otbEstimateInnerProductPCAImageFilter.hxx
+++ b/Modules/Filtering/DimensionalityReduction/include/otbEstimateInnerProductPCAImageFilter.hxx
@@ -34,9 +34,8 @@ namespace otb
  */
 template <class TInputImage, class TOutputImage>
 EstimateInnerProductPCAImageFilter<TInputImage, TOutputImage>
-::EstimateInnerProductPCAImageFilter()
+::EstimateInnerProductPCAImageFilter(): m_NumberOfPrincipalComponentsRequired(1), m_CenterData(true)
 {
-  m_NumberOfPrincipalComponentsRequired = 1;
 }
 
 /**
diff --git a/Modules/Filtering/DimensionalityReduction/include/otbInnerProductPCAImageFilter.hxx b/Modules/Filtering/DimensionalityReduction/include/otbInnerProductPCAImageFilter.hxx
index ab3b3e331ca9b90aaa603ad85b03e90b4f64fc13..1498285a882c51ebcc72eb58c2b46b3db987afeb 100644
--- a/Modules/Filtering/DimensionalityReduction/include/otbInnerProductPCAImageFilter.hxx
+++ b/Modules/Filtering/DimensionalityReduction/include/otbInnerProductPCAImageFilter.hxx
@@ -36,6 +36,7 @@ InnerProductPCAImageFilter<TInputImage, TOutputImage>
   this->SetNthOutput(0, OutputImageType::New());
   m_EstimatePCAFilter  = EstimatePCAFilterType::New();
   m_NormalizePCAFilter  = NormalizePCAFilterType::New();
+  m_NumberOfPrincipalComponentsRequired = 1;
   m_CenterData = true;
   m_GenerateMeanComponent = false;
   m_MeanFilter = MeanFilterType::New();
diff --git a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.hxx b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.hxx
index 6a0de2726707cd5f9cd7734f3ef18f245317e664..d3e1d6e60a9685044e04bbd321b059cf4f79901c 100644
--- a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.hxx
+++ b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.hxx
@@ -36,14 +36,18 @@ namespace otb
  */
 template <class TInputImage, class TOutputImage, class TFunction>
 MultiChannelsPolarimetricSynthesisFilter<TInputImage, TOutputImage, TFunction>
-::MultiChannelsPolarimetricSynthesisFilter()
+::MultiChannelsPolarimetricSynthesisFilter():
+    m_PsiI(0.0),
+    m_KhiI(0.0),
+    m_PsiR(0.0),
+    m_KhiR(0.0),
+    m_Gain(1.0),
+    m_Mode(0),
+    m_EmissionH(false),
+    m_EmissionV(false)
 {
   this->SetNumberOfRequiredInputs(1);
   this->InPlaceOff();
-  SetEmissionH(false);
-  SetEmissionV(false);
-  SetGain(1);
-  SetMode(0);
   m_ArchitectureType = PolarimetricData::New();
 }
 
diff --git a/Modules/Filtering/Smoothing/include/otbMeanShiftSmoothingImageFilter.h b/Modules/Filtering/Smoothing/include/otbMeanShiftSmoothingImageFilter.h
index 606c00e3d678a8fcf98b7fbad52aa722ed082730..ca8e5c5db216468754921f701aa68a8acedc8617 100644
--- a/Modules/Filtering/Smoothing/include/otbMeanShiftSmoothingImageFilter.h
+++ b/Modules/Filtering/Smoothing/include/otbMeanShiftSmoothingImageFilter.h
@@ -59,10 +59,12 @@ class SpatialRangeJointDomainTransform
 public:
   typedef double RealType;
 
-  SpatialRangeJointDomainTransform()
+  SpatialRangeJointDomainTransform():
+      m_ImageDimension(0),
+      m_NumberOfComponentsPerPixel(0),
+      m_OutputSize(0)
   {
   }
-  // ~SpatialRangeJointDomainTransform() {}
 
   typename TOutputJointImage::PixelType operator()(const typename TInputImage::PixelType & inputPixel,
                                                    const typename TInputImage::IndexType & index) const
diff --git a/Modules/Filtering/Smoothing/test/CMakeLists.txt b/Modules/Filtering/Smoothing/test/CMakeLists.txt
index d66fafefd43dd775dc9346e92350490e51799430..1272ed6c4d72d15cc0e973b196d89bce31db03e1 100644
--- a/Modules/Filtering/Smoothing/test/CMakeLists.txt
+++ b/Modules/Filtering/Smoothing/test/CMakeLists.txt
@@ -74,13 +74,13 @@ otb_add_test(NAME bfTvMeanShiftSmoothingImageFilterNonOptim COMMAND otbSmoothing
   2 10 0.1 10 0
   )
 
-otb_add_test(NAME bfTuMeanShiftSmoothingImageFilterROIQBMul4 COMMAND otbSmoothingTestDriver
+otb_add_test(NAME bfTuMeanShiftSmoothingImageFilterROIQB COMMAND otbSmoothingTestDriver
   otbMeanShiftSmoothingImageFilter
-  ${INPUTDATA}/ROI_QB_MUL_4.tif
-  ${TEMP}/bfMeanShiftSmoothingImageFilterSpatialOutput_ROIQBMul4.tif
-  ${TEMP}/bfMeanShiftSmoothingImageFilterSpectralOutput_ROIQBMul4.tif
-  ${TEMP}/bfMeanShiftSmoothingImageFilterIterationOutput_ROIQBMul4.tif
-  ${TEMP}/bfMeanShiftSmoothingImageFilterLabelOutput_ROIQBMul4.tif
+  ${INPUTDATA}/QB_MUL_ROI_1000_100.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterSpatialOutput_ROIQB.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterSpectralOutput_ROIQB.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterIterationOutput_ROIQB.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterLabelOutput_ROIQB.tif
   4 50 0.1 100
   )
 
@@ -133,19 +133,19 @@ otb_add_test(NAME bfTuMeanShiftSmoothingImageFilterQBRoad COMMAND otbSmoothingTe
 
 otb_add_test(NAME bfTuMeanShiftSmoothingImageFilterSpatialStability COMMAND otbSmoothingTestDriver
   otbMeanShiftSmoothingImageFilterSpatialStability
-  ${INPUTDATA}/ROI_QB_MUL_4.tif
-  4 50 0.1 40
-  100 100 512 512
+  ${INPUTDATA}/QB_MUL_ROI_1000_100.tif
+  2 50 0.1 10
+  10 10 80 80
   )
 
 
 otb_add_test(NAME bfTvMeanShiftSmoothingImageFilterThreadingNonOpt COMMAND otbSmoothingTestDriver
   --compare-image ${EPSILON_7}
-  ${TEMP}/bfMeanShiftSmoothingImageFilter2SingleThreading_SPOT5.tif
-  ${TEMP}/bfMeanShiftSmoothingImageFilter2MultiThreading_SPOT5.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterSingleThread.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterMultiThread.tif
   otbMeanShiftSmoothingImageFilterThreading
-  ${INPUTDATA}/SPOT5_EXTRACTS/Arcachon/Arcachon_extrait_3852_3319_546_542.tif
-  ${TEMP}/bfMeanShiftSmoothingImageFilter2SingleThreading_SPOT5.tif
-  ${TEMP}/bfMeanShiftSmoothingImageFilter2MultiThreading_SPOT5.tif
-  4 10 0
+  ${INPUTDATA}/QB_MUL_ROI_1000_100.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterSingleThread.tif
+  ${TEMP}/bfMeanShiftSmoothingImageFilterMultiThread.tif
+  4 50 0
   )
diff --git a/Modules/IO/Carto/src/otbOSMDataToVectorDataGenerator.cxx b/Modules/IO/Carto/src/otbOSMDataToVectorDataGenerator.cxx
index 00142693ec1fc12d900853967fad69558bc18779..d4d27aa9ad074d69ad5e92c3225652a6f039e6f5 100644
--- a/Modules/IO/Carto/src/otbOSMDataToVectorDataGenerator.cxx
+++ b/Modules/IO/Carto/src/otbOSMDataToVectorDataGenerator.cxx
@@ -39,7 +39,7 @@ OSMDataToVectorDataGenerator::OSMDataToVectorDataGenerator():m_North(43.62811),
   this->SetNumberOfRequiredOutputs(1);
 
   // Initialize the url
-  m_Url = "http://www.openstreetmap.org/api/0.6/map?";
+  m_Url = "https://www.openstreetmap.org/api/0.6/map?";
 
   m_Curl = CurlHelper::New();
 
diff --git a/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx b/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx
index 6cc001c7b3303c821aa7bdc486769c9b0ed38161..c4183e041285e13a126af3f511336489e3a1e6d8 100644
--- a/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx
+++ b/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx
@@ -49,7 +49,10 @@ GDALDriverManagerWrapper::GDALDriverManagerWrapper()
 
 GDALDriverManagerWrapper::~GDALDriverManagerWrapper()
 {
-  GDALDestroyDriverManager();
+  // GDALDestroyDriverManager();
+  // Since gdal 2.4 we need to explicitely call GDALDestroy
+  // GDALDestroyDriverManager is called inside
+  GDALDestroy(); // gdaldllmain.cpp line 74
 }
 
 // Open the file for reading and returns a smart dataset pointer
diff --git a/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx b/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx
index 2ceeb5a2924dab8e85df2eaf420a4c9ab27c8348..fccaddb38eb76b622d580f9d22fb8b9e07bc6b70 100644
--- a/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx
+++ b/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx
@@ -155,11 +155,6 @@ GDALOverviewsBuilder
   if( factor<=1 )
     return 0;
 
-  assert( minSize>0 );
-
-  if( minSize<=0 )
-    return 0;
-
   assert( !m_GDALDataset.IsNull() );
 
   // unsigned int minSize = static_cast< unsigned int >( pow( factor, n ) );
diff --git a/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx b/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
index 37dace233af58511e43834c904b688bc998f9dea..402042ffb5299e1eb19356e6acbc3a8487c93c27 100644
--- a/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
+++ b/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
@@ -289,6 +289,9 @@ void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** /** unused */)
   if (projectionInformationAvailable)
     {
     oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str()));
+    #if GDAL_VERSION_NUM >= 3000000
+    oSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
+    #endif
     }
 
   // Retrieving root node
diff --git a/Modules/IO/ImageIO/include/otbScalarBufferToImageFileWriter.hxx b/Modules/IO/ImageIO/include/otbScalarBufferToImageFileWriter.hxx
index df34ef682d94a3d097991b54007b6874aafba2ba..45c633b1fd636d99ad489d919488669d66b86285 100644
--- a/Modules/IO/ImageIO/include/otbScalarBufferToImageFileWriter.hxx
+++ b/Modules/IO/ImageIO/include/otbScalarBufferToImageFileWriter.hxx
@@ -43,7 +43,7 @@ void
 ScalarBufferToImageFileWriter<TBufferType, TOutputPixelType>::GenerateData()
 {
   // Check image parameters
-  if( (m_ImageSize[0]==0) || (m_ImageSize[0]==0) )
+  if( (m_ImageSize[0]==0) || (m_ImageSize[1]==0) )
     {
       itkExceptionMacro("Invalid output image size, Size can't be null.");
     }
diff --git a/Modules/IO/TestKernel/src/otbTestDriver.cxx b/Modules/IO/TestKernel/src/otbTestDriver.cxx
index 930c1910b4ea1311fbb60faa47bbf0e29845e533..8939e2cf1fe9f012edec990eb149939bbe114a15 100644
--- a/Modules/IO/TestKernel/src/otbTestDriver.cxx
+++ b/Modules/IO/TestKernel/src/otbTestDriver.cxx
@@ -188,9 +188,8 @@ int main(int ac, char* av[])
 }
 
 // This is a dummy main to be registered as a test for the otbTestMain
-int Execute(int argc, char * argv[])
+int Execute(int, char * argv[])
 {
-  argc -= 1;
   argv += 1;
   // Create the appropriate itk process
   itksysProcess * process = itksysProcess_New();
diff --git a/Modules/IO/TestKernel/src/otbTestHelper.cxx b/Modules/IO/TestKernel/src/otbTestHelper.cxx
index af7f6aa58d4ef96437508649fc20db2c3cdc42d7..5253e37f20ee0c0a05cdf6c7e8f5be4bc7ff9804 100644
--- a/Modules/IO/TestKernel/src/otbTestHelper.cxx
+++ b/Modules/IO/TestKernel/src/otbTestHelper.cxx
@@ -2613,26 +2613,37 @@ void TestHelper::ogrReportOnLayer(OGRLayer * ref_poLayer,
     CheckValueTolerance("Extent: MaxX", ref_oExt.MaxX, test_oExt.MaxX, nbdiff, m_ReportErrors, epsilon);
     CheckValueTolerance("Extent: MaxY", ref_oExt.MaxY, test_oExt.MaxY, nbdiff, m_ReportErrors, epsilon);
     }
+  
+  
+  /// Spatial reference comparison :
+  /// We use the IsSame GDAL method to determine if the spatial references are equivalent,
+  /// if they're not, a wkt string comparison is done for error reporting.
+  /// Note that two spatial references might be equivalent without having the same
+  /// wkt representation.
+  if ((ref_poLayer->GetSpatialRef() == nullptr) || 
+      (test_poLayer->GetSpatialRef() == nullptr) || 
+      ( ! ref_poLayer->GetSpatialRef()->IsSame( test_poLayer->GetSpatialRef() ) ))
+  {
+    char *ref_pszWKT;
+    char *test_pszWKT;
 
-  char *ref_pszWKT;
-  char *test_pszWKT;
-
-  if (ref_poLayer->GetSpatialRef() == nullptr) ref_pszWKT = CPLStrdup("(unknown)");
-  else
-    {
-    ref_poLayer->GetSpatialRef()->exportToPrettyWkt(&ref_pszWKT);
-    }
-  if (test_poLayer->GetSpatialRef() == nullptr) test_pszWKT = CPLStrdup("(unknown)");
-  else
-    {
-    test_poLayer->GetSpatialRef()->exportToPrettyWkt(&test_pszWKT);
-    }
-
-  otbCheckStringValue("Layer SRS WKT", ref_pszWKT, test_pszWKT, nbdiff, m_ReportErrors);
-
-  CPLFree(ref_pszWKT);
-  CPLFree(test_pszWKT);
+    if (ref_poLayer->GetSpatialRef() == nullptr) ref_pszWKT = CPLStrdup("(unknown)");
+    else
+      {
+      ref_poLayer->GetSpatialRef()->exportToPrettyWkt(&ref_pszWKT);
+      }
+    if (test_poLayer->GetSpatialRef() == nullptr) test_pszWKT = CPLStrdup("(unknown)");
+    else
+      {
+      test_poLayer->GetSpatialRef()->exportToPrettyWkt(&test_pszWKT);
+      }
+  
+    otbCheckStringValue("Layer SRS WKT", ref_pszWKT, test_pszWKT, nbdiff, m_ReportErrors);
 
+    CPLFree(ref_pszWKT);
+    CPLFree(test_pszWKT);
+  }
+  
   otbCheckStringValue("FID Column", ref_poLayer->GetFIDColumn(), test_poLayer->GetFIDColumn(), nbdiff, m_ReportErrors);
   otbCheckStringValue("Geometry Column", ref_poLayer->GetGeometryColumn(),
                       test_poLayer->GetGeometryColumn(), nbdiff, m_ReportErrors);
diff --git a/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx b/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx
index 2b327cafe25714a7825a83c21200583125019fa7..c058234566213edd7551b1517fb81906c73c2b2c 100644
--- a/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx
+++ b/Modules/Learning/Markov/include/otbMarkovRandomFieldFilter.hxx
@@ -243,11 +243,6 @@ void
 MarkovRandomFieldFilter<TInputImage, TClassifiedImage>
 ::Allocate()
 {
-  if (m_NumberOfClasses <= 0)
-    {
-    throw itk::ExceptionObject(__FILE__, __LINE__, "NumberOfClasses <= 0.", ITK_LOCATION);
-    }
-
   //Set the output labelled and allocate the memory
   LabelledImagePointer outputPtr = this->GetOutput();
 
diff --git a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.hxx b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.hxx
index 2545521e7e6c69539463a2f130ebac67acdfdf14..ead92368f7bd5386ac6b1d39c7738a2d42cb227f 100644
--- a/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.hxx
+++ b/Modules/Learning/Sampling/include/otbImageSampleExtractorFilter.hxx
@@ -128,9 +128,16 @@ PersistentImageSampleExtractorFilter<TInputImage>
   if(projectionInformationAvailable)
     {
     OGRSpatialReference imgSRS;
+    
+    #if GDAL_VERSION_NUM >= 3000000 // importFromWkt is const-correct in GDAL 3
+    const char *projWktCstr = projectionRefWkt.c_str();
+    OGRErr err = imgSRS.importFromWkt( &projWktCstr );
+    #else
     const char *projWktCstr = projectionRefWkt.c_str();
     char **projWktPointer = const_cast<char**>(&projWktCstr);
     OGRErr err = imgSRS.importFromWkt( projWktPointer );
+    #endif
+    
     if (err == OGRERR_NONE)
       {
       // get input layer
diff --git a/Modules/Radiometry/Indices/test/otbRadiometricIndicesTest.cxx b/Modules/Radiometry/Indices/test/otbRadiometricIndicesTest.cxx
index 58f76ed98817ba7a2f33e291eb85f31a6e5edccd..a18c6d5a5e669e0d90f4e73705f88802e2cecf94 100644
--- a/Modules/Radiometry/Indices/test/otbRadiometricIndicesTest.cxx
+++ b/Modules/Radiometry/Indices/test/otbRadiometricIndicesTest.cxx
@@ -210,7 +210,7 @@ int otbRadiometricIndexTest(int, char ** const)
     std::cerr << "Calling SetBandIndices with ::MAX should raise a runtime_error exception." << std::endl;
     success = false;
   }
-  catch (const std::runtime_error& e)
+  catch (const std::runtime_error& /*e*/)
   {
   }
 
diff --git a/Modules/Radiometry/OpticalCalibration/include/otbRadianceToReflectanceImageFilter.h b/Modules/Radiometry/OpticalCalibration/include/otbRadianceToReflectanceImageFilter.h
index ceb356b983a2ee3ab783adb1606466f10bc33551..2ce98ce899001ae31f50670c07623548c5f4eb31 100644
--- a/Modules/Radiometry/OpticalCalibration/include/otbRadianceToReflectanceImageFilter.h
+++ b/Modules/Radiometry/OpticalCalibration/include/otbRadianceToReflectanceImageFilter.h
@@ -108,7 +108,7 @@ public:
 private:
   double m_SolarIllumination;
   double m_IlluminationCorrectionCoefficient;
-  double m_UseClamp;
+  bool m_UseClamp;
 };
 }
 
diff --git a/Modules/Registration/DisparityMap/include/otbDisparityMapMedianFilter.hxx b/Modules/Registration/DisparityMap/include/otbDisparityMapMedianFilter.hxx
index ec3834e950a5037574e066e3517ed45fb0914ed8..a75248d5e61d4740ab872b8103082d42fa2be231 100644
--- a/Modules/Registration/DisparityMap/include/otbDisparityMapMedianFilter.hxx
+++ b/Modules/Registration/DisparityMap/include/otbDisparityMapMedianFilter.hxx
@@ -260,7 +260,7 @@ DisparityMapMedianFilter< TInputImage, TOutputImage, TMask>
       InputIt.SetLocation(outputIt.GetIndex());
       for (unsigned int i=0; i<InputIt.Size(); i++)
         {
-        if (!inputmaskPtr || (inputmaskPtr && MaskInputIt.GetPixel(i) != 0))
+        if (!inputmaskPtr || (MaskInputIt.GetPixel(i) != 0))
           {
           p++;
           pixels.push_back(InputIt.GetPixel(i));
@@ -347,7 +347,7 @@ DisparityMapMedianFilter< TInputImage, TOutputImage, TMask>
         MaskInputIt.SetLocation(outputIt.GetIndex());
         }
 
-      if ((!inputmaskPtr || (inputmaskPtr && MaskInputIt.GetCenterPixel() != 0)) &&
+      if ((!inputmaskPtr || (MaskInputIt.GetCenterPixel() != 0)) &&
           std::fabs(InputIt.GetCenterPixel() - MedianIt.Get())>m_IncoherenceThreshold)
         {
         outputDisparityMapIt.Set(0.0); //Remove pixel from disparity map//
diff --git a/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.hxx b/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.hxx
index 2c1ce1af846e8e8088bb08f811299bf794762f73..454a6385f1c86d16a82ad13cb0fff45b0d2ed4cd 100644
--- a/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.hxx
+++ b/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.hxx
@@ -670,9 +670,9 @@ TOutputDisparityImage,TMaskImage,TBlockMatchingFunctor>
           ((tmpIndex[1] - this->m_GridIndex[1] + this->m_Step) % this->m_Step == 0))
         {
         // If the mask is present and valid
-        if(!inLeftMaskPtr || (inLeftMaskPtr && inLeftMaskIt.Get() > 0) )
+        if(!inLeftMaskPtr || (inLeftMaskIt.Get() > 0) )
           {
-          if(!inRightMaskPtr || (inRightMaskPtr && inRightMaskIt.Get() > 0) )
+          if(!inRightMaskPtr || (inRightMaskIt.Get() > 0) )
             {
             int estimatedMinHDisp = m_MinimumHorizontalDisparity;
             int estimatedMinVDisp = m_MinimumVerticalDisparity;
diff --git a/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.hxx b/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.hxx
index 5a2834ff83fe367750eed2bf522c1a42ecfc5ed4..fdf976a52d326216161d337b5b8f3f560b3d97d5 100644
--- a/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.hxx
+++ b/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.hxx
@@ -762,9 +762,9 @@ TDisparityImage,TMaskImage,TBlockMatchingFunctor>
           inRightMaskIt.SetIndex(curRightPos);
           }
         // check that the current positions are not masked
-        if(!inLeftMaskPtr || (inLeftMaskPtr && inLeftMaskIt.Get() > 0) )
+        if(!inLeftMaskPtr || (inLeftMaskIt.Get() > 0) )
           {
-          if(!inRightMaskPtr || (inRightMaskPtr && inRightMaskIt.Get() > 0) )
+          if(!inRightMaskPtr || (inRightMaskIt.Get() > 0) )
             {
             RegionType smallRightRegion;
             smallRightRegion.SetIndex(0,curRightPos[0]-1);
@@ -1195,9 +1195,9 @@ TDisparityImage,TMaskImage,TBlockMatchingFunctor>
           inRightMaskIt.SetIndex(curRightPos);
           }
         // check that the current positions are not masked
-        if(!inLeftMaskPtr || (inLeftMaskPtr && inLeftMaskIt.Get() > 0) )
+        if(!inLeftMaskPtr || (inLeftMaskIt.Get() > 0) )
           {
-          if(!inRightMaskPtr || (inRightMaskPtr && inRightMaskIt.Get() > 0) )
+          if(!inRightMaskPtr || (inRightMaskIt.Get() > 0) )
             {
             RegionType smallRightRegion;
             smallRightRegion.SetIndex(0,curRightPos[0]-1);
@@ -1696,9 +1696,9 @@ TDisparityImage,TMaskImage,TBlockMatchingFunctor>
           inRightMaskIt.SetIndex(curRightPos);
           }
         // check that the current positions are not masked
-        if(!inLeftMaskPtr || (inLeftMaskPtr && inLeftMaskIt.Get() > 0) )
+        if(!inLeftMaskPtr || (inLeftMaskIt.Get() > 0) )
           {
-          if(!inRightMaskPtr || (inRightMaskPtr && inRightMaskIt.Get() > 0) )
+          if(!inRightMaskPtr || (inRightMaskIt.Get() > 0) )
             {
             RegionType smallRightRegion;
             smallRightRegion.SetIndex(0,curRightPos[0]-1);
diff --git a/Modules/Registration/DisparityMap/test/CMakeLists.txt b/Modules/Registration/DisparityMap/test/CMakeLists.txt
index 5d91ed29ad30e0739b781909a884a959aa25d7e4..1017aa1d64584909df800f39678c6639fabaf0ec 100644
--- a/Modules/Registration/DisparityMap/test/CMakeLists.txt
+++ b/Modules/Registration/DisparityMap/test/CMakeLists.txt
@@ -41,7 +41,7 @@ otb_module_target_label(otbDisparityMapTestDriver)
 # Tests Declaration
 
 otb_add_test(NAME dmTvDisparityMapEstimationMethod COMMAND otbDisparityMapTestDriver
-  --compare-ascii ${NOTOL}
+  --compare-ascii ${EPSILON_3}
   ${BASELINE_FILES}/dmDisparityMapEstimationOutput1.txt
   ${TEMP}/dmDisparityMapEstimationOutput1.txt
   otbDisparityMapEstimationMethod
@@ -49,7 +49,7 @@ otb_add_test(NAME dmTvDisparityMapEstimationMethod COMMAND otbDisparityMapTestDr
   ${INPUTDATA}/moving.png
   ${INPUTDATA}/pointSet.png
   ${TEMP}/dmDisparityMapEstimationOutput1.txt
-  20 20
+  10 10
   )
 
 #otb_add_test(NAME dmTvDisparityMapToDEMFilter COMMAND otbDisparityMapTestDriver
diff --git a/Modules/Registration/DisparityMap/test/otbDisparityMapEstimationMethod.cxx b/Modules/Registration/DisparityMap/test/otbDisparityMapEstimationMethod.cxx
index 5ccc5e6c3cb21d8f5419fda1340618a66dcd6dd5..b2150667cc804ee7f05587236d078260f55d42b4 100644
--- a/Modules/Registration/DisparityMap/test/otbDisparityMapEstimationMethod.cxx
+++ b/Modules/Registration/DisparityMap/test/otbDisparityMapEstimationMethod.cxx
@@ -69,8 +69,7 @@ int otbDisparityMapEstimationMethod(int itkNotUsed(argc), char* argv[])
   typedef itk::MinimumMaximumImageCalculator<ImageType> MinMaxType;
   MinMaxType::Pointer mm = MinMaxType::New();
   mm->SetImage(pointSetReader->GetOutput());
-  mm->ComputeMinimum();
-  mm->ComputeMaximum();
+  mm->Compute();
   std::cout << "min: " << (int) mm->GetMinimum() << " max: " << (int) mm->GetMaximum() << std::endl;
 
   PointSetSourceType::Pointer pointSetSource = PointSetSourceType::New();
@@ -96,7 +95,7 @@ int otbDisparityMapEstimationMethod(int itkNotUsed(argc), char* argv[])
 
   // For gradient descent
   optimizer->SetLearningRate(5.0);
-  optimizer->SetNumberOfIterations(600);
+  optimizer->SetNumberOfIterations(100);
   DMEstimationType::ParametersType initialParameters(transform->GetNumberOfParameters());
   initialParameters[0] = 0.0;  // Initial offset in mm along X
   initialParameters[1] = 0.0;  // Initial offset in mm along Y
diff --git a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx
index 8c91096f17efc247f6ad8b001c732ee3ab3ad2c8..5f659baf366148ba89fc491ff9802293e224d239 100644
--- a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx
+++ b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx
@@ -335,7 +335,11 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::GenerateOutpu
   if (!m_ProjectionRef.empty())
     {
     OGRSpatialReference oSRS;
+    #if GDAL_VERSION_NUM >= 3000000 // importFromWkt is const-correct in GDAL 3
+    const char *wkt = m_ProjectionRef.c_str();
+    #else
     char *wkt = const_cast<char *> (m_ProjectionRef.c_str());
+    #endif
     oSRS.importFromWkt(&wkt);
     m_IsGeographic = oSRS.IsGeographic(); // TODO check if this test is valid for all projection systems
     }
diff --git a/Modules/Segmentation/CCOBIA/test/CMakeLists.txt b/Modules/Segmentation/CCOBIA/test/CMakeLists.txt
index 6b069c12e398afb8a0b896c9271b577c7bc358a6..31def1a098e3191eb726383687d80a3379facf39 100644
--- a/Modules/Segmentation/CCOBIA/test/CMakeLists.txt
+++ b/Modules/Segmentation/CCOBIA/test/CMakeLists.txt
@@ -70,12 +70,12 @@ otb_add_test(NAME bfTvConnectedComponentMuParserFunctorTestMask COMMAND otbCCOBI
 
 otb_add_test(NAME obTuMeanShiftStreamingConnectedComponentSegmentationOBIAToVectorDataFilter COMMAND otbCCOBIATestDriver
   otbMeanShiftStreamingConnectedComponentSegmentationOBIAToVectorDataFilter
-  ${INPUTDATA}/ROI_QB_MUL_4.tif
+  ${INPUTDATA}/QB_MUL_ROI_1000_100.tif
   ${TEMP}/obTuMeanShiftStreamingConnectedComponentSegmentationOBIAToVectorDataFilter.shp
-  9
-  10
-  0.001
-  "distance<10"
+  6
+  50
+  0.1
+  "distance<20"
   20
   "SHAPE_Elongation>10"
   5)
diff --git a/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.hxx b/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.hxx
index 126422d6302dc111e0afe93e1679bc31aab3ef73..c1f105665f3bb1ec79490ea5ed3d1871fb0eb415 100644
--- a/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.hxx
+++ b/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.hxx
@@ -144,7 +144,7 @@ LabelImageToVectorDataFilter<TInputImage, TPrecision>
     // integer make us pointing to an non allowed memory block => Crash.
     std::ostringstream stream;
     stream << "MEM:::"
-           <<  "DATAPOINTER=" << (unsigned long)(GUIntBig)(this->GetInput()->GetBufferPointer()) << ","
+           <<  "DATAPOINTER=" << (uintptr_t)(this->GetInput()->GetBufferPointer()) << ","
            <<  "PIXELS=" << size[0] << ","
            <<  "LINES=" << size[1] << ","
            <<  "BANDS=" << nbBands << ","
@@ -216,7 +216,7 @@ LabelImageToVectorDataFilter<TInputImage, TPrecision>
       // integer make us pointing to an non allowed memory block => Crash.
       std::ostringstream maskstream;
       maskstream << "MEM:::"
-            <<  "DATAPOINTER=" << (unsigned long) (GUIntBig) (this->GetInputMask()->GetBufferPointer()) << ","
+            <<  "DATAPOINTER=" << (uintptr_t)(this->GetInputMask()->GetBufferPointer()) << ","
             <<  "PIXELS=" << size[0] << ","
             <<  "LINES=" << size[1] << ","
             <<  "BANDS=" << nbBands << ","
diff --git a/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.hxx b/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.hxx
index 09f98d19724367b2311106a820833515d690b5a4..a24448c51a7f6923c8f9107ec0a45a77f5486ed1 100644
--- a/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.hxx
+++ b/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.hxx
@@ -154,10 +154,10 @@ RasterizeVectorDataFilter<TVectorData, TInputImage, TOutputImage>::GenerateData(
 
   // register drivers
   GDALAllRegister();
-
+  
   std::ostringstream stream;
   stream << "MEM:::"
-         <<  "DATAPOINTER=" << (unsigned long) (GUIntBig) (this->GetOutput()->GetBufferPointer()) << ","
+         <<  "DATAPOINTER=" << (uintptr_t)(this->GetOutput()->GetBufferPointer()) << ","
          <<  "PIXELS=" << bufferedRegion.GetSize()[0] << ","
          <<  "LINES=" << bufferedRegion.GetSize()[1]<< ","
          <<  "BANDS=" << nbBands << ","
diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.hxx b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.hxx
index 7a6836f2ae2dbfd47817cfc07eb1e6b615f4323c..a67a218c1e142589dd6cce8d6f913c933a2427da 100644
--- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.hxx
+++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.hxx
@@ -272,7 +272,7 @@ VectorDataToLabelImageFilter<TVectorData, TOutputImage>::GenerateData()
 
   std::ostringstream stream;
   stream << "MEM:::"
-         <<  "DATAPOINTER=" << (unsigned long)(GUIntBig)(this->GetOutput()->GetBufferPointer()) << ","
+         <<  "DATAPOINTER=" << (uintptr_t)(this->GetOutput()->GetBufferPointer()) << ","
          <<  "PIXELS=" << bufferedRegion.GetSize()[0] << ","
          <<  "LINES=" << bufferedRegion.GetSize()[1]<< ","
          <<  "BANDS=" << nbBands << ","
diff --git a/Modules/Segmentation/MeanShift/test/CMakeLists.txt b/Modules/Segmentation/MeanShift/test/CMakeLists.txt
index 14bf2c3b75fb8321663021ca1b70f71a8001d8f1..f7186627cbbcbfa514e04e9acf1dd980b38b3024 100644
--- a/Modules/Segmentation/MeanShift/test/CMakeLists.txt
+++ b/Modules/Segmentation/MeanShift/test/CMakeLists.txt
@@ -34,13 +34,13 @@ otb_module_target_label(otbMeanShiftTestDriver)
 
 otb_add_test(NAME obTuMeanShiftConnectedComponentSegmentationFilter COMMAND otbMeanShiftTestDriver
   otbMeanShiftConnectedComponentSegmentationFilter
-  ${INPUTDATA}/ROI_QB_MUL_4.tif
-  ${TEMP}/obTuMeanShiftConnectedComponentSegmentationImage.png
-  9
-  9
-  0.01
-  "distance<0.2"
-  50)
+  ${INPUTDATA}/QB_MUL_ROI_1000_100.tif
+  ${TEMP}/obTuMeanShiftConnectedComponentSegmentationImage.tif
+  6
+  50
+  0.1
+  "distance<20"
+  5)
 
 otb_add_test(NAME obTuMeanShiftSegmentationFilterPruning COMMAND otbMeanShiftTestDriver
   otbMeanShiftSegmentationFilter
diff --git a/Modules/ThirdParty/GDAL/otb-module-init.cmake b/Modules/ThirdParty/GDAL/otb-module-init.cmake
index b3b512bc6b95f560cefbb1ee0878865c2d3af9d8..140f5835963031c31b1737bc0b4d616c087eea1e 100644
--- a/Modules/ThirdParty/GDAL/otb-module-init.cmake
+++ b/Modules/ThirdParty/GDAL/otb-module-init.cmake
@@ -51,13 +51,51 @@ macro(error_message m)
   message(FATAL_ERROR "${m}")
 endmacro(error_message)
 
+#------------------- C version ---------------------
+macro(gdal_try_run_c msg_type var source_file)
+message(STATUS "Performing Test ${var}")
+set(${var})
+try_run(RUN_${var} COMPILE_${var} ${CMAKE_CURRENT_BINARY_DIR}
+${CMAKE_SOURCE_DIR}/Modules/ThirdParty/GDAL/${source_file}
+CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GDAL_INCLUDE_DIR}" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}"
+COMPILE_DEFINITIONS "-w"
+COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_${var}
+RUN_OUTPUT_VARIABLE RUN_OUTPUT_${var}
+ARGS ${ARGN}
+)
+
+if(NOT COMPILE_${var})
+  error_message("Compiling Test ${var} - Failed \n
+COMPILE_OUTPUT_${var}: '${COMPILE_OUTPUT_${var}}'")
+endif()
+if(RUN_${var})
+  set(${var} FALSE)
+  #if msg_type is STATUS (ie "okay" if test is failing),
+  #then we don't need to give an run-output and exit status.
+  if("${msg_type}" STREQUAL "STATUS")
+    message(${msg_type} "Performing Test ${var} - Failed")
+  else()
+    error_message("Performing Test ${var} - Failed \n
+            Exit status: '${RUN_${var}}' \n
+            RUN_OUTPUT_${var}: '${RUN_OUTPUT_${var}}'")
+  endif()
+else()
+  set(${var} TRUE)
+  message(STATUS "Performing Test ${var} - Success")
+endif()
+unset(RUN_OUTPUT_${var})
+unset(COMPILE_OUTPUT_${var})
+unset(COMPILE_${var})
+endmacro()
+
 #------------------- Helper Macro ---------------------
 macro(gdal_try_run msg_type var source_file)
 message(STATUS "Performing Test ${var}")
 set(${var})
 try_run(RUN_${var} COMPILE_${var} ${CMAKE_CURRENT_BINARY_DIR}
 ${CMAKE_SOURCE_DIR}/Modules/ThirdParty/GDAL/${source_file}
-CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GDAL_INCLUDE_DIR}" "-w" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}"
+CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GDAL_INCLUDE_DIR}" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}"
+COMPILE_DEFINITIONS "-std=c++14" "-w"
 COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_${var}
 RUN_OUTPUT_VARIABLE RUN_OUTPUT_${var}
 ARGS ${ARGN}
@@ -104,7 +142,8 @@ endif()
 #gdal_try_run(FATAL_ERROR GDAL_HAS_OGR gdalOGRTest.cxx)
 try_compile(COMPILE_GDAL_HAS_OGR ${CMAKE_CURRENT_BINARY_DIR}
 ${CMAKE_SOURCE_DIR}/Modules/ThirdParty/GDAL/gdalOGRTest.cxx
-CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GDAL_INCLUDE_DIR}" "-w" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}"
+CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GDAL_INCLUDE_DIR}" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}"
+COMPILE_DEFINITIONS "-std=c++14" "-w"
 OUTPUT_VARIABLE COMPILE_OUTPUT_GDAL_HAS_OGR
 )
 if(NOT COMPILE_GDAL_HAS_OGR)
@@ -116,11 +155,11 @@ endif()
 # check formats TIFF, GeoTIFF, JPEG, JPEG2000, HDF5
 # Note : exact format names can be found here http://www.gdal.org/formats_list.html
 
-gdal_try_run(STATUS GDAL_FORMATS_LIST gdalFormatsListTest.c ${TEMP}/gdalFormatsList.csv)
+gdal_try_run_c(STATUS GDAL_FORMATS_LIST gdalFormatsListTest.c ${TEMP}/gdalFormatsList.csv)
 
-gdal_try_run(FATAL_ERROR GDAL_HAS_JPEG gdalFormatsTest.c JPEG)
+gdal_try_run_c(FATAL_ERROR GDAL_HAS_JPEG gdalFormatsTest.c JPEG)
 
-gdal_try_run(FATAL_ERROR GDAL_HAS_GTiff gdalFormatsTest.c GTiff)
+gdal_try_run_c(FATAL_ERROR GDAL_HAS_GTiff gdalFormatsTest.c GTiff)
 
 gdal_try_run(FATAL_ERROR GDAL_CAN_CREATE_GTiff gdalCreateTest.cxx GTiff ${TEMP}/testImage.gtif )
 
@@ -129,39 +168,39 @@ gdal_try_run(FATAL_ERROR GDAL_CAN_CREATE_GTiff_BIGTIFF gdalCreateCopyTest.cxx ${
 gdal_try_run(FATAL_ERROR GDAL_CAN_CREATE_JPEG gdalCreateCopyTest.cxx ${TEMP}/testImage.gtif ${TEMP}/testImage.jpeg JPEG)
 
 set(JPEG2000_DRIVER_USED)
-gdal_try_run(STATUS GDAL_HAS_JP2OpenJPEG gdalFormatsTest.c JP2OpenJPEG)
+gdal_try_run_c(STATUS GDAL_HAS_JP2OpenJPEG gdalFormatsTest.c JP2OpenJPEG)
 if (GDAL_HAS_JP2OpenJPEG)
   set(JPEG2000_DRIVER_USED "OpenJPEG")
   gdal_try_run(STATUS GDAL_CAN_CREATE_JP2OpenJPEG gdalCreateCopyTest.cxx ${TEMP}/testImage.gtif ${TEMP}/testImage.j2k JP2OpenJPEG)
 endif()
 
-gdal_try_run(STATUS GDAL_HAS_JP2KAK gdalFormatsTest.c JP2KAK)
+gdal_try_run_c(STATUS GDAL_HAS_JP2KAK gdalFormatsTest.c JP2KAK)
 if (GDAL_HAS_JP2KAK)
   set(JPEG2000_DRIVER_USED "Kakadu")
   gdal_try_run(STATUS GDAL_CAN_CREATE_JP2KAK gdalCreateCopyTest.cxx ${TEMP}/testImage.gtif ${TEMP}/testImage.j2k JP2KAK)
 endif()
 
-gdal_try_run(STATUS GDAL_HAS_JP2ECW gdalFormatsTest.c JP2ECW)
+gdal_try_run_c(STATUS GDAL_HAS_JP2ECW gdalFormatsTest.c JP2ECW)
 if (GDAL_HAS_JP2ECW)
   set(JPEG2000_DRIVER_USED "ECW")
   gdal_try_run(STATUS GDAL_CAN_CREATE_JP2ECW gdalCreateCopyTest.cxx ${TEMP}/testImage.gtif ${TEMP}/testImage.j2k JP2ECW)
 endif()
 
-gdal_try_run(STATUS GDAL_HAS_JPEG2000 gdalFormatsTest.c JPEG2000)
+gdal_try_run_c(STATUS GDAL_HAS_JPEG2000 gdalFormatsTest.c JPEG2000)
 if (GDAL_HAS_JPEG2000)
     set(JPEG2000_DRIVER_USED "JPEG2000")
   gdal_try_run(STATUS GDAL_CAN_CREATE_JPEG2000 gdalCreateCopyTest.cxx ${TEMP}/testImage.gtif ${TEMP}/testImage.j2k JPEG2000)
 endif()
 
-gdal_try_run(STATUS GDAL_HAS_HDF5 gdalFormatsTest.c HDF5)
-gdal_try_run(STATUS GDAL_HAS_HDF4 gdalFormatsTest.c HDF4)
+gdal_try_run_c(STATUS GDAL_HAS_HDF5 gdalFormatsTest.c HDF5)
+gdal_try_run_c(STATUS GDAL_HAS_HDF4 gdalFormatsTest.c HDF4)
 
 #check some vector formats
 #TODO: fix gdalFormatsTest.c to work with gdal 1.x and 2.x
-# gdal_try_run(FATAL_ERROR GDAL_HAS_SQLite gdalFormatsTest.c SQLite)
-# gdal_try_run(FATAL_ERROR GDAL_HAS_VRT gdalFormatsTest.c VRT)
-# gdal_try_run(FATAL_ERROR GDAL_HAS_KML gdalFormatsTest.c KML)
-# gdal_try_run(STATUS GDAL_HAS_LIBKML gdalFormatsTest.c LIBKML)
+# gdal_try_run_c(FATAL_ERROR GDAL_HAS_SQLite gdalFormatsTest.c SQLite)
+# gdal_try_run_c(FATAL_ERROR GDAL_HAS_VRT gdalFormatsTest.c VRT)
+# gdal_try_run_c(FATAL_ERROR GDAL_HAS_KML gdalFormatsTest.c KML)
+# gdal_try_run_c(STATUS GDAL_HAS_LIBKML gdalFormatsTest.c LIBKML)
 
 #------------------- TESTS (END)---------------------
 
diff --git a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
index ecdc6155b7215ae28e35591175094d199157da4e..971bf0e4fbf1eb0b27efe16f762c43f93f34e37b 100644
--- a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
@@ -64,7 +64,7 @@ public:
    : private equality_comparable<ProductType>
    , private less_than_comparable<ProductType>
    {
-     enum Type { SLC, GRD, MGD, GEC, EEC, SCS_B, MAX__, UNDEFINED__, FIRST__=0 };
+     enum Type { SLC, GRD, MGD, GEC, EEC, SCS_B, SCS_U, MAX__, UNDEFINED__, FIRST__=0 };
 
       explicit ProductType(unsigned char value)
          : m_value(Type(value))
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimCosmoSkymedModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimCosmoSkymedModel.cpp
index b195237a95d6ad058d0041ab23297e0f7ca47f43..b11d6dc1fda61880c96f2196d9aeb68ede39b38e 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimCosmoSkymedModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimCosmoSkymedModel.cpp
@@ -268,7 +268,7 @@ namespace ossimplugins
 	  }
       }
 
-    int nbRasterCount = dataset->GetRasterCount();
+    int nbRasterCout = dataset->GetRasterCount();
 
     // Metadata for each Band
     for (int iBand = 0; iBand < dataset->GetRasterCount(); iBand++)
@@ -310,13 +310,14 @@ namespace ossimplugins
 	return false;
       }
 
-    if( (metadataDataSet["Product_Type"] != "SCS_B")) 
+    if( (metadataDataSet["Product_Type"] != "SCS_B") && metadataDataSet["Product_Type"] != "SCS_U") 
       {
 	ossimNotify(ossimNotifyLevel_WARN)
-	  << "Not an expected product type (only SCS_B expected)" << "'\n" ;
+	  << "Not an expected product type (only SCS_B and SCS_U expected)" << "'\n" ;
 	return false;
       }
 
+
     ////////////////// Add General Parameters ////////////////
     add(theProductKwl, "sensor", "CSK"); 
     add(theProductKwl, "sample_type", "COMPLEX");
@@ -352,8 +353,10 @@ namespace ossimplugins
     add(theProductKwl, SUPPORT_DATA_PREFIX, "azimuth_spacing", 
 	std::stod(metadataBands[0]["S01_SBI_Line_Spacing"]));
  
-    add(theProductKwl, SUPPORT_DATA_PREFIX, "range_sampling_rate", 
-	std::stod(metadataDataSet["S01_Sampling_Rate"]));
+
+    double samplingRate = 1./std::stod(metadataBands[0]["S01_SBI_Column_Time_Interval"]);
+
+    add(theProductKwl, SUPPORT_DATA_PREFIX, "range_sampling_rate", samplingRate);
     add(theProductKwl, SUPPORT_DATA_PREFIX, "radar_frequency",  std::stod(metadataDataSet["Radar_Frequency"]));
     add(theProductKwl, SUPPORT_DATA_PREFIX, "slant_range_to_first_pixel", 
 	std::stod(metadataBands[0]["S01_SBI_Zero_Doppler_Range_First_Time"]));
@@ -483,7 +486,6 @@ namespace ossimplugins
 
 
     //////////////// Add GCPs one for the moment ////////////////
-    
     // Get the borders
     std::string geoCoor_TL = metadataBands[0]["S01_SBI_Top_Left_Geodetic_Coordinates"];
     std::vector<std::string> vGeoCoor_TL;
@@ -500,6 +502,7 @@ namespace ossimplugins
     std::string geoCoor_BR = metadataBands[0]["S01_SBI_Bottom_Right_Geodetic_Coordinates"];
     std::vector<std::string> vGeoCoor_BR;
     otb::Utils::ConvertStringToVector(geoCoor_BR, vGeoCoor_BR, "S01_SBI_Bottom_Right_Geodetic_Coordinates", " ");
+   
     
     // Mean
     std::vector<double> vGeoCoor_Mean;
@@ -523,6 +526,7 @@ namespace ossimplugins
     
     // Inverse model for the middle point
     loadState(theProductKwl); // Load the kwl to make the inverse projection
+    
     ossimEcefPoint sensorPos;
     ossimEcefVector sensorVel;
     const bool s1 = this->worldToAzimuthRangeTime(gptPt,estimatedAzimuthTime,estimatedRangeTime,sensorPos,
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
index 16e57c9dedbda060c54972a2d3d6f6c54e637e53..0449388ff54da71a40e95a151ad50b8c262309ab 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
@@ -98,7 +98,7 @@ namespace {// Anonymous namespace
    ossimTrace traceDebug ("ossimSarSensorModel:debug");
 
    typedef char const* const* strings_iterator;
-  static char const* const PRODUCTTYPE_STRINGS[] = { "SLC", "GRD", "MGD", "GEC", "EEC", "SCS_B" };
+  static char const* const PRODUCTTYPE_STRINGS[] = { "SLC", "GRD", "MGD", "GEC", "EEC", "SCS_B", "SCS_U" };
 }// Anonymous namespace
 
 namespace ossimplugins
diff --git a/Modules/Visualization/Ice/src/otbStandardShader.cxx b/Modules/Visualization/Ice/src/otbStandardShader.cxx
index 9903df73c441942a9158f8f034ef250b6bcb621c..77e8e3a1bcc29ebe90ce9611a45cf1fa3b83de34 100644
--- a/Modules/Visualization/Ice/src/otbStandardShader.cxx
+++ b/Modules/Visualization/Ice/src/otbStandardShader.cxx
@@ -69,7 +69,7 @@ std::string StandardShader::GetSource() const
     shader_source+="#version 130 \n";
     }
 
-  shader_source = 
+  shader_source +=
     "uniform sampler2D src;\n"                                          \
     "uniform vec4 shader_a;\n"                                          \
     "uniform vec4 shader_b;\n"                                          \
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
index 738949669131df03fec89abd2318c0330a470fff..6d857dfde441ad207bd449f3c0e88ac9a7b24a59 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
@@ -121,6 +121,12 @@ public:
    */
   int Execute();
 
+  /** write all of the output to disk
+   * if they have an associated filename.
+   * This is a helper function for wrappers without pipeline support.
+   */
+  void WriteOutput();
+
   /** Run the application, then write all of the output to disk
    * if they have an associated filename.
    * This is a helper function for wrappers without pipeline support.
@@ -129,6 +135,12 @@ public:
    */
   int ExecuteAndWriteOutput();
 
+  /** Connect input image to an output image in app */
+  bool ConnectImage(std::string in, Application* app, std::string out);
+
+  /** Propagate the connection mode : */
+  void PropagateConnectMode(bool isMem);
+  
   /** Request the application to stop its processing */
   void Stop();
 
@@ -772,6 +784,8 @@ public:
   */
   void FreeRessources();
 
+  bool IsExecuteDone();
+
 protected:
   /** Constructor */
   Application();
@@ -894,6 +908,9 @@ private:
   /** Flag is true when executing DoInit, DoUpdateParameters or DoExecute */
   bool m_IsInPrivateDo;
 
+  /** Flag to check if Execute has already been called */
+  bool m_ExecuteDone;
+
   /**
     * Declare the class
     * - Wrapper::MapProjectionParametersHandler
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
index a49e4c2bfb477da878372e778b3174755361d5d3..3889acae9f192fceee9cf78a64ef9a98defb0094 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
@@ -55,10 +55,31 @@ public:
   /** RTTI support */
   itkTypeMacro(InputImageParameter, Parameter);
 
+  typedef struct
+    {
+    itk::Object::Pointer app;
+    std::string key;
+    bool isMem;
+    } Connector;
+
   /** Set value from filename */
   bool SetFromFileName( const std::string & filename );
   itkGetConstReferenceMacro( FileName, std::string );
 
+  void SetConnection(Connector c)
+    {
+    m_Connection = c;
+    }
+
+  const Connector & GetConnection() const
+    {
+    return m_Connection;
+    }
+
+  void SetConnectionMode(bool isMem)
+    {
+    m_Connection.isMem = isMem;
+    }
 
   /** Get input-image as ImageBaseType. */
   ImageBaseType const* GetImage() const;
@@ -152,6 +173,8 @@ private:
   /** flag : are we using a filename or an image pointer as an input */
   bool m_UseFilename;
 
+  Connector m_Connection;
+
 }; // End class InputImage Parameter
 
 } // End namespace Wrapper
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.h
index e0f85016e0860ec6065412e79e09395674a7b86d..098a3f4ebf843c994d6346586eb0c0f253ee0ad7 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.h
@@ -86,6 +86,8 @@ public:
   /** */
   void Insert( const std::string &, std::size_t = -1 ) override;
 
+  void InsertElement(typename T::Pointer, std::size_t = -1);
+
   /** Set one specific stored filename. */
   void SetNthFileName( std::size_t, const std::string & ) override;
 
@@ -117,6 +119,8 @@ public:
   /** */
   void Swap( std::size_t, std::size_t ) override;
 
+  typename T::Pointer GetNthElement(std::size_t);
+
   std::vector<std::string> ToStringList() const override;
   void FromStringList(const std::vector<std::string>& value) override;
   std::string ToString() const override;
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.hxx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.hxx
index 74967552f28a7fea8e4d986529302219bdfdc46a..25521e3bb4de8018f43421745cfa56b678e6b569 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.hxx
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.hxx
@@ -159,8 +159,17 @@ ParameterList< T >
 
   p->FromString(filename);
 
-  m_Parameters.insert( m_Parameters.begin() + index, p );
+  InsertElement(p, index);
+}
 
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::InsertElement(typename T::Pointer p, std::size_t index)
+{
+  m_Parameters.insert( m_Parameters.begin() + index, p );
+  
   assert( !m_Parameters.back().IsNull() );
 
   SetActive( true );
@@ -443,9 +452,9 @@ ParameterList< T >
 {
   assert( data!=nullptr );
 
-  typename T::Pointer p;
+  typename T::Pointer p( T::New() );
 
-  return From( p, data, set, description );
+  return FromData( p, data, set, description );
 }
 
 /*****************************************************************************/
@@ -460,8 +469,6 @@ ParameterList< T >
 {
   assert( data!=nullptr );
 
-  parameter = T::New();
-
   set( parameter, data );
   parameter->SetDescription( description );
 
@@ -497,6 +504,14 @@ std::string ParameterList<T>::ToString() const
   return oss.str();
 }
 
+template< typename T >
+typename T::Pointer
+ParameterList< T >
+::GetNthElement(std::size_t i)
+{
+  return m_Parameters[i];
+}
+
 } // End namespace Wrapper
 
 
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
index 0e2127a04f912a0d69c933918d9f3b67edecf6d1..9cdfa1e1d841dd1a4c2f8693b342bc3dd6c72c63 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
@@ -38,13 +38,16 @@
 #include "otbWrapperBoolParameter.h"
 
 #include "otbWrapperAddProcessToWatchEvent.h"
+#include "otbExtendedFilenameToWriterOptions.h"
 
+#include "otbCast.h"
 #include "otbMacro.h"
 #include "otbWrapperTypes.h"
 #include <exception>
 #include "itkMacro.h"
 #include <stack>
 #include <set>
+#include <unordered_set>
 
 namespace otb
 {
@@ -334,7 +337,8 @@ Application::Application()
     m_DocSeeAlso(""),
     m_DocTags(),
     m_Doclink(""),
-    m_IsInPrivateDo(false)
+    m_IsInPrivateDo(false),
+    m_ExecuteDone(false)
 {
   // Don't call Init from the constructor, since it calls a virtual method !
   m_Logger->SetName("Application.logger");
@@ -467,6 +471,8 @@ void Application::UpdateParameters()
   m_IsInPrivateDo = true;
   this->DoUpdateParameters();
   m_IsInPrivateDo = false;
+  // reset the flag m_ExecuteDone
+  m_ExecuteDone = false;
 }
 
 void Application::AfterExecuteAndWriteOutputs()
@@ -675,11 +681,119 @@ void Application::FreeRessources()
 
 int Application::Execute()
 {
+  //----------- Recursive part -------------------------------------------------
+  std::vector<std::string> paramList = GetParametersKeys(true);
+  int status=0;
+  std::unordered_set<Application*> targetApps;
+  for (std::vector<std::string>::const_iterator it = paramList.begin(); it != paramList.end(); ++it)
+    {
+    std::string key = *it;
+    Parameter* param = GetParameterByKey(key);
+    InputImageParameter* imgParam = dynamic_cast<InputImageParameter*>(param);
+    
+    if(imgParam)
+      {
+      Application::Pointer targetApp = otb::DynamicCast<Application>(imgParam->GetConnection().app);
+      if(targetApp.IsNotNull() && !targetApp->IsExecuteDone())
+        {
+        targetApps.insert(targetApp);
+        }
+      }
+    else
+      {
+      InputImageListParameter* imgListParam = dynamic_cast<InputImageListParameter*>(param);
+      if (imgListParam)
+        {
+        for (unsigned int i=0 ; i<imgListParam->Size(); i++)
+          {
+          Application::Pointer targetApp = otb::DynamicCast<Application>(imgListParam->GetNthElement(i)->GetConnection().app);
+          if(targetApp.IsNotNull() && !targetApp->IsExecuteDone())
+            {
+            targetApps.insert(targetApp);
+            }
+          }
+        }
+      } 
+    }
+  for (auto &app : targetApps)
+    {
+    // Call target Execute()
+    status = status | app->Execute();
+    }
+  for (std::vector<std::string>::const_iterator it = paramList.begin(); it != paramList.end(); ++it)
+    {
+    std::string key = *it;
+    Parameter* param = GetParameterByKey(key);
+    InputImageParameter* imgParam = dynamic_cast<InputImageParameter*>(param);
+    if(imgParam)
+      {
+      Application::Pointer targetApp = otb::DynamicCast<Application>(imgParam->GetConnection().app);
+      if(targetApp.IsNotNull())
+        {
+        std::string outKey = imgParam->GetConnection().key;
+        if(imgParam->GetConnection().isMem || !targetApp->HasValue(outKey))
+          {
+          // memory connection
+          SetParameterInputImage(key,
+            targetApp->GetParameterOutputImage(outKey));
+          targetApp->DisableParameter(outKey);
+          }
+        else
+          {
+          // set input string based on out image (and strip any extended filename)
+          otb::ExtendedFilenameToWriterOptions::Pointer fnHelper = otb::ExtendedFilenameToWriterOptions::New();
+          fnHelper->SetExtendedFileName(targetApp->GetParameterString(outKey));
+          SetParameterString(key, fnHelper->GetSimpleFileName() );
+          targetApp->EnableParameter(outKey);
+          }
+        }
+      }
+    else
+      {
+      InputImageListParameter* imgListParam = dynamic_cast<InputImageListParameter*>(param);
+      if (imgListParam)
+        {
+        for (unsigned int i=0 ; i<imgListParam->Size() ; i++)
+          {
+          Application::Pointer targetApp = otb::DynamicCast<Application>(imgListParam->GetNthElement(i)->GetConnection().app);
+          if(targetApp.IsNotNull())
+            {
+            std::string outKey = imgListParam->GetNthElement(i)->GetConnection().key;
+            if(imgListParam->GetNthElement(i)->GetConnection().isMem ||
+               !targetApp->HasValue(outKey))
+              {
+              // memory connection
+              SetNthParameterInputImageList(key,i,
+                targetApp->GetParameterOutputImage(outKey));
+              targetApp->DisableParameter(outKey);
+              }
+            else
+              {
+              // set input string based on out image (and strip any extended filename)
+              otb::ExtendedFilenameToWriterOptions::Pointer fnHelper = otb::ExtendedFilenameToWriterOptions::New();
+              fnHelper->SetExtendedFileName(targetApp->GetParameterString(outKey));
+              SetNthParameterStringList(key, i, fnHelper->GetSimpleFileName());
+              targetApp->EnableParameter(outKey);
+              }
+            }
+          }
+        }
+      }
+    }
+  if (status != 0)
+    {
+    return status;
+    }
+  for (auto &app : targetApps)
+    {
+    app->WriteOutput();
+    }
 
+  //------------------------------------------------------------
   this->UpdateParameters();
 
   // before execute we set the seed of mersenne twister
-  std::vector<std::string> paramList = GetParametersKeys(true);
+  
   bool UseSpecificSeed = false;
 
   for (std::vector<std::string>::const_iterator it = paramList.begin(); it != paramList.end(); ++it)
@@ -705,6 +819,7 @@ int Application::Execute()
   m_IsInPrivateDo = true;
   this->DoExecute();
   m_IsInPrivateDo = false;
+  m_ExecuteDone = true;
 
   // Ensure that all output image parameter have called UpdateOutputInformation()
   for (auto it = paramList.begin(); it != paramList.end(); ++it)
@@ -725,84 +840,91 @@ int Application::Execute()
   return 0;
 }
 
-int Application::ExecuteAndWriteOutput()
+void Application::WriteOutput()
 {
-  m_Chrono.Restart();
-
-  m_Logger->LogSetupInformation();
-
-  int status = this->Execute();
-
-  if (status == 0)
+  std::vector<std::string> paramList = GetParametersKeys(true);
+  // First Get the value of the available memory to use with the
+  // writer if a RAMParameter is set
+  bool useRAM = false;
+  unsigned int ram = 0;
+  for (std::vector<std::string>::const_iterator it = paramList.begin();
+       it != paramList.end();
+       ++it)
     {
-      std::vector<std::string> paramList = GetParametersKeys(true);
-      // First Get the value of the available memory to use with the
-      // writer if a RAMParameter is set
-      bool useRAM = false;
-      unsigned int ram = 0;
-      for (std::vector<std::string>::const_iterator it = paramList.begin();
-           it != paramList.end();
-           ++it)
-        {
-        std::string key = *it;
+    std::string key = *it;
 
-        if (GetParameterType(key) == ParameterType_RAM
-            && IsParameterEnabled(key))
-          {
-          Parameter* param = GetParameterByKey(key);
-          RAMParameter* ramParam = dynamic_cast<RAMParameter*>(param);
-          if(ramParam!=nullptr)
-            {
-            ram = ramParam->GetValue();
-            useRAM = true;
-            }
-          }
+    if (GetParameterType(key) == ParameterType_RAM
+        && IsParameterEnabled(key))
+      {
+      Parameter* param = GetParameterByKey(key);
+      RAMParameter* ramParam = dynamic_cast<RAMParameter*>(param);
+      if(ramParam!=nullptr)
+        {
+        ram = ramParam->GetValue();
+        useRAM = true;
         }
+      }
+    }
 
-      for (std::vector<std::string>::const_iterator it = paramList.begin();
-           it != paramList.end();
-           ++it)
+  for (std::vector<std::string>::const_iterator it = paramList.begin();
+       it != paramList.end();
+       ++it)
+    {
+    std::string key = *it;
+    if (GetParameterType(key) == ParameterType_OutputImage
+        && IsParameterEnabled(key) && HasValue(key) )
+      {
+      Parameter* param = GetParameterByKey(key);
+      OutputImageParameter* outputParam = dynamic_cast<OutputImageParameter*>(param);
+
+      if(outputParam!=nullptr)
         {
-        std::string key = *it;
-        if (GetParameterType(key) == ParameterType_OutputImage
-            && IsParameterEnabled(key) && HasValue(key) )
+        std::string checkReturn = outputParam->CheckFileName(true);
+        if (!checkReturn.empty())
           {
-          Parameter* param = GetParameterByKey(key);
-          OutputImageParameter* outputParam = dynamic_cast<OutputImageParameter*>(param);
-
-          if(outputParam!=nullptr)
-            {
-            std::string checkReturn = outputParam->CheckFileName(true);
-            if (!checkReturn.empty())
-              {
-              otbAppLogWARNING("Check filename: "<<checkReturn);
-              }
-            if (useRAM)
-              {
-              outputParam->SetRAMValue(ram);
-              }
-            outputParam->InitializeWriters();
-            std::ostringstream progressId;
-            progressId << "Writing " << outputParam->GetFileName() << "...";
-            AddProcess(outputParam->GetWriter(), progressId.str());
-            outputParam->Write();
-            }
+          otbAppLogWARNING("Check filename: "<<checkReturn);
           }
-        else if (GetParameterType(key) == ParameterType_OutputVectorData
-                 && IsParameterEnabled(key) && HasValue(key) )
+        if (useRAM)
           {
-          Parameter* param = GetParameterByKey(key);
-          OutputVectorDataParameter* outputParam = dynamic_cast<OutputVectorDataParameter*>(param);
-          if(outputParam!=nullptr)
-            {
-            outputParam->InitializeWriters();
-            std::ostringstream progressId;
-            progressId << "Writing " << outputParam->GetFileName() << "...";
-            AddProcess(outputParam->GetWriter(), progressId.str());
-            outputParam->Write();
-            }
+          outputParam->SetRAMValue(ram);
           }
+        outputParam->InitializeWriters();
+        std::ostringstream progressId;
+        progressId << "Writing " << outputParam->GetFileName() << "...";
+        AddProcess(outputParam->GetWriter(), progressId.str());
+        outputParam->Write();
+        }
+      }
+    else if (GetParameterType(key) == ParameterType_OutputVectorData
+             && IsParameterEnabled(key) && HasValue(key) )
+      {
+      Parameter* param = GetParameterByKey(key);
+      OutputVectorDataParameter* outputParam = dynamic_cast<OutputVectorDataParameter*>(param);
+      if(outputParam!=nullptr)
+        {
+        outputParam->InitializeWriters();
+        std::ostringstream progressId;
+        progressId << "Writing " << outputParam->GetFileName() << "...";
+        AddProcess(outputParam->GetWriter(), progressId.str());
+        outputParam->Write();
         }
+      }
+    }
+}
+
+int Application::ExecuteAndWriteOutput()
+{
+  m_Chrono.Restart();
+  // reset the flag m_ExecuteDone
+  m_ExecuteDone = false;
+
+  m_Logger->LogSetupInformation();
+
+  int status = this->Execute();
+
+  if (status == 0)
+    {
+    this->WriteOutput();
     }
 
   this->AfterExecuteAndWriteOutputs();
@@ -1630,5 +1752,91 @@ otbGetParameterImageMacro(ComplexFloatVectorImage);
 otbGetParameterImageMacro(ComplexDoubleVectorImage);
 
 
+bool
+Application::ConnectImage(std::string in, Application* app, std::string out)
+{
+  if(app == nullptr)
+    {
+    // throw error ?
+    return false;
+    }
+
+  Parameter* param = GetParameterByKey(in);
+  InputImageParameter* inParam = dynamic_cast<InputImageParameter*>(param);
+  if(inParam == nullptr)
+    {
+    InputImageListParameter* inListParam = dynamic_cast<InputImageListParameter*>(param);
+    if (inListParam == nullptr)
+      {
+      return false;
+      }
+    inListParam->InsertElement(InputImageParameter::New(),inListParam->Size());
+    inParam = (inListParam->GetNthElement(inListParam->Size() - 1)).GetPointer();
+    }
+  param = app->GetParameterByKey(out);
+  OutputImageParameter* outParam = dynamic_cast<OutputImageParameter*>(param);
+  if(outParam == nullptr)
+    {
+    return false;
+    }
+  InputImageParameter::Connector c;
+  c.app = app;
+  c.key = out;
+  c.isMem = true;
+  inParam->SetConnection(c);
+  return true;
+}
+
+void
+Application::PropagateConnectMode(bool isMem)
+{
+  // reset ExecuteDone flag
+  m_ExecuteDone = false;
+  std::vector<std::string> paramList = GetParametersKeys(true);
+  std::unordered_set<Application*> targetApps;
+  for (std::vector<std::string>::const_iterator it = paramList.begin(); it != paramList.end(); ++it)
+    {
+    std::string key = *it;
+    Parameter* param = GetParameterByKey(key);
+    InputImageParameter* imgParam = dynamic_cast<InputImageParameter*>(param);
+    
+    if(imgParam)
+      {
+      Application::Pointer targetApp = otb::DynamicCast<Application>(imgParam->GetConnection().app);
+      if(targetApp.IsNotNull())
+        {
+        imgParam->SetConnectionMode(isMem);
+        targetApps.insert(targetApp);
+        }
+      }
+    else
+      {
+      InputImageListParameter* imgListParam = dynamic_cast<InputImageListParameter*>(param);
+      if (imgListParam)
+        {
+        for (unsigned int i=0 ; i<imgListParam->Size(); i++)
+          {
+          Application::Pointer targetApp = otb::DynamicCast<Application>(imgListParam->GetNthElement(i)->GetConnection().app);
+          if(targetApp.IsNotNull())
+            {
+            imgListParam->GetNthElement(i)->SetConnectionMode(isMem);
+            targetApps.insert(targetApp);
+            }
+          }
+        }
+      }
+    }
+  for (auto &app : targetApps)
+    {
+    app->PropagateConnectMode(isMem);
+    }
+}
+
+bool
+Application::IsExecuteDone()
+{
+  return m_ExecuteDone;
+}
+
 }
 }
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx
index fe6afc7d7cf690b8c25f14f97cf8ca328b0d0c3f..e722332692f68d73f2e137c035b1049658db7bd9 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx
@@ -47,7 +47,7 @@ InputImageListParameter
 {
   assert( image!=nullptr );
 
-  InputImageParameter::Pointer p;
+  InputImageParameter::Pointer p( InputImageParameter::New() );
 
   return FromImage( p, image );
 }
diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i
index fbfcdb06a6edf8a272cb0d4b15d5eff2eb1461f2..3cf79c5d8991ba6e59eeb21ea75b39f6775b60f5 100644
--- a/Modules/Wrappers/SWIG/src/otbApplication.i
+++ b/Modules/Wrappers/SWIG/src/otbApplication.i
@@ -203,6 +203,35 @@ public:
 #endif
 
 
+#if SWIGPYTHON
+
+// We want all SetParameterXXX functions to call UpdateParameters automaticaly
+// so that using it is not required from the Python API
+// for more discussion about this see gitlab issue #1842
+
+%pythonappend Application::SetParameterInt %{
+    self.UpdateParameters()
+%}
+
+%pythonappend Application::SetParameterFloat %{
+    self.UpdateParameters()
+%}
+
+%pythonappend Application::SetParameterString %{
+    self.UpdateParameters()
+%}
+
+%pythonappend Application::SetParameterStringList %{
+    self.UpdateParameters()
+%}
+
+%pythonappend Application::SetParameterOutputImagePixelType %{
+    self.UpdateParameters()
+%}
+
+#endif
+
+
 class Application: public itkObject
 {
 public:
@@ -215,7 +244,10 @@ public:
   void Init();
   void UpdateParameters();
   int Execute();
+  void WriteOutput();
   int ExecuteAndWriteOutput();
+  bool ConnectImage(std::string in, Application* app, std::string out);
+  void PropagateConnectMode(bool isMem);
 
   void LoadParametersFromXML(const std::string& filename);
   void SaveParametersToXML(const std::string& filename);
@@ -511,7 +543,6 @@ private:
   void operator =(const Application&);
 };
 
-
 DECLARE_REF_COUNT_CLASS( Application )
 
 
diff --git a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
index 154599d1794efe726f31c391ca26e31499735bbd..7b0bd59465dd896e922622afa59427da408eca88 100644
--- a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
@@ -131,7 +131,7 @@ add_test( NAME pyTvNewStyleParameters
   COMMAND ${TEST_DRIVER} Execute
   ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonTestDriver.py
   PythonNewStyleParametersTest
-  ${OTB_DATA_ROOT}/Input/poupees.tif
+  ${OTB_DATA_ROOT}/Input/sensor_stereo_left.tif
   ${TEMP}/pyTvNewStyleParametersTest.tif
   ${OTB_DATA_ROOT}/Input/apTvUtSmoothingTest_OutXML.xml)
 
@@ -160,3 +160,12 @@ add_test( NAME pyTvParametersDict
   ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonTestDriver.py
   PythonParametersDict
   ${OTB_DATA_ROOT}/Input/poupees.tif)
+
+add_test( NAME pyTvNoUpdateParameter
+  COMMAND ${TEST_DRIVER} Execute
+  ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonTestDriver.py
+  PythonNoUpdateParameter
+  ${OTB_DATA_ROOT}/Input/poupees.tif
+  ${OTB_DATA_ROOT}/Input/training/training.shp
+  )
+
diff --git a/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py b/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py
index e44ab774fa79bfa9e30cf65aa877437d33f5eb7a..a9b3133534988ee87df4cf9246692956d2643ce6 100644
--- a/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py
+++ b/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py
@@ -22,27 +22,39 @@
 # -*- coding: utf-8 -*-
 
 #
-#  Example on the use of the Rescale
+#  Example on the use of application connections
 #
 
 def test(otb, argv):
-	app1 = otb.Registry.CreateApplication("Smoothing")
-	app2 = otb.Registry.CreateApplication("Smoothing")
-	app3 = otb.Registry.CreateApplication("Smoothing")
-	app4 = otb.Registry.CreateApplication("ConcatenateImages")
+  #---------------------------------------------------------------------------
+  # First run with in-memory connections by default
+  app1 = otb.Registry.CreateApplication("Smoothing")
+  app2 = otb.Registry.CreateApplication("Smoothing")
+  app3 = otb.Registry.CreateApplication("Smoothing")
+  app4 = otb.Registry.CreateApplication("ConcatenateImages")
 
-	app1.IN = argv[1]
-	app1.Execute()
+  app1.IN = argv[1]
+  app1.TYPE = "mean"
 
-	app2.SetParameterInputImage("in",app1.GetParameterOutputImage("out"))
-	app2.Execute()
+  app2.ConnectImage("in",app1, "out")
+  app2.TYPE = "anidif"
 
-	app3.IN = argv[1]
-	app3.Execute()
+  app3.ConnectImage("in",app1, "out")
+  app3.TYPE = "gaussian"
 
-	app4.AddImageToParameterInputImageList("il",app2.GetParameterOutputImage("out"));
-	app4.AddImageToParameterInputImageList("il",app3.GetParameterOutputImage("out"));
-	app4.AddParameterStringList("il",argv[1])
+  app4.ConnectImage("il", app2, "out")
+  app4.ConnectImage("il", app3, "out")
+  app4.AddParameterStringList("il",argv[1])
 
-	app4.OUT = argv[2]
-	app4.ExecuteAndWriteOutput()
+  app4.OUT = argv[2]
+  app4.ExecuteAndWriteOutput()
+
+  #---------------------------------------------------------------------------
+  # Second run with on-disk connections
+  app1.OUT = argv[2]+"_tmp1.tif"
+  app3.OUT = argv[2]+"_tmp3.tif"
+
+  # app2.OUT is left empty and should fallback to memory connection
+
+  app4.PropagateConnectMode(False)
+  app4.ExecuteAndWriteOutput()
diff --git a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
index ea6203a0545a537a4f60bc7a556fd69d947b21d6..0320b78f19e40add9ba8cfda4b916c3e89f10a68 100644
--- a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
+++ b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
@@ -67,8 +67,8 @@ def test(otb, argv):
 	cm_assert(app.MAP, 'epsg')
 
 	# 6 - int type 2nd level sub parameters of choice parameter set
-	app.MAP.EPSG.CODE = 32768
-	cm_assert(32768, app.GetParameterInt('map.epsg.code'))
+	app.MAP.EPSG.CODE = 2154
+	cm_assert(2154, app.GetParameterInt('map.epsg.code'))
 
 	# 7 - another choice with sub parameters set
 	app.MAP = 'utm'
diff --git a/Modules/Feature/Edge/src/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/PythonNoUpdateParameter.py
similarity index 58%
rename from Modules/Feature/Edge/src/CMakeLists.txt
rename to Modules/Wrappers/SWIG/test/python/PythonNoUpdateParameter.py
index 2e1b1339f93734f7bb135cef80032d002598ac8a..8453eb1bb67cf726c9cf73118ec2cff996bfd88a 100644
--- a/Modules/Feature/Edge/src/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/python/PythonNoUpdateParameter.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 # Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 #
@@ -18,24 +19,14 @@
 # limitations under the License.
 #
 
-set(OTBEdge_SRC
-  otbFillGapsFilter.cxx
-  )
+def test(otb, argv):
+    """
+    The purpose of this test is to check that we don't need UpdateParameter()
+    from the PythonAPI, especially in the case of ListView parameters
+    See gitlab issue #1842
+    """
+    app = otb.Registry.CreateApplication("TrainImagesClassifier")
+    app.SetParameterStringList("io.il", [argv[1]])
+    app.SetParameterStringList("io.vd",[argv[2]])
+    app.SetParameterStringList("sample.vfn",["CODE"])
 
-add_library(OTBEdge ${OTBEdge_SRC})
-target_link_libraries(OTBEdge
-  ${OTBCommon_LIBRARIES}
-  ${OTBConversion_LIBRARIES}
-  ${OTBITK_LIBRARIES}
-  ${OTBITKPendingPatches_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-  ${OTBPath_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBSpatialObjects_LIBRARIES}
-  ${OTBStreaming_LIBRARIES}
-  ${OTBVectorDataBase_LIBRARIES}
-)
-
-otb_module_target(OTBEdge)
diff --git a/Packaging/Files/selftester.bat b/Packaging/Files/selftester.bat
index dc44d62ba8757ac0a842eb29e7252aa48804ceda..85fe9d6d19e9804227e4c5295491d56afc2dc9e8 100755
--- a/Packaging/Files/selftester.bat
+++ b/Packaging/Files/selftester.bat
@@ -180,7 +180,7 @@ goto :eof
 :check_python_wrapping
 setlocal
 type NUL > tmp.log
-python3 -c "import otbApplication" > tmp.log 2>&1
+python -c "import otbApplication" > tmp.log 2>&1
 call :nb_tmp_lines
 if %nb_tmp_lines_out% gtr 0 (
   echo ERROR : failed to run python wrapping
@@ -193,7 +193,7 @@ goto :eof
 :parse_cli_output
 setlocal
 set /a ret=1
-findstr /n /r /c:"^This is the *.*(%app%) application, version " tmp.log  > results.txt
+findstr /n /r /c:"^This is the %app% application, version " tmp.log  > results.txt
 if %errorlevel%==1 (
   set /a ret=0
   echo "findstr failed 1st regex in parse_cli_output"
diff --git a/Packaging/Files/selftester.sh b/Packaging/Files/selftester.sh
index 5dfe3e38ce17e9a60c0ab1e2495d5d9814b2de24..0ecbdde3526c46d20c4b5a251b40bf5455d0aa5e 100755
--- a/Packaging/Files/selftester.sh
+++ b/Packaging/Files/selftester.sh
@@ -81,9 +81,9 @@ for name in $OTB_SO_LIBRARIES $OTB_DY_LIBRARIES $OTB_EXE; do
       echo_and_report "$LDD_ERRORS"
     fi
   elif echo "$F_OUTPUT" | grep -q -i -e ': Mach-O .*shared library' -e ': Mach-O .*bundle' -e ': Mach-O .*executable'; then
-    DL_ERRORS=$(dltest "$name" | grep -i 'ERROR')
+    DL_ERRORS=$(./tools/otb_loader "$name")
     if [ -n "$DL_ERRORS" ]; then
-      echo_and_report "dltest $name"
+      echo_and_report "otb_loader $name"
       echo_and_report "$DL_ERRORS"
     fi
   elif echo "$F_OUTPUT" | grep -q ': symbolic link'; then
@@ -114,7 +114,7 @@ for app in $OTB_APPS; do
       
   else
     CLI_OUTPUT=$("bin/otbcli_$app" -help 2>&1)
-    CLI_FILTER=$(echo "${CLI_OUTPUT}"| tr '\n' ' ' | grep -E "This is the*.*$app*.*application, version .* Parameters: .* Examples:.*")
+    CLI_FILTER=$(echo "${CLI_OUTPUT}"| tr '\n' ' ' | grep -E "This is the $app application, version .* Parameters: .* Examples:.*")
     CLI_FILTER2=$(echo "$CLI_FILTER" | grep -v 'FATAL')
     if [ -z "$CLI_FILTER2" ]; then
       echo_and_report "ERROR: bin/otbcli_$app\n$CLI_OUTPUT"
diff --git a/Packaging/detect_using_file_command.cmake b/Packaging/detect_using_file_command.cmake
index c22b1f02452bb2184ed859df87dc99797e9c8cce..9fae4baaa10b30e652be6bd73bf7e22df9a19341 100644
--- a/Packaging/detect_using_file_command.cmake
+++ b/Packaging/detect_using_file_command.cmake
@@ -115,10 +115,10 @@ function(detect_using_file_command input_file result_type result_dir)
   # Patch file command returning shared-oject for executable on Linux when -PIE is used.
   if( LINUX )
     get_filename_component( input_file_DIR ${input_file} DIRECTORY )
-    get_filename_component( input_file_dIR ${input_file_DIR} NAME )
-    string( TOLOWER "${input_file_DIR}" input_file_DIR )
-    if( ${input_file_DIR} MATCHES "bin" )
-      message( WARNING "${input_file} detected as shared-object." )
+    get_filename_component( dir_name ${input_file_DIR} NAME )
+    string( TOLOWER "${dir_name}" dir_name_l )
+    if( "${dir_name_l}" STREQUAL "bin" )
+      message( STATUS "${input_file} detected as shared-object, but processed as executable" )
       set(detected_type PROGRAMS)
       set(detected_dir bin)
     endif()
diff --git a/SuperBuild/CMake/External_gdal.cmake b/SuperBuild/CMake/External_gdal.cmake
index 1652dc69a5c6004b28d7233692735586a6296508..418c9e6de361772b61d38b3172c31c49e1f9fcac 100644
--- a/SuperBuild/CMake/External_gdal.cmake
+++ b/SuperBuild/CMake/External_gdal.cmake
@@ -29,7 +29,9 @@ ADD_SUPERBUILD_CONFIGURE_VAR(GDAL TIFF_ROOT     --with-libtiff)
 ADD_SUPERBUILD_CONFIGURE_VAR(GDAL GEOTIFF_ROOT  --with-geotiff)
 ADD_SUPERBUILD_CONFIGURE_VAR(GDAL PNG_ROOT      --with-png)
 ADD_SUPERBUILD_CONFIGURE_VAR(GDAL JPEG_ROOT     --with-jpeg)
-ADD_SUPERBUILD_CONFIGURE_VAR(GDAL OPENJPEG_ROOT --with-openjpeg)
+# This is not needed as from GDAL 2.4 it uses pkg-config to find openjpeg.
+# It is found thanks to the $PKG_CONFIG_PATH in SB_ENV_CONFIGURE_CMD
+# ADD_SUPERBUILD_CONFIGURE_VAR(GDAL OPENJPEG_ROOT --with-openjpeg)
 ADD_SUPERBUILD_CONFIGURE_VAR(GDAL SQLITE_ROOT   --with-sqlite3)
 ADD_SUPERBUILD_CONFIGURE_VAR(GDAL ZLIB_ROOT     --with-libz)
 ADD_SUPERBUILD_CONFIGURE_VAR(GDAL EXPAT_ROOT    --with-expat)
@@ -88,11 +90,11 @@ if(UNIX)
     --with-odbc=no
     --with-ogdi=no
     --with-pam
+    --with-openjpeg
     --with-pcidsk=yes
     --with-pcraster=no
     --with-pcre=no
     --with-perl=no
-    --with-php=no
     --with-python=no
     --with-qhull=internal
     --with-sde=no
@@ -145,8 +147,8 @@ endif()
 
 ExternalProject_Add(GDAL
   PREFIX GDAL
-  URL "http://download.osgeo.org/gdal/2.2.1/gdal-2.2.1.tar.gz"
-  URL_MD5 785acf2b0cbf9d56d37c9044d0ee2505
+  URL "http://download.osgeo.org/gdal/2.4.1/gdal-2.4.1.tar.gz"
+  URL_MD5 8bc93c7ae4d3a46916918a52c7f5f10f
   SOURCE_DIR ${GDAL_SB_SRC}
   BINARY_DIR ${GDAL_SB_SRC}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
diff --git a/SuperBuild/CMake/External_opencv.cmake b/SuperBuild/CMake/External_opencv.cmake
index de575f07d4fd5c53a2af3efee3c4a2a4c275f09c..a0b0cdbd25d0bab4e43f4e835ec88762c0b12bc2 100644
--- a/SuperBuild/CMake/External_opencv.cmake
+++ b/SuperBuild/CMake/External_opencv.cmake
@@ -50,7 +50,7 @@ ExternalProject_Add(OPENCV
   -DWITH_FFMPEG:BOOL=OFF
   -DWITH_VFW:BOOL=OFF
   -DBUILD_OPENEXR:BOOL=OFF
-  -DBUILD_PACKAGE:BOOL=ON
+  -DBUILD_PACKAGE:BOOL=OFF
   -DBUILD_PERF_TESTS:BOOL=OFF
   -DBUILD_PNG:BOOL=OFF
   -DBUILD_TBB:BOOL=OFF
@@ -97,6 +97,23 @@ ExternalProject_Add(OPENCV
   -DBUILD_opencv_video:BOOL=OFF
   -DBUILD_opencv_videostab:BOOL=OFF
   -DBUILD_opencv_world:BOOL=OFF
+  -DWITH_CUBLAS:BOOL=OFF
+  -DWITH_DIRECTX:BOOL=OFF
+  -DWITH_DSHOW:BOOL=OFF
+  -DWITH_EIGEN:BOOL=OFF
+  -DWITH_IPP:BOOL=OFF
+  -DWITH_ITT:BOOL=OFF
+  -DWITH_LAPACK:BOOL=OFF
+  -DWITH_MATLAB:BOOL=OFF
+  -DWITH_NVCUVID:BOOL=OFF
+  -DWITH_WEBP:BOOL=OFF
+  -DWITH_WIN32UI:BOOL=OFF
+  -DBUILD_PROTOBUF:BOOL=OFF
+  -DBUILD_WEBP:BOOL=OFF
+  -DBUILD_opencv_java_bindings_generator:BOOL=OFF
+  -DBUILD_opencv_python_bindings_generator:BOOL=OFF
+  -DBUILD_opencv_python3:BOOL=OFF
+  -DBUILD_opencv_python2:BOOL=OFF
   -DCMAKE_INSTALL_LIBDIR:PATH=lib
   ${OPENCV_SB_CONFIG}
   DEPENDS ${OPENCV_DEPENDENCIES}
@@ -107,7 +124,6 @@ ExternalProject_Add(OPENCV
   LOG_INSTALL 1
   )
 
-
 SUPERBUILD_PATCH_SOURCE(OPENCV)
 
 set(_SB_OpenCV_DIR ${SB_INSTALL_PREFIX}/share/OpenCV)
diff --git a/SuperBuild/CMake/External_qt5.cmake b/SuperBuild/CMake/External_qt5.cmake
index 1c46eb8b14c516ff5b6576f130b628c35b719286..87db40d8be0ca6b479e6625cd1b9cfa0bbc264c4 100644
--- a/SuperBuild/CMake/External_qt5.cmake
+++ b/SuperBuild/CMake/External_qt5.cmake
@@ -130,7 +130,7 @@ configure_file( ${QT5_CONFIGURE_COMMAND_IN} ${QT5_CONFIGURE_COMMAND} @ONLY )
 
 ExternalProject_Add(QT5
   PREFIX QT5
-  URL "http://download.qt.io/official_releases/qt/5.10/5.10.1/single/qt-everywhere-src-5.10.1.tar.xz"
+  URL "https://download.qt.io/archive/qt/5.10/5.10.1/single/qt-everywhere-src-5.10.1.tar.xz"
   URL_MD5 7e167b9617e7bd64012daaacb85477af
   BINARY_DIR ${QT5_SB_BUILD_DIR}
   INSTALL_DIR ${SB_INSTALL_PREFIX}
diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt
index 4eaa0f1c4a6a6666564b20a23d582338053dfd00..54b09d87b881dde45a673b8b670fdb506d9f4a94 100644
--- a/SuperBuild/CMakeLists.txt
+++ b/SuperBuild/CMakeLists.txt
@@ -258,6 +258,9 @@ if(CMAKE_MODULE_LINKER_FLAGS)
   list(APPEND SB_ENV_CONFIGURE_CMD "LDFLAGS=${CMAKE_MODULE_LINKER_FLAGS}")
 endif()
 
+# This is needed for gdal 2.4 in order to find OpenJPEG
+list(APPEND SB_ENV_CONFIGURE_CMD "PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/lib/pkgconfig")
+
 list(REMOVE_DUPLICATES SB_ENV_CONFIGURE_CMD)
 
 message(STATUS "Environment setup for CMake (SB_CMAKE_COMMAND) : ${SB_CMAKE_COMMAND}")
@@ -343,10 +346,10 @@ option(OTB_USE_MPI "Enable MPI in OTB" OFF)
 option(OTB_USE_SPTW "Enable Simple Parallel Tiff Writer in OTB" OFF)
 
 # set OTB_DATA_ROOT to run test
-find_path(OTB_DATA_ROOT README-OTB-Data
-  PATHS
-  $ENV{OTB_DATA_ROOT}
-  ${OTB-SuperBuild_SOURCE_DIR}/../../OTB-Data)
+find_path(OTB_DATA_ROOT
+  NAMES README-OTB-Data
+  HINTS ${OTB-SuperBuild_SOURCE_DIR}/../Data
+  )
 
 # SWIG Wrapping
 option(OTB_WRAP_PYTHON "Enable python wrappers for OTB applications (requires SWIG)" ON)
diff --git a/SuperBuild/patches/GDAL/gdal-1-nmake-win.diff b/SuperBuild/patches/GDAL/gdal-1-nmake-win.diff
index c2cadc7efb5e47940ac5d62d9fe770d3a7e52e04..dfccda71c0cc500663038ae2c40447bbf93e1448 100644
--- a/SuperBuild/patches/GDAL/gdal-1-nmake-win.diff
+++ b/SuperBuild/patches/GDAL/gdal-1-nmake-win.diff
@@ -1,12 +1,16 @@
-diff -burN gdal-2.1.0.orig/nmake.opt gdal-2.1.0/nmake.opt
---- gdal-2.1.0.orig/nmake.opt	2016-06-14 11:39:22.911630802 +0200
-+++ gdal-2.1.0/nmake.opt	2016-06-14 11:39:39.827630670 +0200
-@@ -247,7 +247,7 @@
- JPEG_SUPPORTED = 1
+diff -burN gdal-2.4.1_orig/nmake.opt gdal-2.4.1/nmake.opt
+--- gdal-2.4.1_orig/nmake.opt	2019-03-15 13:30:03.000000000 +0100
++++ gdal-2.4.1/nmake.opt	2019-04-02 10:57:50.712191315 +0200
+@@ -276,9 +276,9 @@
+ !ENDIF
  
  # This will enable 12bit libjpeg - use only with internal jpeg builds.
+-!IFNDEF JPEG12_SUPPORTED
 -JPEG12_SUPPORTED = 1
+-!ENDIF
++#!IFNDEF JPEG12_SUPPORTED
 +#JPEG12_SUPPORTED = 1
++#!ENDIF
  
  #if using an external jpeg library uncomment the following lines
  #JPEG_EXTERNAL_LIB = 1
diff --git a/SuperBuild/patches/GDAL/gdal-2-enviRotation-all.diff b/SuperBuild/patches/GDAL/gdal-2-enviRotation-all.diff
index 8c7f7acdce6b34c908a9a10580f2697157534658..69e120390aca0fa023452ee933ee1ce83de7c70f 100644
--- a/SuperBuild/patches/GDAL/gdal-2-enviRotation-all.diff
+++ b/SuperBuild/patches/GDAL/gdal-2-enviRotation-all.diff
@@ -1,7 +1,7 @@
-diff -burN gdal-2.2.1-orig/frmts/raw/envidataset.cpp gdal-2.2.1/frmts/raw/envidataset.cpp
---- gdal-2.2.1-orig/frmts/raw/envidataset.cpp	2017-06-23 14:18:43.000000000 +0200
-+++ gdal-2.2.1/frmts/raw/envidataset.cpp	2017-07-20 18:25:05.373655046 +0200
-@@ -620,10 +620,13 @@
+diff -burN gdal-2.4.1_orig/frmts/raw/envidataset.cpp gdal-2.4.1/frmts/raw/envidataset.cpp
+--- gdal-2.4.1_orig/frmts/raw/envidataset.cpp	2019-03-29 14:48:15.444066736 +0100
++++ gdal-2.4.1/frmts/raw/envidataset.cpp	2019-03-29 14:48:49.556067582 +0100
+@@ -618,10 +618,13 @@
          adfGeoTransform[4] != 0.0 || adfGeoTransform[5] != 1.0;
      if( bHasNonDefaultGT )
      {
@@ -17,16 +17,16 @@ diff -burN gdal-2.2.1-orig/frmts/raw/envidataset.cpp gdal-2.2.1/frmts/raw/envida
          const double dfRotation = (dfRotation1 + dfRotation2) / 2.0;
  
          if( fabs(dfRotation1 - dfRotation2) > 1e-5 )
-@@ -1534,7 +1537,12 @@
+@@ -1530,7 +1533,12 @@
  
      // Fallback to localcs if we don't recognise things.
-     if( oSRS.GetRoot() == NULL )
-+        {
+     if( oSRS.GetRoot() == nullptr )
++      {
          oSRS.SetLocalCS(papszFields[0]);
-+        // assume that the Y axis isn't flipped
-+        adfGeoTransform[2] *= -1.0;
-+        adfGeoTransform[5] *= -1.0;
-+        }
++      // assume that the Y axis isn't flipped
++      adfGeoTransform[2] *= -1.0;
++      adfGeoTransform[5] *= -1.0;
++      }
  
      // Try to set datum from projection info line if we have a
      // projected coordinate system without a GEOGCS.
diff --git a/SuperBuild/patches/GDAL/gdal-4-fixhdf5-win.diff b/SuperBuild/patches/GDAL/gdal-4-fixhdf5-win.diff
index 23e9fb0d748ddcc1ec8aec384434bde8754bd2fb..ecdff5829509a786ea54a8c9cbec034586c3c19b 100644
--- a/SuperBuild/patches/GDAL/gdal-4-fixhdf5-win.diff
+++ b/SuperBuild/patches/GDAL/gdal-4-fixhdf5-win.diff
@@ -1,11 +1,11 @@
---- GDAL-orig/frmts/hdf5/makefile.vc	2017-08-30 18:45:33.632677939 +0200
-+++ GDAL/frmts/hdf5/makefile.vc	2017-08-30 18:46:05.316972947 +0200
+--- gdal-2.4.1_orig/frmts/hdf5/makefile.vc	2019-03-15 13:30:02.000000000 +0100
++++ gdal-2.4.1/frmts/hdf5/makefile.vc	2019-04-05 17:43:22.356322797 +0200
 @@ -7,7 +7,7 @@
- 
- PLUGIN_DLL 	=	gdal_HDF5.dll
- 
--EXTRAFLAGS 	= 	-I$(HDF5_DIR)\include -DWIN32 -D_HDF5USEDLL_ 
-+EXTRAFLAGS 	= 	-I$(HDF5_DIR)\include -DWIN32 -DH5_BUILT_AS_DYNAMIC_LIB 
- 
- !IF "$(HDF5_PLUGIN)" == "YES"
- EXTRAFLAGS = $(EXTRAFLAGS) -DHDF5_PLUGIN
+ 
+ PLUGIN_DLL 	=	gdal_HDF5.dll
+ 
+-EXTRAFLAGS 	= 	-I$(HDF5_DIR)\include -DWIN32 -D_HDF5USEDLL_ 
++EXTRAFLAGS 	= 	-I$(HDF5_DIR)\include -DWIN32 -DH5_BUILT_AS_DYNAMIC_LIB 
+ 
+ !IF "$(HDF5_PLUGIN)" == "YES"
+ EXTRAFLAGS = $(EXTRAFLAGS) -DHDF5_PLUGIN
diff --git a/SuperBuild/patches/GDAL/gdal-5-fixOpenJPEG22_rev39821-all.diff b/SuperBuild/patches/GDAL/gdal-5-fixOpenJPEG22_rev39821-all.diff
deleted file mode 100644
index c82ddc28ab75d6c36bd16d6ec7ee3e1e3bf77636..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/GDAL/gdal-5-fixOpenJPEG22_rev39821-all.diff
+++ /dev/null
@@ -1,177 +0,0 @@
-Index: gdal/configure
-===================================================================
---- gdal/configure	(revision 39820)
-+++ gdal/configure	(revision 39821)
-@@ -25116,10 +25116,10 @@
- elif test "$with_openjpeg" = "yes" -o "$with_openjpeg" = "" ; then
- 
--  for ac_header in openjpeg-2.0/openjpeg.h
-+  for ac_header in openjpeg-2.2/openjpeg.h
- do :
--  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.0/openjpeg.h" "ac_cv_header_openjpeg_2_0_openjpeg_h" "$ac_includes_default"
--if test "x$ac_cv_header_openjpeg_2_0_openjpeg_h" = xyes; then :
-+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.2/openjpeg.h" "ac_cv_header_openjpeg_2_2_openjpeg_h" "$ac_includes_default"
-+if test "x$ac_cv_header_openjpeg_2_2_openjpeg_h" = xyes; then :
-   cat >>confdefs.h <<_ACEOF
--#define HAVE_OPENJPEG_2_0_OPENJPEG_H 1
-+#define HAVE_OPENJPEG_2_2_OPENJPEG_H 1
- _ACEOF
- 
-@@ -25128,5 +25128,5 @@
- done
- 
--  if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
-+  if test "$ac_cv_header_openjpeg_2_2_openjpeg_h" = "yes"; then
-     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_stream_set_user_data_length in -lopenjp2" >&5
- $as_echo_n "checking for opj_stream_set_user_data_length in -lopenjp2... " >&6; }
-@@ -25172,4 +25172,5 @@
- 
-     if test "$HAVE_OPENJPEG" = "yes"; then
-+        OPENJPEG_VERSION=20200
-         LIBS="-lopenjp2 $LIBS"
-     fi
-@@ -25234,4 +25235,64 @@
-             LIBS="-lopenjp2 $LIBS"
-         fi
-+    else
-+        for ac_header in openjpeg-2.0/openjpeg.h
-+do :
-+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.0/openjpeg.h" "ac_cv_header_openjpeg_2_0_openjpeg_h" "$ac_includes_default"
-+if test "x$ac_cv_header_openjpeg_2_0_openjpeg_h" = xyes; then :
-+  cat >>confdefs.h <<_ACEOF
-+#define HAVE_OPENJPEG_2_0_OPENJPEG_H 1
-+_ACEOF
-+
-+fi
-+
-+done
-+
-+        if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
-+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_stream_set_user_data_length in -lopenjp2" >&5
-+$as_echo_n "checking for opj_stream_set_user_data_length in -lopenjp2... " >&6; }
-+if ${ac_cv_lib_openjp2_opj_stream_set_user_data_length+:} false; then :
-+  $as_echo_n "(cached) " >&6
-+else
-+  ac_check_lib_save_LIBS=$LIBS
-+LIBS="-lopenjp2  $LIBS"
-+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h.  */
-+
-+/* Override any GCC internal prototype to avoid an error.
-+   Use char because int might match the return type of a GCC
-+   builtin and then its argument prototype would still apply.  */
-+#ifdef __cplusplus
-+extern "C"
-+#endif
-+char opj_stream_set_user_data_length ();
-+int
-+main ()
-+{
-+return opj_stream_set_user_data_length ();
-+  ;
-+  return 0;
-+}
-+_ACEOF
-+if ac_fn_c_try_link "$LINENO"; then :
-+  ac_cv_lib_openjp2_opj_stream_set_user_data_length=yes
-+else
-+  ac_cv_lib_openjp2_opj_stream_set_user_data_length=no
-+fi
-+rm -f core conftest.err conftest.$ac_objext \
-+    conftest$ac_exeext conftest.$ac_ext
-+LIBS=$ac_check_lib_save_LIBS
-+fi
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openjp2_opj_stream_set_user_data_length" >&5
-+$as_echo "$ac_cv_lib_openjp2_opj_stream_set_user_data_length" >&6; }
-+if test "x$ac_cv_lib_openjp2_opj_stream_set_user_data_length" = xyes; then :
-+  HAVE_OPENJPEG=yes
-+else
-+  HAVE_OPENJPEG=no
-+fi
-+
-+            if test "$HAVE_OPENJPEG" = "yes"; then
-+                LIBS="-lopenjp2 $LIBS"
-+            fi
-+        fi
-     fi
-   fi
-@@ -25244,6 +25305,9 @@
-     OPENJPEG_VERSION=20100
-     EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
-+  elif test -r $with_openjpeg/include/openjpeg-2.2/openjpeg.h ; then
-+    OPENJPEG_VERSION=20200
-+    EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
-   else
--    as_fn_error $? "openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1" "$LINENO" 5
-+    as_fn_error $? "openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1 or $with_openjpeg/include/openjpeg-2.2" "$LINENO" 5
-   fi
- 
-Index: gdal/configure.ac
-===================================================================
---- gdal/configure.ac	(revision 39820)
-+++ gdal/configure.ac	(revision 39821)
-@@ -2540,8 +2540,9 @@
- elif test "$with_openjpeg" = "yes" -o "$with_openjpeg" = "" ; then
- 
--  AC_CHECK_HEADERS([openjpeg-2.0/openjpeg.h])
--  if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
-+  AC_CHECK_HEADERS([openjpeg-2.2/openjpeg.h])
-+  if test "$ac_cv_header_openjpeg_2_2_openjpeg_h" = "yes"; then
-     AC_CHECK_LIB(openjp2,opj_stream_set_user_data_length,HAVE_OPENJPEG=yes,HAVE_OPENJPEG=no,)
-     if test "$HAVE_OPENJPEG" = "yes"; then
-+        OPENJPEG_VERSION=20200
-         LIBS="-lopenjp2 $LIBS"
-     fi
-@@ -2554,4 +2555,12 @@
-             LIBS="-lopenjp2 $LIBS"
-         fi
-+    else
-+        AC_CHECK_HEADERS([openjpeg-2.0/openjpeg.h])
-+        if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
-+            AC_CHECK_LIB(openjp2,opj_stream_set_user_data_length,HAVE_OPENJPEG=yes,HAVE_OPENJPEG=no,)
-+            if test "$HAVE_OPENJPEG" = "yes"; then
-+                LIBS="-lopenjp2 $LIBS"
-+            fi
-+        fi
-     fi
-   fi
-@@ -2564,6 +2573,9 @@
-     OPENJPEG_VERSION=20100
-     EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
--  else
--    AC_MSG_ERROR([openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1])
-+  elif test -r $with_openjpeg/include/openjpeg-2.2/openjpeg.h ; then
-+    OPENJPEG_VERSION=20200
-+    EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
-+  else
-+    AC_MSG_ERROR([openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1 or $with_openjpeg/include/openjpeg-2.2])
-   fi
- 
-Index: gdal/frmts/openjpeg/openjpegdataset.cpp
-===================================================================
---- gdal/frmts/openjpeg/openjpegdataset.cpp	(revision 39820)
-+++ gdal/frmts/openjpeg/openjpegdataset.cpp	(revision 39821)
-@@ -35,5 +35,7 @@
- #endif
- 
--#if defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20100
-+#if defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20200
-+#include <openjpeg-2.2/openjpeg.h>
-+#elif defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20100
- #include <openjpeg-2.1/openjpeg.h>
- #else
-Index: gdal/nmake.opt
-===================================================================
---- gdal/nmake.opt	(revision 39820)
-+++ gdal/nmake.opt	(revision 39821)
-@@ -608,6 +608,8 @@
- #OPENJPEG_CFLAGS = -IC:\openjpeg\include
- #OPENJPEG_LIB = C:\openjpeg\lib\openjp2.lib
--# For OpenJpeg >= 2.1, uncomment
-+# For OpenJpeg 2.1.x, uncomment
- #OPENJPEG_VERSION = 20100
-+# For OpenJpeg 2.2.x, uncomment
-+#OPENJPEG_VERSION = 20200
- 
- #if using an external zlib uncomment the following lines
-
diff --git a/SuperBuild/patches/GDAL/gdal-6-pythonInstall-all.diff b/SuperBuild/patches/GDAL/gdal-6-pythonInstall-all.diff
deleted file mode 100644
index f11d53394582aa4ec1ddc51614ae7854a1af5c50..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/GDAL/gdal-6-pythonInstall-all.diff
+++ /dev/null
@@ -1,22 +0,0 @@
---- gdal-2.2.1-orig/swig/python/GNUmakefile	2017-06-23 14:18:44.000000000 +0200
-+++ gdal-2.2.1/swig/python/GNUmakefile	2018-03-13 17:20:34.951592209 +0100
-@@ -81,18 +81,7 @@
- endif
- 
- ifdef prefix
--    ifeq ($(shell uname),Darwin)
--        STD_UNIX_LAYOUT=$(shell $(PYTHON) -c "from __future__ import print_function;import sys;print(\"FALSE\" if \"framework\" in sys.prefix.lower() else \"TRUE\")")
--        ifeq ($(STD_UNIX_LAYOUT),"TRUE")
--            setup_opts+=--prefix=$(prefix)
--        else
--            ifdef PYTHON_INSTALL_LIB
--                setup_opts+=--install-lib=$(PYTHON_INSTALL_LIB)
--            endif
--        endif
--    else
--        setup_opts+=--prefix=$(prefix)
--    endif
-+    setup_opts+=--install-lib=$(site_package_dir)
- endif
- 
- ifdef INSTALL_LAYOUT
diff --git a/SuperBuild/patches/GDAL/gdal-8-swigPython-win.diff b/SuperBuild/patches/GDAL/gdal-8-swigPython-win.diff
deleted file mode 100644
index ac49902f6cbe1f3e1e95f203466d0af346622afe..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/GDAL/gdal-8-swigPython-win.diff
+++ /dev/null
@@ -1,62 +0,0 @@
---- gdal-2.2.1-orig/makefile.vc	2017-06-23 14:18:38.000000000 +0200
-+++ gdal-2.2.1/makefile.vc	2018-03-14 19:05:43.372712378 +0100
-@@ -49,6 +49,12 @@
- 
- DISTDIR	=	gdal_$(VERSION)
- 
-+WRAP_TARGETS =
-+
-+!IFDEF WRAP_PYTHON
-+WRAP_TARGETS = $(WRAP_TARGETS) swig_py
-+!ENDIF
-+
- !IFDEF DLLBUILD
- TARGET_LIB = dll
- PLUGIN_TARGET = plugin_dir
-@@ -58,7 +64,7 @@
- 
- DEFAULT_TARGETS = 
- 
--default:	$(TARGET_LIB) $(PLUGIN_TARGET) apps_dir
-+default:	$(TARGET_LIB) $(PLUGIN_TARGET) apps_dir $(WRAP_TARGETS)
- 
- staticlib:      $(LIB_DEPENDS)
- 	if exist gdal.lib del gdal.lib
-@@ -166,6 +172,11 @@
- 
- dll:	$(GDAL_DLL)
- 
-+swig_py:   $(TARGET_LIB)
-+  cd swig
-+  $(MAKE) /f makefile.vc python
-+  cd ..
-+
- install: default
- 	-mkdir $(BINDIR)
- 	-mkdir $(DATADIR)
-@@ -191,6 +202,11 @@
- !ENDIF
- 	cd ..\..
- !ENDIF
-+!IFDEF WRAP_PYTHON
-+	cd swig
-+	$(MAKE) /f makefile.vc python-install
-+	cd ..
-+!ENDIF
- 
- libinstall: $(GDALLIB)
- 	-mkdir $(LIBDIR)
---- gdal-2.2.1-orig/swig/makefile.vc	2017-06-23 14:18:45.000000000 +0200
-+++ gdal-2.2.1/swig/makefile.vc	2018-03-14 19:04:05.851776139 +0100
-@@ -22,6 +22,11 @@
-         $(SWIG) -c++ -python -modern -new_repr -I../include/python -I../include/python/docs -o extensions/gdal_array_wrap.cpp -outdir osgeo ..\include\gdal_array.i
-         $(PYDIR)\python.exe setup.py build
- 
-+python-install: python
-+        cd python
-+        $(PYDIR)\python.exe setup.py install --prefix=$(GDAL_HOME)
-+        # TODO: install python scripts
-+
- #d:\Python\debug\Python-2.4\PCbuild\python_d.exe setup.py build   --debug
- 
- csharp: gdalvars
diff --git a/SuperBuild/patches/GDAL/gdal-fix-rpath-for-macx.diff b/SuperBuild/patches/GDAL/gdal-fix-rpath-for-macx.diff
index 1074669b42e22ebbf9cf5b2a602e5f759505f8d5..c78897e0b633e32bd3bbdd2067c7a71df867b8ef 100755
--- a/SuperBuild/patches/GDAL/gdal-fix-rpath-for-macx.diff
+++ b/SuperBuild/patches/GDAL/gdal-fix-rpath-for-macx.diff
@@ -1,33 +1,33 @@
-diff -burN gdal-1.11.2.orig/configure gdal-1.11.2/configure
---- gdal-1.11.2.orig/configure	2016-04-19 12:27:26.000000000 +0200
-+++ gdal-1.11.2/configure	2016-04-19 13:05:25.000000000 +0200
-@@ -12510,9 +12510,9 @@
+diff -burN gdal-2.4.1_orig/configure gdal-2.4.1/configure
+--- gdal-2.4.1_orig/configure	2019-03-15 13:30:02.000000000 +0100
++++ gdal-2.4.1/configure	2019-04-02 14:32:16.488024213 +0200
+@@ -14125,9 +14125,9 @@
    esac
-   if test "$_lt_dar_can_shared" = "yes"; then
+   if test yes = "$_lt_dar_can_shared"; then
      output_verbose_link_cmd=func_echo_all
--    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-     module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
--    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-     module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
-
+-    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
++    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+     module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+-    archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
++    archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+     module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ 
    else
-@@ -15457,13 +15457,13 @@
+@@ -17247,13 +17247,13 @@
    esac
-   if test "$_lt_dar_can_shared" = "yes"; then
+   if test yes = "$_lt_dar_can_shared"; then
      output_verbose_link_cmd=func_echo_all
--    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-     module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
--    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-     module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
-        if test "$lt_cv_apple_cc_single_mod" != "yes"; then
--      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
--      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
-+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring${_lt_dsymutil}"
-+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+-    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
++    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+     module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+-    archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
++    archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+     module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+        if test yes != "$lt_cv_apple_cc_single_mod"; then
+-      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+-      archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
++      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring$_lt_dsymutil"
++      archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \@rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
      fi
-
+ 
    else
diff --git a/SuperBuild/patches/GDAL/gdal-ogrclean-all.diff b/SuperBuild/patches/GDAL/gdal-ogrclean-all.diff
new file mode 100644
index 0000000000000000000000000000000000000000..6abb405815508d2f7ce3253e17fc6d3f2674372e
--- /dev/null
+++ b/SuperBuild/patches/GDAL/gdal-ogrclean-all.diff
@@ -0,0 +1,11 @@
+--- gdal-2.4.1_orig/ogr/ogrsf_frmts/generic/ogrsfdriverregistrar.cpp
++++ gdal-2.4.1/ogr/ogrsf_frmts/generic/ogrsfdriverregistrar.cpp
+@@ -83,7 +83,7 @@ int OGRwillNeverBeTrue = FALSE;
+ void OGRCleanupAll()
+ 
+ {
+-    GDALDestroyDriverManager();
++    GDALDestroy();
+ #if defined(WIN32) && defined(_MSC_VER)
+ // Horrible hack: for some reason MSVC doesn't export those classes&symbols
+ // if they are not referenced from the DLL itself
diff --git a/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in b/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in
index f17412ac067d1dd8a8052ae3a083f2261b7d1a62..8a03873073d1505ea3680959f40185526e0689a8 100644
--- a/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in
+++ b/SuperBuild/patches/GDAL/nmake_gdal_extra.opt.in
@@ -60,10 +60,9 @@ GEOS_CFLAGS = -I$(GEOS_DIR)\include -I$(GEOS_DIR)\include\geos -DHAVE_GEOS
 GEOS_LIB     = $(GEOS_DIR)\lib\geos.lib $(GEOS_DIR)\lib\geos_c.lib
 
 # Uncomment for OpenJpeg support
-HAVE_OPENJPEG = YES
 OPENJPEG_ENABLED = YES
 OPENJPEG_VERSION = 20200
-OPENJPEG_CFLAGS = -I@SB_INSTALL_PREFIX_NATIVE@\include
+OPENJPEG_CFLAGS = -I@SB_INSTALL_PREFIX_NATIVE@\include\openjpeg-2.2
 OPENJPEG_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\openjp2.lib
 
 
@@ -110,3 +109,7 @@ NETCDF_LIB = @SB_INSTALL_PREFIX_NATIVE@\lib\netcdf.lib
 NETCDF_INC_DIR = @SB_INSTALL_PREFIX_NATIVE@\include
 NETCDF_HAS_NC4 = YES
 NETCDF_HAS_HDF4 = YES
+
+# Binding list. One or several in the following list
+# csharp, java, python
+BINDINGS=python
diff --git a/sonar-project.properties b/sonar-project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..295fbc9b31bcc708be0fed7a3d586332ab1a9631
--- /dev/null
+++ b/sonar-project.properties
@@ -0,0 +1,21 @@
+sonar.projectKey=orfeotoolbox-otb
+sonar.projectName=Orfeo Toolbox
+sonar.projectDescription="Orfeo ToolBox is an open-source project for state-of-the-art remote sensing"
+sonar.links.homepage="https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb"
+sonar.links.scm="https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git"
+sonar.links.ci="https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/pipelines"
+sonar.sourceEncoding=UTF-8
+sonar.language=c++
+sonar.projectBaseDir=.
+sonar.sources=Modules
+sonar.cxx.includeDirectories=Modules
+sonar.exclusions="Modules/ThirdParty/**"
+sonar.coverage.exclusions="Modules/*/*/test/*.*"
+sonar.cxx.suffixes.sources=.cpp,.cxx,.txx,.cc,.c
+sonar.cxx.suffixes.headers=.hxx,.h
+# Commented because the relative paths are not analyzed correctly
+#sonar.cxx.jsonCompilationDatabase=build/compile_commands.json
+sonar.cxx.compiler.parser=GCC
+sonar.cxx.xunit.reportPath=build/ctest_report.xml
+sonar.cxx.coverage.reportPath=build/coverage_report.xml
+sonar.cxx.cppcheck.reportPath=build/cppcheck_report.xml