diff --git a/.gitlab/issue_templates/bugs.md b/.gitlab/issue_templates/bugs.md
index 75b403c79f42c0dcd8ee1be513cee9b70787a0a9..378d84f1b9fd63fb4c96cb6ee3319f098b70390d 100644
--- a/.gitlab/issue_templates/bugs.md
+++ b/.gitlab/issue_templates/bugs.md
@@ -9,3 +9,5 @@ Describe as precisely as possible how to reproduce the bug. Try to isolate a min
 ### Configuration information
 
 OS, OTB version or tag, information related to build (binaries, superbuild, system libs ...)
+
+/label ~bug
diff --git a/.gitlab/issue_templates/feature_request.md b/.gitlab/issue_templates/feature_request.md
index 6031fad9a77fc5b1c2dba02fbbe52847963c58e6..5b6ee30b89001a72c48d6f9435fd10ebfb5cd5a7 100644
--- a/.gitlab/issue_templates/feature_request.md
+++ b/.gitlab/issue_templates/feature_request.md
@@ -1 +1,3 @@
 Short summary of the requested feature
+
+/label ~feature
diff --git a/.gitlab/merge_request_templates/request_for_changes.md b/.gitlab/merge_request_templates/request_for_changes.md
index 1fcd7227260d3ca5bc769480ba39cf5ef63926d0..354996678a5435ed27f162a2f9b0f2142004d211 100644
--- a/.gitlab/merge_request_templates/request_for_changes.md
+++ b/.gitlab/merge_request_templates/request_for_changes.md
@@ -10,11 +10,11 @@ Explain the rationale for the changes (possible link to a Request For Comments o
 
 #### Classes and files
 
-Give an overview of the implementation: main changes made to classes, files and module. Do not paste complete diff, as it is available in the merge request already.
+Give an overview of the implementation: main changes made to classes, files and modules. Do not paste complete diff, as it is available in the merge request already.
 
 #### Applications
 
-Describe any changes made to existing applications, or new application that have been added.
+Describe any changes made to existing applications, or new applications that have been added.
 
 #### Tests
 
@@ -22,7 +22,7 @@ Describe the testing strategy for new features.
 
 ### Documentation
 
-List or link documentation modification that were made (doxygen, example, software guide, application documentation, cookbook).
+List or link documentation modifications that were made (doxygen, example, software guide, application documentation, cookbook).
 
 ### Additional notes
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..bc96c959330c797648434e970e0bfef424721428
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,147 @@
+# How to contribute to Orfeo ToolBox ?
+
+Thank you for taking the time to contribute to OTB! This document will guide you
+through the workflow and best practices you need to know to send your
+contribution.
+
+There are many ways to contribute to OTB:
+
+* [Reporting a bug](#reporting-bugs)
+* [Making a feature request](#feature-requests-and-discussions)
+* [Improving documentation](#documentation-improvements)
+* [Contributing code (C++, Python, CMake, etc.)](#code-contribution)
+* [Publishing a remote module](#remote-modules)
+
+Our main workflow uses GitLab for source control, issues and task tracking. We
+use a self-hosted gitlab instance:
+
+[`https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb`](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb)
+
+Remember to check out also our [developers mailing list](https://groups.google.com/forum/?hl=fr#!forum/otb-developers/join),
+where we discuss some features, improvements and high level project planning.
+You are welcome to ask questions there as a beginner or future OTB contributor!
+
+## Reporting bugs
+
+If you have found a bug, you can first [search the existing issues](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues?label_name%5B%5D=bug)
+to see if it has already been reported.
+
+If it's a new bug, please [open a new issue on GitLab](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues/new).
+The 'Bug' issue template will help you provide all important information and
+help fixing the bug quicker. Remember to add as much information as possible!
+
+## Feature requests and discussions
+
+Feature requests are welcome! Generally you are welcome to simply [open an issue](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues)
+and discuss your idea there. For more complex requests there is an issue
+template for in depth description called 'Request for Comments'.
+
+
+## Documentation improvements
+
+The two main OTB documentations are the [Software Guide](https://www.orfeo-toolbox.org/SoftwareGuide/index.html)
+and the [CookBook](https://www.orfeo-toolbox.org/CookBook/).  Their sources are
+hosted in the main OTB repository in the `Documentation/` directory. Then, to
+contribute documentation use the same workflow as for code contributions (see
+below).
+
+See also the [Compiling documentation](https://wiki.orfeo-toolbox.org/index.php/Compiling_documentation)
+wiki page for help on building the Sphinx and Latex source.
+
+## Code contribution
+
+The OTB workflow is based on GitLab [Merge Requests](https://docs.gitlab.com/ee/gitlab-basics/add-merge-request.html).
+Clone the repository, create a feature branch, commit your changes, push the
+feature branch to a fork (or the main repository if you are a core developer),
+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.
+
+### Commit message
+
+On your feature branch, write a good [commit message](https://xkcd.com/1296/):
+short and descriptive. If fixing an issue or bug, put the issue number in the
+commit message so that GitLab can [crosslink it](https://docs.gitlab.com/ce/user/project/issues/crosslinking_issues.html).
+You can prefix your commit message with an indicating flag (DOC, BUG, PKG,
+TEST, SuperBuild, etc.).
+
+Standard prefixes for OTB commit messages:
+
+    BUG: Fix for runtime crash or incorrect result
+    COMP: Compiler error or warning fix
+    DOC: Documentation change
+    ENH: New functionality
+    PERF: Performance improvement
+    STYLE: No logic impact (indentation, comments)
+    WIP: Work In Progress not ready for merge
+
+For example, here are some good commit messages:
+
+    BUG: #1701 Warn users if parameter string is unset
+    DOC: Fix typo in Monteverdi French translation
+    COMP: Allow GeoTIFF and TIFF to be disabled when no 3rd party drags them
+
+### Merge request
+
+Your contribution is ready to be added to the main OTB repository? Send a Merge
+Request against the `develop` branch on GitLab using the merge request
+template. The merge request will then be discussed by the community and the core
+OTB team.
+
+* Merge requests can not be merged until all discussions have been resolved (this is enforced by GitLab)
+* Merge requests **must receive at least 2 positives votes from 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
+
+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:
+
+```
+branch_name [otb-data_branch_name]
+
+```
+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.
+
+For branches in forks, the syntax is the following:
+```
+user/branch_name [user/otb-data_branch_name]
+```
+Again, the second branch name is optional.
+
+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.
+
+Once the feature branch is registered for testing, it should appear in the *FeatureBranches* section of the [OTB dashboard](https://dash.orfeo-toolbox.org/index.php?project=OTB) next day (remember tests are run on a nighlty basis).
+
+Do not forget to remove the feature branch for testing once it has been merged.
+
+## Remote modules
+
+[Remote Modules](https://wiki.orfeo-toolbox.org/index.php/Remote_Modules) are
+the prefered way if you wish to make your apps and filters available to the
+community while keeping control and maintenance of their sources. Remote
+modules are just like regular modules, except they are not distributed inside
+OTB source code. Under some conditions (dependencies, official acceptance
+process, etc.), we are also able to distribute your remote module in the
+official standalone binaries. See [the wiki](https://wiki.orfeo-toolbox.org/index.php/Remote_Modules)
+for more information.
+
+## Gitlab guidelines
+
+In order to organize the issues in our Gitlab instance, we use both labels and
+milestones.
+
+The [milestones](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/milestones) should be used to track in which release a feature is merged.
+Gitlab can then provide a summary of all features and bugs added to a given release
+version.
+
+Regarding labels, we use the following set:
+* ~story: significant feature to be implemented with a detailed work plan, it can
+  correspond to a Request for Comments that has turned into a development action
+* ~bug: Bug, crash or unexpected behavior, reported by a user or a developer
+* ~feature: Feature request expressed by an OTB user/developer
+* ~"To Do": action is planned
+* ~Doing: work in progress
+* ~api ~app ~documentation ~monteverdi ~packaging ~qgis: optional context information
diff --git a/Documentation/Cookbook/rst/ExtendedFilenames.rst b/Documentation/Cookbook/rst/ExtendedFilenames.rst
new file mode 100644
index 0000000000000000000000000000000000000000..02b5512351958d0b5ae88f1de831e9c5c2f823cc
--- /dev/null
+++ b/Documentation/Cookbook/rst/ExtendedFilenames.rst
@@ -0,0 +1,317 @@
+.. _extended-filenames:
+
+Extended filenames
+================================
+
+Extended filenames is an interesting feature of OTB. With it, you can control
+several aspects of the beahvior of the OTB in the OTB-Applications or in our
+own C++ applications. Historically this feature has been desingn to solve
+an issue with how to handle geo-referencing information. 
+
+Indeed, there are multiple ways to define geo-referencing information. For
+instance, one can use a geographic transform, a cartographic projection,
+or a sensor model with RPC coefficients. A single image may contain
+several of these elements, such as in the “ortho-ready” products: this
+is a type of product still in sensor geometry (the sensor model is
+supplied with the image) but it also contains an approximative
+geographic transform that can be used to have a quick estimate of the
+image localisation. For instance, your product may contain a “.TIF” file
+for the image, along with a “.RPB” file that contains the sensor model
+coefficients and an “.IMD” file that contains a cartographic projection.
+
+This case leads to the following question: which geo-referencing
+element should be used when opening this image in OTB. In
+fact, it depends on the users need. For an orthorectification
+application, the sensor model must be used. In order to specify which
+information should be skipped, a syntax of extended filenames has been
+developed for both reading and writing.
+
+Since the development of this feature we have extend this mechanism for 
+other aspaects: like band or overview selection in reader part or support
+create option of gdal in writer part.The reader and writer extended filename 
+support is based on the same syntax, only the options are different. 
+To benefit from the extended file name mechanism, the following syntax 
+is to be used:
+
+::
+
+    Path/Image.ext?&key1=<value1>&key2=<value2>
+
+**Note that you’ll probably need to “quote” the filename, especially if calling
+applications from the bash command line.**
+
+Reader options
+^^^^^^^^^^^^^^
+
+::
+
+    &geom=<path/filename.geom>
+
+-  Contains the file name of a valid geom file
+
+-  Use the content of the specified geom file instead of
+   image-embedded geometric information
+
+-  empty by default, use the image-embedded information if available
+
+-----------------------------------------------
+
+::
+
+    &sdataidx=<(int)idx>
+
+-  Select the sub-dataset to read
+
+-  0 by default
+
+-----------------------------------------------
+
+::
+
+    &resol=<(int)resolution factor>
+
+-  Select the JPEG2000 sub-resolution image to read
+
+-  0 by default
+
+-----------------------------------------------
+
+::
+
+    &bands=r1,r2,...,rn
+
+-  Select a subset of bands from the input image
+
+-  The syntax is inspired by Python indexing syntax with
+   bands=r1,r2,r3,...,rn where each ri is a band range that can be :
+
+   -  a single index (1-based) :
+
+      -  :code:`2` means 2nd band
+
+      -  :code:`-1` means last band
+
+   -  or a range of bands :
+
+      -  :code:`3:` means 3rd band until the last one
+
+      -  :code:`:-2` means the first bands until the second to last
+
+      -  :code:`2:4` means bands 2,3 and 4
+
+-  empty by default (all bands are read from the input image)
+
+-----------------------------------------------
+
+::
+
+    &skipcarto=<(bool)true>
+
+-  Skip the cartographic information
+
+-  Clears the projectionref, set the origin to :math:`[0,0]` and the
+   spacing to :math:`[1/max(1,r),1/max(1,r)]` where :math:`r` is the resolution
+   factor.
+
+-  Keeps the keyword list
+
+-  false by default
+
+-----------------------------------------------
+
+::
+
+    &skipgeom=<(bool)true>
+
+-  Skip geometric information
+
+-  Clears the keyword list
+
+-  Keeps the projectionref and the origin/spacing information
+
+-  false by default.
+
+-----------------------------------------------
+
+::
+
+    &skiprpctag=<(bool)true>
+
+-  Skip the reading of internal RPC tags (see
+   [sec:TypesofSensorModels] for details)
+
+-  false by default.
+
+Writer options
+^^^^^^^^^^^^^^
+
+::
+
+    &writegeom=<(bool)false>
+
+-  To activate writing of external geom file
+
+-  true by default
+
+-----------------------------------------------
+
+::
+
+    &writerpctags=<(bool)true>
+
+-  To activate writing of RPC tags in TIFF files
+
+-  false by default
+
+-----------------------------------------------
+
+::
+
+    &gdal:co:<GDALKEY>=<VALUE>
+
+-  To specify a gdal creation option
+
+-  For gdal creation option information, see dedicated gdal documentation for each driver. For example, you can find `here <http://www.gdal.org/frmt_gtiff.html>`_ the information about the GeoTiff create options
+
+-  None by default
+
+-----------------------------------------------
+
+::
+
+    &streaming:type=<VALUE>
+
+-  Activates configuration of streaming through extended filenames
+
+-  Override any previous configuration of streaming
+
+-  Allows to configure the kind of streaming to perform
+
+-  Available values are:
+
+   -  auto: tiled or stripped streaming mode chosen automatically
+      depending on TileHint read from input files
+
+   -  tiled: tiled streaming mode
+
+   -  stripped: stripped streaming mode
+
+   -  none: explicitly deactivate streaming
+
+-  Not set by default
+
+-----------------------------------------------
+
+::
+
+    &streaming:sizemode=<VALUE>
+
+-  Allows to choose how the size of the streaming pieces is computed
+
+-  Available values are:
+
+   -  auto: size is estimated from the available memory setting by
+      evaluating pipeline memory print
+
+   -  height: size is set by setting height of strips or tiles
+
+   -  nbsplits: size is computed from a given number of splits
+
+-  Default is auto
+
+-----------------------------------------------
+
+::
+
+    &streaming:sizevalue=<VALUE>
+
+-  Parameter for size of streaming pieces computation
+
+-  Value is :
+
+   -  if sizemode=auto: available memory in Mb
+
+   -  if sizemode=height: height of the strip or tile in pixels
+
+   -  if sizemode=nbsplits: number of requested splits for streaming
+
+-  If not provided, the default value is set to 0 and result in
+   different behaviour depending on sizemode (if set to height or
+   nbsplits, streaming is deactivated, if set to auto, value is
+   fetched from configuration or cmake configuration file)
+
+-----------------------------------------------
+
+::
+
+    &box=<startx>:<starty>:<sizex>:<sizey>
+
+-  User defined parameters of output image region
+
+-  The region must be set with 4 unsigned integers (the separator
+   used is the colon ’:’). Values are:
+
+   -  startx: first index on X (starting with 0)
+
+   -  starty: first index on Y (starting with 0)
+
+   -  sizex: size along X
+
+   -  sizey: size along Y
+
+-  The definition of the region follows the same convention as
+   itk::Region definition in C++. A region is defined by two classes:
+   the itk::Index and itk::Size classes. The origin of the region
+   within the image with which it is associated is defined by Index
+
+-----------------------------------------------
+
+::
+
+    &bands=r1,r2,...,rn
+
+-  Select a subset of bands from the output image
+
+-  The syntax is inspired by Python indexing syntax with
+   bands=r1,r2,r3,...,rn where each ri is a band range that can be :
+
+   -  a single index (1-based) :
+
+      -  :code:`2` means 2nd band
+
+      -  :code:`-1` means last band
+
+   -  or a range of bands :
+
+      -  :code:`3:` means 3rd band until the last one
+
+      -  :code:`:-2` means the first bands until the second to last
+
+      -  :code:`2:4` means bands 2,3 and 4
+
+-  Empty by default (all bands are write from the output image)
+
+The available syntax for boolean options are:
+
+-  ON, On, on, true, True, 1 are available for setting a ’true’ boolean
+   value
+
+-  OFF, Off, off, false, False, 0 are available for setting a ’false’
+   boolean value
+   
+Examples
+^^^^^^^^^^^^^^
+
+You can find below some examples:
+
+- Write a file with blockSize equal to 256 and with DEFLATE compression
+
+::
+
+    $ otbcli_Convert -in OTB-Data/Examples/QB_1_ortho.tif -out "/tmp/example1.tif?&gdal:co:TILED=YES&gdal:co:COMPRESS=DEFLATE"
+
+- Process only first band from a file
+
+::
+
+    $ otbcli_Convert -in "OTB-Data/Examples/QB_1_ortho.tif?&bands=1" -out /tmp/example2.tif
diff --git a/Documentation/Cookbook/rst/FAQ.rst b/Documentation/Cookbook/rst/FAQ.rst
index 490e77a34c1619fb5025e823fcf680d9c3d27c83..83faac13abd949abb9c97b6ad0e07137e19c0ae2 100644
--- a/Documentation/Cookbook/rst/FAQ.rst
+++ b/Documentation/Cookbook/rst/FAQ.rst
@@ -189,7 +189,7 @@ The first time, you can get the source code using:
 
 ::
 
-          git clone https://git@git.orfeo-toolbox.org/git/otb.git
+          git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git
 
 Then you can build OTB as usual using this directory as the source
 (refer to build instructions). Later if you want to update your source,
@@ -428,7 +428,7 @@ You can get the base doing:
 
 ::
 
-          git clone https://git@git.orfeo-toolbox.org/git/otb-data.git
+          git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git
 
 This is about 1 GB of data, so it will take a while, but you have to do
 it only once, as after, a simple
diff --git a/Documentation/Cookbook/rst/Installation_Linux_xdk.txt b/Documentation/Cookbook/rst/Installation_Linux_xdk.txt
index a81d7f1f6f09f6740bee5b41fc1c4aff4515b6d0..38c890f066429e6af90b2c6cb8ec1f20af269a90 100644
--- a/Documentation/Cookbook/rst/Installation_Linux_xdk.txt
+++ b/Documentation/Cookbook/rst/Installation_Linux_xdk.txt
@@ -54,7 +54,7 @@ Download, Configure and build OTB
 ::
 
     mkdir -p /opt/OTB/build && cd /opt/OTB
-    git clone --depth=1 --branch=develop https://git@git.orfeo-toolbox.org/git/otb.git source
+    git clone --depth=1 --branch=develop https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git source
     cd build && cmake ../source 
     make -j2
 
diff --git a/Documentation/Cookbook/rst/Monteverdi.rst b/Documentation/Cookbook/rst/Monteverdi.rst
index 257ae1a017a0bac15cadf68443a6a5cdf6d236a4..ac362cc2822f7925b3a21159cd8c43958cc194f7 100644
--- a/Documentation/Cookbook/rst/Monteverdi.rst
+++ b/Documentation/Cookbook/rst/Monteverdi.rst
@@ -321,7 +321,7 @@ Conclusion
 ~~~~~~~~~~
 
 The images used in this documentation can be found in the OTB-Data
-repository (https://git.orfeo-toolbox.org/otb-data.git):
+repository (https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git):
 
 -  in OTB-Data/Input:
 
diff --git a/Documentation/Cookbook/rst/OTB-Applications.rst b/Documentation/Cookbook/rst/OTB-Applications.rst
index 4da50bd9f419a096e11957e7c35e2621d9cfbd50..1905a737e7e72d869670d226e69bfa6e02b5b9d7 100644
--- a/Documentation/Cookbook/rst/OTB-Applications.rst
+++ b/Documentation/Cookbook/rst/OTB-Applications.rst
@@ -360,296 +360,3 @@ among 560 cpus and took only 56 seconds.
 Note that this MPI parallel invocation of applications is only
 available for command-line calls to OTB applications, and only for
 images output parameters.
-
-.. _extended-filenames:
-
-Extended filenames
-------------------
-
-There are multiple ways to define geo-referencing information. For
-instance, one can use a geographic transform, a cartographic projection,
-or a sensor model with RPC coefficients. A single image may contain
-several of these elements, such as in the “ortho-ready” products: this
-is a type of product still in sensor geometry (the sensor model is
-supplied with the image) but it also contains an approximative
-geographic transform that can be used to have a quick estimate of the
-image localisation. For instance, your product may contain a “.TIF” file
-for the image, along with a “.RPB” file that contains the sensor model
-coefficients and an “.IMD” file that contains a cartographic projection.
-
-This case leads to the following question: which geo-referencing
-element should be used when opening this image in OTB. In
-fact, it depends on the users need. For an orthorectification
-application, the sensor model must be used. In order to specify which
-information should be skipped, a syntax of extended filenames has been
-developed for both reading and writing.
-
-The reader and writer extended file name support is based on the same
-syntax, only the options are different. To benefit from the extended
-file name mechanism, the following syntax is to be used:
-
-::
-
-    Path/Image.ext?&key1=<value1>&key2=<value2>
-
-Note that you’ll probably need to “quote” the filename, especially if calling
-applications from the bash command line.
-
-Reader options
-^^^^^^^^^^^^^^
-
-::
-
-    &geom=<path/filename.geom>
-
--  Contains the file name of a valid geom file
-
--  Use the content of the specified geom file instead of
-   image-embedded geometric information
-
--  empty by default, use the image-embedded information if available
-
------------------------------------------------
-
-::
-
-    &sdataidx=<(int)idx>
-
--  Select the sub-dataset to read
-
--  0 by default
-
------------------------------------------------
-
-::
-
-    &resol=<(int)resolution factor>
-
--  Select the JPEG2000 sub-resolution image to read
-
--  0 by default
-
------------------------------------------------
-
-::
-
-    &bands=r1,r2,...,rn
-
--  Select a subset of bands from the input image
-
--  The syntax is inspired by Python indexing syntax with
-   bands=r1,r2,r3,...,rn where each ri is a band range that can be :
-
-   -  a single index (1-based) :
-
-      -  :code:`2` means 2nd band
-
-      -  :code:`-1` means last band
-
-   -  or a range of bands :
-
-      -  :code:`3:` means 3rd band until the last one
-
-      -  :code:`:-2` means the first bands until the second to last
-
-      -  :code:`2:4` means bands 2,3 and 4
-
--  empty by default (all bands are read from the input image)
-
------------------------------------------------
-
-::
-
-    &skipcarto=<(bool)true>
-
--  Skip the cartographic information
-
--  Clears the projectionref, set the origin to :math:`[0,0]` and the
-   spacing to :math:`[1/max(1,r),1/max(1,r)]` where :math:`r` is the resolution
-   factor.
-
--  Keeps the keyword list
-
--  false by default
-
------------------------------------------------
-
-::
-
-    &skipgeom=<(bool)true>
-
--  Skip geometric information
-
--  Clears the keyword list
-
--  Keeps the projectionref and the origin/spacing information
-
--  false by default.
-
------------------------------------------------
-
-::
-
-    &skiprpctag=<(bool)true>
-
--  Skip the reading of internal RPC tags (see
-   [sec:TypesofSensorModels] for details)
-
--  false by default.
-
-Writer options
-^^^^^^^^^^^^^^
-
-::
-
-    &writegeom=<(bool)false>
-
--  To activate writing of external geom file
-
--  true by default
-
------------------------------------------------
-
-::
-
-    &writerpctags=<(bool)true>
-
--  To activate writing of RPC tags in TIFF files
-
--  false by default
-
------------------------------------------------
-
-::
-
-       &gdal:co:<GDALKEY>=<VALUE>
-
--  To specify a gdal creation option
-
--  For gdal creation option information, see dedicated gdal documentation
-
--  None by default
-
------------------------------------------------
-
-::
-
-    &streaming:type=<VALUE>
-
--  Activates configuration of streaming through extended filenames
-
--  Override any previous configuration of streaming
-
--  Allows to configure the kind of streaming to perform
-
--  Available values are:
-
-   -  auto: tiled or stripped streaming mode chosen automatically
-      depending on TileHint read from input files
-
-   -  tiled: tiled streaming mode
-
-   -  stripped: stripped streaming mode
-
-   -  none: explicitly deactivate streaming
-
--  Not set by default
-
------------------------------------------------
-
-::
-
-    &streaming:sizemode=<VALUE>
-
--  Allows to choose how the size of the streaming pieces is computed
-
--  Available values are:
-
-   -  auto: size is estimated from the available memory setting by
-      evaluating pipeline memory print
-
-   -  height: size is set by setting height of strips or tiles
-
-   -  nbsplits: size is computed from a given number of splits
-
--  Default is auto
-
------------------------------------------------
-
-::
-
-    &streaming:sizevalue=<VALUE>
-
--  Parameter for size of streaming pieces computation
-
--  Value is :
-
-   -  if sizemode=auto: available memory in Mb
-
-   -  if sizemode=height: height of the strip or tile in pixels
-
-   -  if sizemode=nbsplits: number of requested splits for streaming
-
--  If not provided, the default value is set to 0 and result in
-   different behaviour depending on sizemode (if set to height or
-   nbsplits, streaming is deactivated, if set to auto, value is
-   fetched from configuration or cmake configuration file)
-
------------------------------------------------
-
-::
-
-    &box=<startx>:<starty>:<sizex>:<sizey>
-
--  User defined parameters of output image region
-
--  The region must be set with 4 unsigned integers (the separator
-   used is the colon ’:’). Values are:
-
-   -  startx: first index on X (starting with 0)
-
-   -  starty: first index on Y (starting with 0)
-
-   -  sizex: size along X
-
-   -  sizey: size along Y
-
--  The definition of the region follows the same convention as
-   itk::Region definition in C++. A region is defined by two classes:
-   the itk::Index and itk::Size classes. The origin of the region
-   within the image with which it is associated is defined by Index
-
------------------------------------------------
-
-::
-
-    &bands=r1,r2,...,rn
-
--  Select a subset of bands from the output image
-
--  The syntax is inspired by Python indexing syntax with
-   bands=r1,r2,r3,...,rn where each ri is a band range that can be :
-
-   -  a single index (1-based) :
-
-      -  :code:`2` means 2nd band
-
-      -  :code:`-1` means last band
-
-   -  or a range of bands :
-
-      -  :code:`3:` means 3rd band until the last one
-
-      -  :code:`:-2` means the first bands until the second to last
-
-      -  :code:`2:4` means bands 2,3 and 4
-
--  Empty by default (all bands are write from the output image)
-
-The available syntax for boolean options are:
-
--  ON, On, on, true, True, 1 are available for setting a ’true’ boolean
-   value
-
--  OFF, Off, off, false, False, 0 are available for setting a ’false’
-   boolean value
diff --git a/Documentation/Cookbook/rst/index_TOC.rst b/Documentation/Cookbook/rst/index_TOC.rst
index d09049ccec83ef3be5d654decf11e25998f9e7bc..12565d1577bd6a9211449e2c9e71b2cf0ca291e6 100644
--- a/Documentation/Cookbook/rst/index_TOC.rst
+++ b/Documentation/Cookbook/rst/index_TOC.rst
@@ -8,6 +8,7 @@ Table of Contents
    Installation
    OTB-Applications
    Monteverdi
+   ExtendedFilenames
    Recipes
    Applications
    FAQ
diff --git a/Documentation/Cookbook/rst/recipes/optpreproc.rst b/Documentation/Cookbook/rst/recipes/optpreproc.rst
index 41b1169fa8bf5fa3736bc259f7f0797f72415fe3..e3f00ca3a47bb36f7b98e0128a280d52593f233a 100644
--- a/Documentation/Cookbook/rst/recipes/optpreproc.rst
+++ b/Documentation/Cookbook/rst/recipes/optpreproc.rst
@@ -242,7 +242,7 @@ path to a file which contains the geoid. `Geoid <http://en.wikipedia.org/wiki/Ge
 corresponds to the equipotential surface that would coincide with the mean ocean surface of
 the Earth.
 
-We provide one geoid in the `OTB-Data <https://git.orfeo-toolbox.org/otb-data.git/tree/HEAD:/Input/DEM>`_ repository.
+We provide one geoid in the `OTB-Data <https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data/tree/master/Input/DEM>`_ repository.
 
 In all applications, the option **elev.geoid** allows to manage the path
 to the geoid. Finally, it is also possible to use an average elevation
diff --git a/Documentation/Cookbook/rst/recipes/pbclassif.rst b/Documentation/Cookbook/rst/recipes/pbclassif.rst
index 1e26e4c7f53a0aafdf701cf3b8bd7ef9bc1fb51a..4202066085f000e6ec8f4b1f1eac313f277de09a 100644
--- a/Documentation/Cookbook/rst/recipes/pbclassif.rst
+++ b/Documentation/Cookbook/rst/recipes/pbclassif.rst
@@ -525,7 +525,7 @@ Example
 
 We consider 4 classes: water, roads, vegetation and buildings with red
 roofs. Data is available in the OTB-Data
-`repository <https://git.orfeo-toolbox.org/otb-data.git/tree/HEAD:/Input/Classification>`_ .
+`repository <https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data/tree/master/Input/Classification>`_ .
 
 .. |image_21| image:: ../Art/MonteverdiImages/classification_chain_inputimage.jpg
 .. |image_22| image:: ../Art/MonteverdiImages/classification_chain_fancyclassif_fusion.jpg
diff --git a/Documentation/SoftwareGuide/Latex/Installation.tex b/Documentation/SoftwareGuide/Latex/Installation.tex
index ea869b753148edff4d213bf066a1de0b26a24271..e6ab1534d296b6158b0a4627fc4edecfd363992f 100644
--- a/Documentation/SoftwareGuide/Latex/Installation.tex
+++ b/Documentation/SoftwareGuide/Latex/Installation.tex
@@ -163,7 +163,7 @@ To setup this structure, the following commands can be used:
 \begin{verbatim}
 $ mkdir ~/OTB
 $ cd ~/OTB
-$ git clone https://git@git.orfeo-toolbox.org/git/otb.git
+$ git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git
 $ mkdir build
 $ mkdir install
 \end{verbatim}
diff --git a/Documentation/SoftwareGuide/Latex/Introduction.tex b/Documentation/SoftwareGuide/Latex/Introduction.tex
index bca731112bbd207b7b598532ed8eb2816cf2ab52..f3ae6653bade821339a938887b6313916cd4125c 100644
--- a/Documentation/SoftwareGuide/Latex/Introduction.tex
+++ b/Documentation/SoftwareGuide/Latex/Introduction.tex
@@ -100,14 +100,14 @@ process described in Section \ref{chapter:Installation}.
 There are two other ways of getting the OTB source code:
 \begin{itemize}
 \item Clone the current release with \href{https://git-scm.com/}{Git} from the
-  \href{https://git.orfeo-toolbox.org/otb.git}{OTB git server}, (master branch)
+  \href{https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git}{OTB git server}, (master branch)
 \item Clone the latest revision with \href{https://git-scm.com/}{Git} from the
-  \href{https://git.orfeo-toolbox.org/otb.git}{OTB git server} (develop branch).
+  \href{https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git}{OTB git server} (develop branch).
 \end{itemize}
 
 These last two options need a proper \href{https://git-scm.com/}{Git} installation. To get source code from Git, do:
 \begin{verbatim}
-git clone https://git@git.orfeo-toolbox.org/git/otb.git
+git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git
 \end{verbatim}
 
 Using Git, you can easily navigate through the different versions. The master
diff --git a/Documentation/SoftwareGuide/Latex/Tutorial.tex b/Documentation/SoftwareGuide/Latex/Tutorial.tex
index be8cd232fc53ecfb8dfe51e5fbae91cb0424fca6..4a09dc660223796abaa0b3f92bb28d4e81660960 100644
--- a/Documentation/SoftwareGuide/Latex/Tutorial.tex
+++ b/Documentation/SoftwareGuide/Latex/Tutorial.tex
@@ -224,7 +224,7 @@ Once this file is written you just have to run \code{make}. The
 
 Get one image from the \code{OTB-Data/Examples} directory from the OTB-Data
 repository. You can get it either by cloning the OTB data repository 
-(\code{git clone https://git.orfeo-toolbox.org/otb-data.git}), but that might be quite 
+(\code{git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git}), but that might be quite 
 long as this also gets the data to run the tests. Alternatively, you can get it from 
 \url{http://www.orfeo-toolbox.org/packages/OTB-Data-Examples.tgz}.
 Take for example get \code{QB\_Suburb.png}.
diff --git a/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h b/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h
index 692c1574fc7e12b390832546a43154411d6f5e7b..8a713883b6720d0dd9b8e0ce89c03ae924cd75c9 100644
--- a/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h
+++ b/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h
@@ -24,6 +24,7 @@
 #include <memory>
 
 #include "otbDEMHandler.h"
+#include "itkPoint.h"
 
 namespace ossimplugins
 {
@@ -62,6 +63,9 @@ public:
 
   typedef std::auto_ptr<ossimplugins::ossimSarSensorModel> InternalModelPointer;
 
+  using Point2DType = itk::Point<double,2>;
+  using Point3DType = itk::Point<double,3>;
+  
   /** Method for creation through the object factory. */
   itkNewMacro(Self);
 
@@ -80,6 +84,21 @@ public:
   /** Deburst metadata if possible and return lines to keep in image file */
   bool Deburst(std::vector<std::pair<unsigned long, unsigned long> > & lines);
 
+  /** Transform world point (lat,lon,hgt) to input image point
+  (col,row) and YZ frame */
+  bool WorldToLineSampleYZ(const Point3DType & inGeoPoint, Point2DType & cr, Point2DType & yz) const;
+
+  /** Transform world point (lat,lon,hgt) to input image point
+  (col,row) */
+  bool WorldToLineSample(const Point3DType & inGEoPOint, Point2DType & cr) const;
+
+/** Transform world point (lat,lon,hgt) to satellite position (x,y,z) and satellite velocity */
+  bool WorldToSatPositionAndVelocity(const Point3DType & inGeoPoint, Point3DType & satelitePosition,  
+				     Point3DType & sateliteVelocity) const;
+
+  /** Transform world point (lat,lon,hgt) to cartesian point (x,y,z) */
+  static bool WorldToCartesian(const Point3DType & inGeoPoint, Point3DType & outCartesianPoint);
+
   static bool ImageLineToDeburstLine(const std::vector<std::pair<unsigned long,unsigned long> >& lines, unsigned long imageLine, unsigned long & deburstLine);
 
   static void DeburstLineToImageLine(const std::vector<std::pair<unsigned long,unsigned long> >& lines, unsigned long deburstLine, unsigned long & imageLine);
diff --git a/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx b/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx
index 36550717ca0ade79935fad796beb91624afdf008..6063915cfb4996895de1371735454092f81368d7 100644
--- a/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx
+++ b/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx
@@ -287,60 +287,15 @@ ReadGeometryFromImage(const std::string& filename, bool checkRpcTag)
     }
 
   /**********************************************************/
-  /* Third try : look for external geom file and RPC tags   */
+  /* Third try : look for RPC tags   */
   /**********************************************************/
-  if (!hasMetaData)
+  if (!hasMetaData && checkRpcTag)
     {
-    // If still no metadata, try the ".geom" file
-    ossimFilename ossimGeomFile = ossimFilename(filename).setExtension(".geom");
-    otb_kwl = ReadGeometryFromGEOMFile(ossimGeomFile);
-
-    // also check any RPC tags
-    ImageKeywordlist rpc_kwl;
-    if (checkRpcTag)
-      {
-      rpc_kwl = ReadGeometryFromRPCTag(filename);
-      }
-
-    if (otb_kwl.HasKey("type"))
-      {
-      // external geom has a "type" keyword
-      std::string geomType(otb_kwl.GetMetadataByKey("type"));
-      ossimProjection *testProj = ossimProjectionFactoryRegistry::instance()
-        ->createProjection(ossimString(geomType));
-      if (dynamic_cast<ossimSensorModel*>(testProj))
-        {
-        // "type" keyword corresponds to a sensor model : don't erase it
-        if (rpc_kwl.GetSize() > 0)
-          {
-          rpc_kwl.ClearMetadataByKey("type");
-          }
-
-        ossimKeywordlist ossim_test_kwl;
-        otb_kwl.convertToOSSIMKeywordlist(ossim_test_kwl);
-        testProj = ossimProjectionFactoryRegistry::instance()
-          ->createProjection(ossim_test_kwl);
-        if (testProj)
-          {
-          // external geom contains a valid sensor geometry
-          hasMetaData = true;
-          }
-        }
-      }
+    // check any RPC tags
+    otb_kwl = ReadGeometryFromRPCTag(filename);
 
-    // copy keywords found in RPC tags if the external geom is not valid
-    if (!hasMetaData && rpc_kwl.GetSize() > 0)
+    if (!otb_kwl.Empty())
       {
-      const ImageKeywordlist::KeywordlistMap &kwlMap = rpc_kwl.GetKeywordlist();
-      for (ImageKeywordlist::KeywordlistMap::const_iterator it = kwlMap.begin();
-          it != kwlMap.end();
-          ++it)
-        {
-        if (it->second != "")
-          {
-          otb_kwl.AddKey(it->first , it->second);
-          }
-        }
       hasMetaData = true;
       }
     }
diff --git a/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx b/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx
index 62d5203af5c4d7dc04f4b9a3d66706cef1fa084a..56bcfbca01f498b1f8cc020b5c8e839ebf809cbb 100644
--- a/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx
+++ b/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx
@@ -109,7 +109,112 @@ void SarSensorModelAdapter::DeburstLineToImageLine(const std::vector<std::pair<u
   ossimplugins::ossimSarSensorModel::deburstLineToImageLine(lines,deburstLine,imageLine);
 }
 
+bool SarSensorModelAdapter::WorldToLineSampleYZ(const Point3DType & inGeoPoint, Point2DType & cr, Point2DType & yz) const
+{
+  if(m_SensorModel.get() == ITK_NULLPTR)
+    {
+    return false;
+    }
+
+  ossimGpt inGpt;
+  inGpt.lon = inGeoPoint[0];
+  inGpt.lat = inGeoPoint[1];
+  inGpt.hgt = inGeoPoint[2];
+
+  ossimDpt outDpt;
+
+  double y(0.),z(0.);
+  m_SensorModel->worldToLineSampleYZ(inGpt,outDpt,y,z);
+
+  if(outDpt.isNan())
+    return false;
+
+  cr[0]=outDpt.x;
+  cr[1]=outDpt.y;
+  yz[0]=y;
+  yz[1]=z;
+
+  return true;
+}
 
+bool SarSensorModelAdapter::WorldToLineSample(const Point3DType & inGeoPoint, Point2DType & cr) const
+{
+  if(m_SensorModel.get() == ITK_NULLPTR)
+    {
+    return false;
+    }
+
+  ossimGpt inGpt;
+  inGpt.lon = inGeoPoint[0];
+  inGpt.lat = inGeoPoint[1];
+  inGpt.hgt = inGeoPoint[2];
+
+  ossimDpt outDpt;
+
+  m_SensorModel->worldToLineSample(inGpt,outDpt);
+
+  if(outDpt.isNan())
+    return false;
+
+  cr[0]=outDpt.x;
+  cr[1]=outDpt.y;
+
+  return true;
+}
+
+bool SarSensorModelAdapter::WorldToCartesian(const Point3DType & inGeoPoint, Point3DType & outCartesianPoint)
+{
+  ossimGpt inGpt;
+  inGpt.lon = inGeoPoint[0];
+  inGpt.lat = inGeoPoint[1];
+  inGpt.hgt = inGeoPoint[2];
+
+  ossimEcefPoint outCartesien(inGpt);
+  
+  if(outCartesien.isNan())
+    return false;
+
+  outCartesianPoint[0] = outCartesien.x();
+  outCartesianPoint[1] = outCartesien.y();
+  outCartesianPoint[2] = outCartesien.z();
+
+  return true;
+}
+  
+bool SarSensorModelAdapter::WorldToSatPositionAndVelocity(const Point3DType & inGeoPoint, 
+							  Point3DType & satelitePosition, 
+							  Point3DType & sateliteVelocity) const
+{
+  if(m_SensorModel.get() == ITK_NULLPTR)
+    {
+      return false;
+    }
+
+  ossimGpt inGpt;
+  inGpt.lon = inGeoPoint[0];
+  inGpt.lat = inGeoPoint[1];
+  inGpt.hgt = inGeoPoint[2];
+  
+  ossimplugins::ossimSarSensorModel::TimeType azimuthTime;
+  double rangeTime;
+  ossimEcefPoint sensorPos;
+  ossimEcefVector sensorVel;
+
+  const bool success = m_SensorModel->worldToAzimuthRangeTime(inGpt, azimuthTime, rangeTime,sensorPos,sensorVel);
+  
+  if(sensorPos.isNan() || !success)
+    return false;
+
+  satelitePosition[0] = sensorPos.x();
+  satelitePosition[1] = sensorPos.y();
+  satelitePosition[2] = sensorPos.z();
+
+  sateliteVelocity[0] = sensorVel.x();
+  sateliteVelocity[1] = sensorVel.y();
+  sateliteVelocity[2] = sensorVel.z();    
+
+  return true;
+}
 
 
 } // namespace otb
diff --git a/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt b/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt
index 54a7117fc93c342e11d0e77b2b5226c70c0104cc..8dadc14ff05f911b3fa0af4cca37e05592cecced 100644
--- a/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt
+++ b/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt
@@ -31,6 +31,7 @@ otbGeometricSarSensorModelAdapter.cxx
 otbPlatformPositionAdapter.cxx
 otbDEMHandlerTest.cxx
 otbRPCSolverAdapterTest.cxx
+otbSarSensorModelAdapterTest.cxx
 )
 
 add_executable(otbOSSIMAdaptersTestDriver ${OTBOSSIMAdaptersTests})
@@ -499,3 +500,8 @@ otb_add_test(NAME uaTvRPCSolverAdapterValidationTest COMMAND otbOSSIMAdaptersTes
   ${INPUTDATA}/DEM/egm96.grd
   )
 
+
+otb_add_test(NAME uaTvSarSensorModelAdapter COMMAND otbOSSIMAdaptersTestDriver
+  otbSarSensorModelAdapterTest
+  ${INPUTDATA}/s1a-iw1-slc-vh-amp_xt.geom
+  )
diff --git a/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx b/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx
index 911e57e671884e9bb003e399b605b6dfd3dacf29..5f7295d6dffdb208aafde1ab1326ecdd544bd24f 100644
--- a/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx
+++ b/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx
@@ -33,4 +33,5 @@ void RegisterTests()
   REGISTER_TEST(otbPlatformPositionComputeBaselineTest);
   REGISTER_TEST(otbDEMHandlerTest);
   REGISTER_TEST(otbRPCSolverAdapterTest);
+  REGISTER_TEST(otbSarSensorModelAdapterTest);
 }
diff --git a/Modules/Adapters/OSSIMAdapters/test/otbSarSensorModelAdapterTest.cxx b/Modules/Adapters/OSSIMAdapters/test/otbSarSensorModelAdapterTest.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d48f10066193796158002b55aba127b464814ccc
--- /dev/null
+++ b/Modules/Adapters/OSSIMAdapters/test/otbSarSensorModelAdapterTest.cxx
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <fstream>
+#include <iomanip>
+
+#include "otbSarSensorModelAdapter.h"
+#include "otbImageKeywordlist.h"
+
+
+int otbSarSensorModelAdapterTest(int itkNotUsed(argc), char* argv[])
+{
+  std::string infname = argv[1];
+
+  otb::SarSensorModelAdapter::Pointer sensorModel = otb::SarSensorModelAdapter::New();
+
+  auto kwl = otb::ReadGeometryFromGEOMFile(infname);
+
+  bool success = sensorModel->LoadState(kwl);
+
+  if(!success)
+    {
+    std::cerr<<"Could not LoadState() from keyword list read from"<<infname<<std::endl;
+    return EXIT_FAILURE;
+    }
+
+  std::vector<std::pair<unsigned long, unsigned long> > lines;
+  success = sensorModel->Deburst(lines);
+
+  if(!success)
+    {
+    std::cerr<<"Deburst() call failed."<<std::endl;
+    return EXIT_FAILURE;
+    }
+  
+
+  otb::ImageKeywordlist outKwl;
+  success = sensorModel->SaveState(outKwl);
+  if(!success)
+    {
+    std::cerr<<"SaveState() call failed."<<std::endl;
+    return EXIT_FAILURE;
+    }
+  
+
+  otb::SarSensorModelAdapter::Point2DType out1,out2;
+  otb::SarSensorModelAdapter::Point3DType in, out3, out4, out5;
+
+  // GCP 99 from input geom file
+  //support_data.geom.gcp[99].world_pt.hgt:  2.238244926818182e+02
+  //support_data.geom.gcp[99].world_pt.lat:  4.323458093295080e+01
+  //support_data.geom.gcp[99].world_pt.lon:  1.116316013091967e+00
+    
+  in[0] = 4.323458093295080e+01;
+  in[1] = 1.116316013091967e+00;
+  in[2] = 2.238244926818182e+02;
+
+  sensorModel->WorldToLineSample(in,out1);
+  sensorModel->WorldToLineSampleYZ(in,out1,out2);
+
+  sensorModel->WorldToCartesian(in, out5);
+  sensorModel->WorldToSatPositionAndVelocity(in,out3, out4);
+  
+  
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx
index ff4f4b01e4be8c30476b4aef78dadaf9819e606f..4a35145462f48ac18220bafc08c5ab2998426f35 100644
--- a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx
+++ b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx
@@ -76,7 +76,7 @@ private:
     SetDocName("Polygon Class Statistics");
     SetDocLongDescription("The application processes a set of geometries "
       "intended for training (they should have a field giving the associated "
-      "class). The geometries are analysed against a support image to compute "
+      "class). The geometries are analyzed against a support image to compute "
       "statistics : \n"
       "  - number of samples per class\n"
       "  - number of samples per geometry\n"
@@ -92,17 +92,17 @@ private:
 
     AddDocTag(Tags::Learning);
 
-    AddParameter(ParameterType_InputImage,  "in",   "InputImage");
+    AddParameter(ParameterType_InputImage,  "in",   "Input image");
     SetParameterDescription("in", "Support image that will be classified");
 
-    AddParameter(ParameterType_InputImage,  "mask",   "InputMask");
+    AddParameter(ParameterType_InputImage,  "mask",   "Input validity mask");
     SetParameterDescription("mask", "Validity mask (only pixels corresponding to a mask value greater than 0 will be used for statistics)");
     MandatoryOff("mask");
     
     AddParameter(ParameterType_InputFilename, "vec", "Input vectors");
-    SetParameterDescription("vec","Input geometries to analyse");
+    SetParameterDescription("vec","Input geometries to analyze");
     
-    AddParameter(ParameterType_OutputFilename, "out", "Output Statistics");
+    AddParameter(ParameterType_OutputFilename, "out", "Output XML statistics file");
     SetParameterDescription("out","Output file to store statistics (XML format)");
 
     AddParameter(ParameterType_ListView, "field", "Field Name");
@@ -155,6 +155,22 @@ private:
           }
         }
       }
+
+     // Check that the extension of the output parameter is XML (mandatory for
+     // StatisticsXMLFileWriter)
+     // Check it here to trigger the error before polygons analysis
+     
+     if ( HasValue("out") )
+       {
+       // Store filename extension
+       // Check that the right extension is given : expected .xml
+       const std::string extension = itksys::SystemTools::GetFilenameLastExtension(this->GetParameterString("out"));
+
+       if (itksys::SystemTools::LowerCase(extension) != ".xml")
+         {
+         otbAppLogFATAL( << extension << " is a wrong extension for parameter \"out\": Expected .xml" );
+         }
+       }
   }
 
   void DoExecute() ITK_OVERRIDE
@@ -223,7 +239,7 @@ private:
   filter->SetLayerIndex(this->GetParameterInt("layer"));
   filter->GetStreamer()->SetAutomaticAdaptativeStreaming(GetParameterInt("ram"));
 
-  AddProcess(filter->GetStreamer(),"Analyse polygons...");
+  AddProcess(filter->GetStreamer(),"Analyze polygons...");
   filter->Update();
   
   FilterType::ClassCountMapType &classCount = filter->GetClassCountOutput()->Get();
diff --git a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
index 54dbe894f6520795efb9066b3d1546f89c991cd8..c853f4863b75e799d10a1199098cffae48640792 100644
--- a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
+++ b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx
@@ -264,7 +264,7 @@ private:
       {
       // fft ttransform
       bool shift = IsParameterEnabled( "mode.fft.shift");
-      typedef otb::Image< std::complex<OutputPixelType> >          ComplexOutputImageType;
+      typedef otb::Image< std::complex<OutputPixelType> > ComplexOutputImageType;
 
       if (dir == 0 )
         {
diff --git a/Modules/Applications/AppImageUtils/test/CMakeLists.txt b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
index d2852f4d46be0c1a130e293c101fdd1934e60aae..d428cc87bbeae493384dbbc4be46fb87b0807cc7 100644
--- a/Modules/Applications/AppImageUtils/test/CMakeLists.txt
+++ b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
@@ -173,6 +173,14 @@ otb_test_application(NAME apTvUtExtractROIRightInputFile
                              ${INPUTDATA}/couleurs_extrait.png
                              ${TEMP}/apTvUtExtractROIRightInputFile.tif)
 
+otb_test_application(NAME apTvUtExtractROIComplexInputFile
+                     APP  ExtractROI
+                     OPTIONS -in ${INPUTDATA}/complexInputCfloat.tif
+                             -out ${TEMP}/apTvUtExtractROIComplexInputFile.tif cfloat
+                     VALID   --compare-image ${NOTOL}
+                             ${INPUTDATA}/complexInputCfloat.tif
+                             ${TEMP}/apTvUtExtractROIComplexInputFile.tif)
+
 
 #----------- Rescale TESTS ----------------
 otb_test_application(NAME  apTvUtRescaleTest
@@ -207,6 +215,11 @@ otb_test_application(NAME apTuUtReadImageInfoExtendedFilename_reader
                      OPTIONS -in ${INPUTDATA}/ToulouseExtract_WithGeom.tif?&skipgeom=true&skipcarto=true
                      )
 
+otb_test_application(NAME apTuUtReadComplexImageInfoFilename_reader
+                     APP  ReadImageInfo
+                     OPTIONS -in ${INPUTDATA}/complexInputCfloat.tif
+                     )
+
 
 set(TESTNAME
 "gd-pleiades-1" #LARGEINPUT{PLEIADES/TLSE_JP2_DIMAPv2_PRIMARY_PMS_lossless_12bits/IMGPHR_201222215194743808/IMG_PHR1A_PMS_201201151100183_SEN_IPU_20120222_0901-001_R1C1.JP2}
diff --git a/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx b/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx
index 87e7dc310fa0cc14efda2c900c0b29942d3feb11..829c4f3052c9d95683dd55b0d62b28d5bd1f14f9 100644
--- a/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx
+++ b/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx
@@ -29,7 +29,7 @@
 #include "otbReflectanceToRadianceImageFilter.h"
 #include "otbReflectanceToSurfaceReflectanceImageFilter.h"
 #include "itkMultiplyImageFilter.h"
-#include "otbClampVectorImageFilter.h"
+#include "otbClampImageFilter.h"
 #include "otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h"
 #include "otbGroundSpacingImageFunction.h"
 #include "vnl/vnl_random.h"
@@ -92,7 +92,7 @@ public:
 
   typedef itk::MultiplyImageFilter<DoubleVectorImageType,DoubleImageType,DoubleVectorImageType>         ScaleFilterOutDoubleType;
 
-  typedef otb::ClampVectorImageFilter<DoubleVectorImageType,
+  typedef otb::ClampImageFilter<DoubleVectorImageType,
                                       DoubleVectorImageType>              ClampFilterType;
 
   typedef ReflectanceToSurfaceReflectanceImageFilter<DoubleVectorImageType,
diff --git a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
index 4a91dda2f5183e34a8bd470684302805b54d5609..751678774184b69c0d048d18f906c2ecdb55694c 100644
--- a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
+++ b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx
@@ -60,7 +60,7 @@ private:
     AddDocTag(Tags::Calibration);
     AddDocTag(Tags::SAR);
 
-    AddParameter(ParameterType_ComplexInputImage,  "in", "Input Image");
+    AddParameter(ParameterType_InputImage,  "in", "Input Image");
     SetParameterDescription("in", "Input complex image");
 
     AddParameter(ParameterType_OutputImage,  "out", "Output Image");
diff --git a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
index 155795417f8c78b96317cd7676e4ed1294be90b4..796d3f4e26a9fd34b7e7891f81846dab6fa95c2a 100644
--- a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
+++ b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
@@ -31,7 +31,7 @@
 #include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
 #include "otbPerBandVectorImageFilter.h"
 #include "itkMeanImageFilter.h"
-#include "otbNRIBandImagesToOneNComplexBandsImage.h"
+// #include "otbNRIBandImagesToOneNComplexBandsImage.h"
 #include "otbImageListToVectorImageFilter.h"
 #include "otbImageList.h"
 
@@ -109,21 +109,21 @@ private:
 
     AddDocTag(Tags::SAR);
 
-    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input Image");
+    AddParameter(ParameterType_InputImage,  "inhh",   "Input Image");
     SetParameterDescription("inhh", "Input image (HH)");
     
-    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input Image");
+    AddParameter(ParameterType_InputImage,  "inhv",   "Input Image");
     SetParameterDescription("inhv", "Input image (HV)");
     MandatoryOff("inhv");
     
-    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input Image");
+    AddParameter(ParameterType_InputImage,  "invh",   "Input Image");
     SetParameterDescription("invh", "Input image (VH)");
     MandatoryOff("invh");
     
-    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input Image");
+    AddParameter(ParameterType_InputImage,  "invv",   "Input Image");
     SetParameterDescription("invv", "Input image (VV)");
     
-    AddParameter(ParameterType_ComplexOutputImage, "out",  "Output Image");
+    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
     SetParameterDescription("out", "Output image");
     
     AddParameter(ParameterType_Choice, "decomp", "Decompositions");
@@ -201,7 +201,7 @@ private:
 		
 		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
 		m_HAFilter->SetInput(m_MeanFilter->GetOutput());
-		SetParameterComplexOutputImage("out", m_HAFilter->GetOutput() );
+		SetParameterOutputImage("out", m_HAFilter->GetOutput() );
     
 		break;
         
@@ -220,7 +220,7 @@ private:
 		
 		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
 		m_BarnesFilter->SetInput(m_MeanFilter->GetOutput());
-		SetParameterComplexOutputImage("out", m_BarnesFilter->GetOutput() );
+		SetParameterOutputImage("out", m_BarnesFilter->GetOutput() );
     
 		break;
         
@@ -239,7 +239,7 @@ private:
 		
 		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
 		m_HuynenFilter->SetInput(m_MeanFilter->GetOutput());
-		SetParameterComplexOutputImage("out", m_HuynenFilter->GetOutput() );
+		SetParameterOutputImage("out", m_HuynenFilter->GetOutput() );
     
 		break;
         
@@ -257,7 +257,7 @@ private:
         m_Concatener->SetInput( m_ImageList );        
         m_PauliFilter->SetInput(m_Concatener->GetOutput());
         
-		SetParameterComplexOutputImage("out", m_PauliFilter->GetOutput() );
+		SetParameterOutputImage("out", m_PauliFilter->GetOutput() );
     
 		break;
 	  }
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
index 9c8c06211234eef4f9f8207c1762e6f10fbe88fb..657643541d477617e13a196a4a2853f76920f569 100644
--- a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
@@ -232,7 +232,7 @@ private:
 
     AddDocTag(Tags::SAR);
 
-    AddParameter(ParameterType_ComplexInputImage,  "inc",   "Input : multi-band complex image");
+    AddParameter(ParameterType_InputImage,  "inc",   "Input : multi-band complex image");
     SetParameterDescription("inc", "Input : multi-band complex image");
     MandatoryOff("inc");
     
@@ -241,23 +241,23 @@ private:
     MandatoryOff("inf");
 
 
-    AddParameter(ParameterType_ComplexInputImage,  "inhh",   "Input : one-band complex image (HH)");
+    AddParameter(ParameterType_InputImage,  "inhh",   "Input : one-band complex image (HH)");
     SetParameterDescription("inhh", "Input : one-band complex image (HH)");
     MandatoryOff("inhh");
     
-    AddParameter(ParameterType_ComplexInputImage,  "inhv",   "Input : one-band complex image (HV)");
+    AddParameter(ParameterType_InputImage,  "inhv",   "Input : one-band complex image (HV)");
     SetParameterDescription("inhv", "Input : one-band complex image (HV)");
     MandatoryOff("inhv");
     
-    AddParameter(ParameterType_ComplexInputImage,  "invh",   "Input : one-band complex image (VH)");
+    AddParameter(ParameterType_InputImage,  "invh",   "Input : one-band complex image (VH)");
     SetParameterDescription("invh", "Input : one-band complex image (VH)");
     MandatoryOff("invh");
     
-    AddParameter(ParameterType_ComplexInputImage,  "invv",   "Input : one-band complex image (VV)");
+    AddParameter(ParameterType_InputImage,  "invv",   "Input : one-band complex image (VV)");
     SetParameterDescription("invv", "Input : one-band complex image (VV)");
     MandatoryOff("invv");
     
-    AddParameter(ParameterType_ComplexOutputImage, "outc",  "Output Complex Image");
+    AddParameter(ParameterType_OutputImage, "outc",  "Output Complex Image");
     SetParameterDescription("outc", "Output Complex image.");
     MandatoryOff("outc");
     
@@ -509,7 +509,7 @@ private:
 		m_RCohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterComplexOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
 		
 		break;
 
@@ -526,7 +526,7 @@ private:
 		m_RCovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterComplexOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
 		
 		break;
 		
@@ -544,7 +544,7 @@ private:
 		m_RCCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
 		m_RCCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterComplexOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
+		SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output :  6 complex channels
 		
 		break;
 		
@@ -565,7 +565,7 @@ private:
 		m_RCCDFilter = RCCDFilterType::New();
 		m_RCCDFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterComplexOutputImage("outc", m_RCCDFilter->GetOutput() ); // input : 6 complex channels | 3 complex channels
+		SetParameterOutputImage("outc", m_RCCDFilter->GetOutput() ); // input : 6 complex channels | 3 complex channels
 		
 		break;
 
@@ -575,7 +575,7 @@ private:
 		m_RCRCFilter = RCRCFilterType::New();
 		m_RCRCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterComplexOutputImage("outc", m_RCRCFilter->GetOutput() ); // input : 6 complex channels | 6 complex channels
+		SetParameterOutputImage("outc", m_RCRCFilter->GetOutput() ); // input : 6 complex channels | 6 complex channels
 		
 		break;
 		
@@ -586,7 +586,7 @@ private:
 		m_RLCRCCFilter = RLCRCCFilterType::New();
 		m_RLCRCCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
 		
-		SetParameterComplexOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input : 6 complex channels | output : 6 complex channels
+		SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input : 6 complex channels | output : 6 complex channels
 		
 		break;
 		
@@ -597,7 +597,7 @@ private:
 		
 		m_MRCFilter->SetInput(GetParameterDoubleVectorImage("inf"));
 		
-		SetParameterComplexOutputImage("outc", m_MRCFilter->GetOutput() ); // input : 16 real channels | output : 6 complex channels
+		SetParameterOutputImage("outc", m_MRCFilter->GetOutput() ); // input : 16 real channels | output : 6 complex channels
 		
 		break;
 		
@@ -615,7 +615,7 @@ private:
 		m_CohSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterComplexOutputImage("outc", m_CohSRFilter->GetOutput() ); // input : 4 x 1 complex channel | 10 complex channels
+		SetParameterOutputImage("outc", m_CohSRFilter->GetOutput() ); // input : 4 x 1 complex channel | 10 complex channels
 		
 		break;
 		
@@ -630,7 +630,7 @@ private:
 		m_CovSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterComplexOutputImage("outc", m_CovSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		SetParameterOutputImage("outc", m_CovSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
 		
 		break;
 		
@@ -644,7 +644,7 @@ private:
 		m_CCSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
 		m_CCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
 		
-		SetParameterComplexOutputImage("outc", m_CCSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
+		SetParameterOutputImage("outc", m_CCSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels
 		
 		break;
 		
diff --git a/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
index 236ac0789fa1e8e2077e9903bcc5c4c0e8aa9733..3db956847e1dba701365e3c1823e8d5370525063 100644
--- a/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
+++ b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx
@@ -86,7 +86,7 @@ private:
 
     AddDocTag(Tags::SAR);
 
-    AddParameter(ParameterType_ComplexInputImage,  "in",   "Input Image");
+    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
     SetParameterDescription("in", "Input image.");
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
     SetParameterDescription("out", "Output image.");
diff --git a/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx b/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx
index 39db311e799737b730973d68c5156d273366896b..ec91b7e53b6c04b398a1e3d854475758d1f9d21e 100644
--- a/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx
+++ b/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx
@@ -75,7 +75,7 @@ private:
     AddDocTag(Tags::SAR);
     AddDocTag(Tags::Manip);
     // Input images
-    AddParameter(ParameterType_ComplexInputImage,  "in",   "Input Image");
+    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
     SetParameterDescription("in", "Input image (complex single band)");
 
     // Outputs
@@ -110,7 +110,7 @@ private:
     m_Modulus = ModulusFilterType::New();
     m_Phase = PhaseFilterType::New();
 
-    ComplexFloatVectorImageType::Pointer inImage = GetParameterComplexImage("in");
+    ComplexFloatVectorImageType::Pointer inImage = GetParameterComplexFloatVectorImage("in");
 
     if (inImage->GetNumberOfComponentsPerPixel() != 1)
     {
diff --git a/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h b/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h
index 3339a54a1a39b6be9d8ddd5dc17a757289a87213..be11633e7b98a62cded643e040e26aa76abd5d4c 100644
--- a/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h
+++ b/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h
@@ -1,5 +1,4 @@
 /*
- * Copyright (C) 1999-2011 Insight Software Consortium
  * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
  *
  * This file is part of Orfeo Toolbox
@@ -19,322 +18,67 @@
  * limitations under the License.
  */
 
-
 #ifndef otbDefaultConvertPixelTraits_h
 #define otbDefaultConvertPixelTraits_h
 
-#include "itkOffset.h"
-#include "itkVector.h"
-#include "itkMatrix.h"
+#include "itkDefaultConvertPixelTraits.h"
 
-namespace otb
+namespace otb 
 {
 
-/** \class DefaultConvertPixelTraits
- *  \brief Traits class used to by ConvertPixels to convert blocks of pixels.
- *
- *  TOutputPixelType is the destination type. The input type is inferred
- *  by the templated static function Convert.
- *
- *  This implementation does a simple assignment operator, so if you are
- *  going from a higher bit representation to a lower bit one (int to
- *  char), you may want to specialize and add some sort of transfer function.
- *
- * \ingroup OTBImageBase
- */
-template<typename PixelType>
-class DefaultConvertPixelTraits
+
+template < typename PixelType>
+class DefaultConvertPixelTraits 
+: public itk::DefaultConvertPixelTraits < PixelType >
 {
 public:
-  /** Determine the pixel data type. */
-  typedef typename PixelType::ComponentType ComponentType;
-
-  /** Return the number of components per pixel. */
-  static unsigned int GetNumberOfComponents()
-  { return PixelType::GetNumberOfComponents(); }
-
-  /** Return the nth component of the pixel. */
-  static ComponentType GetNthComponent(int c, const PixelType& pixel)
-  { return pixel.GetNthComponent(c); }
-
-  /** Set the nth component of the pixel. */
-  static void SetNthComponent(int c, PixelType& pixel, const ComponentType& v)
-  { pixel.SetNthComponent(c, v); }
-  static void SetNthComponent(int itkNotUsed(c), PixelType & pixel, const PixelType& v)
-  { pixel = v; }
+  typedef itk::DefaultConvertPixelTraits < PixelType > SuperClass;
+  using typename SuperClass::ComponentType;
 
-  /** Return a single scalar value from this pixel. */
-  static ComponentType GetScalarValue(const PixelType& pixel)
-  { return pixel.GetScalarValue(); }
+  using SuperClass::SetNthComponent;
 
+  static void SetNthComponent(int , PixelType & pixel, const PixelType & v)
+    {
+      pixel = v;
+    }  
 };
 
-#define OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(type)                    \
-template<>                                                               \
-class DefaultConvertPixelTraits<type>                                    \
-{                                                                        \
-public:                                                                  \
-  typedef type ComponentType;                                            \
-  static unsigned int GetNumberOfComponents()                            \
-    {                                                                    \
-      return 1;                                                          \
-    }                                                                    \
-  static void SetNthComponent(int , type& pixel, const ComponentType& v) \
-    {                                                                    \
-      pixel = v;                                                         \
-    }                                                                    \
-  static type GetScalarValue(const type& pixel)                          \
-    {                                                                    \
-      return pixel;                                                      \
-    }                                                                    \
-};
-
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(float)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(double)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(int)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(char)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(short)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned int)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(signed char)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned char)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned short)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(long)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned long)
-OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(bool)
-
-#undef OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL
-
-//
-//  Default traits for the Offset<> pixel type
-//
+template < typename T >
+class DefaultConvertPixelTraits < ::std::complex < T > > 
+: public itk::DefaultConvertPixelTraits < ::std::complex < T > >
+{
+public:
 
-#define OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(dimension)                  \
-template<>                                                               \
-class DefaultConvertPixelTraits< itk::Offset<dimension> >                \
-{                                                                        \
-public:                                                                  \
-  typedef itk::Offset<dimension>  TargetType;                            \
-  typedef TargetType::OffsetValueType  ComponentType;                    \
-  static unsigned int GetNumberOfComponents()                            \
-    {                                                                    \
-      return dimension;                                                  \
-    }                                                                    \
-  static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)   \
-    {                                                                    \
-      pixel[i] = v;                                                      \
-    }                                                                    \
-  static void SetNthComponent(int , TargetType & pixel, const TargetType& v)   \
-    {                                                                    \
-      pixel = v;                                                         \
-    }                                                                    \
-  static ComponentType GetScalarValue(const TargetType& pixel)           \
-    {                                                                    \
-      return pixel[0];                                                   \
-    }                                                                    \
+  typedef itk::DefaultConvertPixelTraits < ::std::complex < T > > SuperClass;
+  using typename SuperClass::TargetType ;
+  using typename SuperClass::ComponentType ;
+
+  using SuperClass::SetNthComponent ;
+
+  static void SetNthComponent(int , TargetType & pixel, const TargetType & v)
+    {
+      pixel = v;
+    }
+
+  static TargetType GetNthComponent ( int , const TargetType & pixel )
+    {
+    return pixel;
+    }
+
+  static ComponentType GetScalarValue(const TargetType& pixel)
+    {
+       /*
+       * This seems to be dead code, since the complex to scalar
+       * conversion is done by ConvertPixelBuffer
+       *
+       * Historically, it was returning std::norm, which causes
+       * compilation error on MacOSX 10.9.
+       * Now returns the equivalent implementation of std::norm.
+       */
+      return static_cast<ComponentType>( pixel.real()*pixel.real()
+                                         + pixel.imag()*pixel.imag() );
+    }
 };
 
-
-// Define traits for Offset<> from dimensions 1 to 5
-  OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(1)
-  OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(2)
-  OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(3)
-  OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(4)
-  OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(5)
-
-//
-//  Default traits for the pixel types deriving from FixedArray<>
-//
-
-#define OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(type,componenttype, dimension) \
-template<>                                                               \
-class DefaultConvertPixelTraits< type< componenttype, dimension> >       \
-{                                                                        \
-public:                                                                  \
-  typedef type< componenttype, dimension >  TargetType;                  \
-  typedef componenttype                     ComponentType;               \
-  static unsigned int GetNumberOfComponents()                            \
-    {                                                                    \
-      return dimension;                                                  \
-    }                                                                    \
-  static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)   \
-    {                                                                    \
-      pixel[i] = v;                                                      \
-    }                                                                    \
-  static void SetNthComponent(int , TargetType & pixel, const TargetType& v)   \
-    {                                                                    \
-      pixel = v;                                                      \
-    }                                                                    \
-  static ComponentType GetScalarValue(const TargetType& pixel)           \
-    {                                                                    \
-      return pixel[0];                                                   \
-    }                                                                    \
-};                                                                       \
-
-//
-//
-// Define traits for Classed deriving from FixedArray from dimensions 1 to 6
-// These classes include: Vector, CovariantVector and Point.
-//
-//
-#define OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, Type) \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,1) \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,2) \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,3) \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,4) \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,5) \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,6)
-
-#define OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(ArrayType) \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, char); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, signed char); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned char); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, short); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned short); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, int); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned int); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, long); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned long); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, float); \
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, double);
-
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::Vector);
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::CovariantVector);
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::Point);
-  OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::FixedArray);
-
-//
-//  End of Traits for the classes deriving from FixedArray.
-//
-//
-
-
-//
-//  Default traits for the pixel types deriving from Matrix<>
-//
-
-#define OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(type,componenttype,rows,cols) \
-template<>                                                               \
-class DefaultConvertPixelTraits< type< componenttype, rows, cols > >     \
-{                                                                        \
-public:                                                                  \
-  typedef type< componenttype, rows, cols >  TargetType;                 \
-  typedef componenttype                     ComponentType;               \
-  static unsigned int GetNumberOfComponents()                            \
-    {                                                                    \
-      return rows * cols;                                                \
-    }                                                                    \
-  static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v)   \
-    {                                                                    \
-      const unsigned int row = i / cols;                                 \
-      const unsigned int col = i % cols;                                 \
-      pixel[row][col] = v;                                               \
-    }                                                                    \
-  static void SetNthComponent(int , TargetType & pixel, const TargetType& v)   \
-    {                                                                    \
-      pixel = v;                                               \
-    }                                                                    \
-  static ComponentType GetScalarValue(const TargetType& pixel)           \
-    {                                                                    \
-      return pixel[0][0];                                                \
-    }                                                                    \
-};                                                                       \
-
-//
-//
-// Define traits for Classed deriving from Matrix from dimensions 1 to 6
-//
-//
-#define OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, Type) \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,1,1) \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,2,2) \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,3,3) \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,4,4) \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,5,5) \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,6,6)
-
-#define OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(ArrayType) \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, char); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, signed char); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned char); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, short); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned short); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, int); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned int); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, long); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned long); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, float); \
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, double);
-
-//
-// Add here other classes that derive from Matrix or that have the same API
-//
-  OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(itk::Matrix);
-
-//
-//  End of Traits for the classes deriving from Matrix.
-//
-//
-
-
-//
-//  Default traits for the pixel types deriving from std::complex<>
-//
-
-#define OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE( componenttype )                   \
-template<>                                                                       \
-class DefaultConvertPixelTraits< ::std::complex< componenttype > >               \
-{                                                                                \
-public:                                                                          \
-  typedef ::std::complex< componenttype>  TargetType;                            \
-  typedef componenttype                     ComponentType;                       \
-  static unsigned int GetNumberOfComponents()                                    \
-    {                                                                            \
-    return 2;                                                                    \
-    }                                                                            \
-  static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v) \
-    {                                                                            \
-    if( i == 0 )                                                                 \
-      {                                                                          \
-      pixel = TargetType( v, pixel.imag() );                                     \
-      }                                                                          \
-    else                                                                         \
-      {                                                                          \
-      pixel = TargetType( pixel.real(), v );                                     \
-      }                                                                          \
-    }                                                                            \
-  static void SetNthComponent(int , TargetType & pixel, const TargetType& v)     \
-    {                                                                            \
-      pixel = v;                                                                 \
-    }                                                                            \
-  static ComponentType GetScalarValue(const TargetType& pixel)                   \
-    {                                                                            \
-      /*                                                                         \
-       * This seems to be dead code, since the complex to scalar                 \
-       * conversion is done by ConvertPixelBuffer                                \
-       *                                                                         \
-       * Historically, it was returning std::norm, which causes                  \
-       * compilation error on MacOSX 10.9.                                       \
-       * Now returns the equivalent implementation of std::norm.                 \
-       */                                                                        \
-      return static_cast<ComponentType>( pixel.real()*pixel.real()               \
-                                         + pixel.imag()*pixel.imag() );          \
-    }                                                                            \
-};                                                                               \
-
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(float);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(double);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed int);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned int);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(short int);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed char);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned char);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed long);
-OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned long);
-
-//
-//  End of Traits for the classes deriving from std::complex.
-//
-//
-
-} // end namespace otb
+} // end namespace
 #endif
diff --git a/Modules/Core/ObjectList/include/otbImageList.h b/Modules/Core/ObjectList/include/otbImageList.h
index 611d84a47a18efdb93a79085fa4a764968338ddf..4cb77bddec306437bccb05b45b81bdf71c9b9610 100644
--- a/Modules/Core/ObjectList/include/otbImageList.h
+++ b/Modules/Core/ObjectList/include/otbImageList.h
@@ -68,6 +68,8 @@ public:
     throw (itk::InvalidRequestedRegionError) ITK_OVERRIDE;
   void UpdateOutputData(void) ITK_OVERRIDE;
 
+  void SetRequestedRegion(const itk::DataObject * source);
+  
 protected:
   /** Constructor */
   ImageList() {};
diff --git a/Modules/Core/ObjectList/include/otbImageList.txx b/Modules/Core/ObjectList/include/otbImageList.txx
index dc0cbc9b6fef35e3430891fb9cd08a7e4324aefd..dec0ab8b3e5ce3a834ee5a6dc9a247831d432f5b 100644
--- a/Modules/Core/ObjectList/include/otbImageList.txx
+++ b/Modules/Core/ObjectList/include/otbImageList.txx
@@ -39,10 +39,32 @@ ImageList<TImage>
         || it.Get()->GetDataReleased()
         || it.Get()->RequestedRegionIsOutsideOfTheBufferedRegion())
       {
+      if(it.Get()->GetSource())
+        {
+        it.Get()->GetSource()->UpdateOutputData(it.Get());
+        }
+      }
+    }
+}
+
+template <class TImage>
+void
+ImageList<TImage>
+::PropagateRequestedRegion() throw (itk::InvalidRequestedRegionError)
+  {
+  Superclass::PropagateRequestedRegion();
+
+  for (ConstIterator it = this->Begin(); it != this->End(); ++it)
+    {
+    if (it.Get()->GetUpdateMTime() < it.Get()->GetPipelineMTime()
+        || it.Get()->GetDataReleased()
+        || it.Get()->RequestedRegionIsOutsideOfTheBufferedRegion())
+      {
+
       if (it.Get()->GetSource())
         {
         it.Get()->GetSource()->PropagateRequestedRegion(it.Get());
-
+        
         // Check that the requested region lies within the largest possible region
         if (!it.Get()->VerifyRequestedRegion())
           {
@@ -51,23 +73,24 @@ ImageList<TImage>
           e.SetLocation(ITK_LOCATION);
           e.SetDataObject(it.Get());
           e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
-
+          
           throw e;
           }
-
-        it.Get()->GetSource()->UpdateOutputData(it.Get());
         }
       }
     }
-}
+  }
 
-template <class TImage>
+template<class TImage>
 void
 ImageList<TImage>
-::PropagateRequestedRegion() throw (itk::InvalidRequestedRegionError)
-  {
-  Superclass::PropagateRequestedRegion();
-  }
+::SetRequestedRegion(const itk::DataObject * source)
+{
+  for (ConstIterator it = this->Begin(); it != this->End(); ++it)
+    {
+    it.Get()->SetRequestedRegion(source);
+    }
+}
 
 template <class TImage>
 void
diff --git a/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h b/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h
index 826478711d24b2c9ab3ac7e75d4e8586354c8afb..41fe7808e9d84a0d0ae3017996e417ea0cd97c3a 100644
--- a/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h
+++ b/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h
@@ -121,7 +121,7 @@ public:
   static const double MegabyteToByte;
 
   /** Evaluate the print (in bytes) of a single data object */
-  MemoryPrintType EvaluateDataObjectPrint(DataObjectType * data) const;
+  MemoryPrintType EvaluateDataObjectPrint(DataObjectType * data);
 
 protected:
   /** Constructor */
diff --git a/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx b/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx
index 033c58bc379fed6aba092e28e346b1d58ab35b84..d7d62e8c88cd6a779425feb92d5c9eeea7a71497 100644
--- a/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx
+++ b/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx
@@ -162,7 +162,7 @@ PipelineMemoryPrintCalculator
 
 PipelineMemoryPrintCalculator::MemoryPrintType
 PipelineMemoryPrintCalculator
-::EvaluateDataObjectPrint(DataObjectType * data) const
+::EvaluateDataObjectPrint(DataObjectType * data)
 {
   otbMsgDevMacro(<< "EvaluateMemoryPrint for " << data->GetNameOfClass() << " (" << data << ")")
 
@@ -183,11 +183,13 @@ PipelineMemoryPrintCalculator
     {                                                                   \
     ImageList<Image<type, 2> > * imageList = dynamic_cast<otb::ImageList<otb::Image<type, 2> > *>(data); \
     MemoryPrintType print(0);                                         \
-    for(ImageList<Image<type, 2> >::ConstIterator it = imageList->Begin(); \
+    for(ImageList<Image<type, 2> >::Iterator it = imageList->Begin(); \
        it != imageList->End(); ++it)                                    \
        {                                                             \
-       print += it.Get()->GetRequestedRegion().GetNumberOfPixels()   \
-       * it.Get()->GetNumberOfComponentsPerPixel() * sizeof(type); \
+       if(it.Get()->GetSource())                                        \
+         print += this->EvaluateProcessObjectPrintRecursive(it.Get()->GetSource());\
+       else                                                             \
+         print += this->EvaluateDataObjectPrint(it.Get());              \
        }                                                           \
     return print;                                                  \
     }                                                              \
@@ -198,8 +200,10 @@ PipelineMemoryPrintCalculator
     for(ImageList<VectorImage<type, 2> >::ConstIterator it = imageList->Begin(); \
        it != imageList->End(); ++it)                                    \
        {                                                             \
-       print += it.Get()->GetRequestedRegion().GetNumberOfPixels()   \
-       * it.Get()->GetNumberOfComponentsPerPixel() * sizeof(type); \
+       if(it.Get()->GetSource())                                        \
+         print += this->EvaluateProcessObjectPrintRecursive(it.Get()->GetSource());\
+       else                                                             \
+         print += this->EvaluateDataObjectPrint(it.Get());              \
        }                                                           \
     return print;                                                  \
     }                                                              \
diff --git a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h
index 6fdd16e955a3b7a754779b6d1acd76de60e711d8..478eb952220a8cf08eed6b8550114d2053ba2ccd 100644
--- a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h
@@ -21,121 +21,104 @@
 #ifndef otbClampImageFilter_h
 #define otbClampImageFilter_h
 
-#include "itkImageToImageFilter.h"
+#include "otbConvertTypeFunctor.h"
+#include "itkUnaryFunctorImageFilter.h"
 
 namespace otb
 {
 
 /** \class ClampImageFilter
- * \brief Set image values to a user-specified value if they are below,
- * above, or between simple threshold values.
+ * \brief Clamp image values to be below, over, or between threhold values.
  *
  * ClampImageFilter  clamp image values to be between an upper
  * and lower value. Values lower than m_Lower values are set to lower,
  * and values greater than upper threshold are set to upper threshold
  * value.
+ * This filter can also be used to cast any type of image into any other type
+ * as long as those types are arithmetics or complex.
  *
  * By default lower and upper thresholds are set to the maximum and
- * minimum bounds of the image pixel type.
- *
- * The pixels must support the operators >= and <=.
+ * minimum bounds of the image internal pixel value.
  *
  * \ingroup IntensityImageFilters Multithreaded
  *
  * \ingroup OTBImageManipulation
  */
   template <class TInputImage, class TOutputImage=TInputImage>
-  class ITK_EXPORT ClampImageFilter : public itk::ImageToImageFilter<TInputImage, TOutputImage>
+  class ITK_EXPORT ClampImageFilter 
+  : public itk::UnaryFunctorImageFilter< TInputImage , TOutputImage ,
+      Functor::ConvertTypeFunctor <typename TInputImage::PixelType ,
+                                   typename TOutputImage::PixelType> >
 {
 public:
   /** Standard class typedefs. */
-  typedef ClampImageFilter               Self;
-  typedef itk::ImageToImageFilter<TInputImage, TOutputImage>  Superclass;
-  typedef itk::SmartPointer<Self>                 Pointer;
-  typedef itk::SmartPointer<const Self>           ConstPointer;
+  typedef ClampImageFilter Self;
+  typedef itk::UnaryFunctorImageFilter< TInputImage , TOutputImage ,
+    Functor::ConvertTypeFunctor <typename TInputImage::PixelType ,
+                                 typename TOutputImage::PixelType> >  Superclass;
+  typedef itk::SmartPointer<Self> Pointer;
+  typedef itk::SmartPointer<const Self> ConstPointer;
 
   /** Method for creation through the object factory. */
-  itkNewMacro(Self);
+  itkNewMacro( Self );
 
   /** Run-time type information (and related methods). */
-  itkTypeMacro(ClampImageFilter, itk::ImageToImageFilter);
+  itkTypeMacro( ClampImageFilter , itk::UnaryFunctorImageFilter );
 
 
   /** Some additional typedefs.  */
   typedef TInputImage                                  InputImageType;
-  typedef typename InputImageType::ConstPointer        InputImagePointer;
   typedef typename InputImageType::RegionType          InputImageRegionType;
   typedef typename InputImageType::PixelType           InputImagePixelType;
 
   /** Some additional typedefs.  */
-  typedef TOutputImage                                 OutputImageType;
-  typedef typename OutputImageType::Pointer            OutputImagePointer;
-  typedef typename OutputImageType::RegionType         OutputImageRegionType;
-  typedef typename OutputImageType::PixelType          OutputImagePixelType;
+  typedef TOutputImage OutputImageType;
+  typedef typename OutputImageType::RegionType OutputImageRegionType;
+  typedef typename OutputImageType::PixelType OutputImagePixelType;
+  typedef typename OutputImageType::InternalPixelType OutputInternalPixelType;
+  typedef typename itk::NumericTraits< OutputInternalPixelType >::ValueType OutputPixelValueType;
 
 
-  /** The values greater than or equal to the value are set to OutsideValue. */
-  void ClampAbove(const OutputImagePixelType &thresh);
+  /** The values greater than or equal to the value are set to \p thresh. */
+  void ClampAbove(const OutputPixelValueType &thresh);
 
-  /** The values less than or equal to the value are set to OutsideValue. */
-  void ClampBelow(const OutputImagePixelType &thresh);
+  /** The values less than or equal to the value are set to \p thresh. */
+  void ClampBelow(const OutputPixelValueType &thresh);
 
-  /** The values outside the range are set to OutsideValue. */
-  void ClampOutside(const OutputImagePixelType &lower, const OutputImagePixelType &upper);
+  /** The values outside the range are set to \p lower or \p upper. */
+  void ClampOutside(const OutputPixelValueType &lower, const OutputPixelValueType &upper);
 
   /** Set/Get methods to set the lower threshold */
-  void SetLower(OutputImagePixelType val)
-  {
-    m_Lower = val;
-    m_DLower = static_cast<double>(val);
-    this->Modified();
-  }
-  itkGetConstMacro(Lower, OutputImagePixelType);
+  void SetLower(OutputPixelValueType val);
+
+  itkGetConstMacro(Lower, OutputPixelValueType);
 
   /** Set/Get methods to set the upper threshold */
-  void SetUpper(OutputImagePixelType val)
-  {
-    m_Upper = val;
-    m_DUpper = static_cast<double>(val);
-    this->Modified();
-  }
-  itkGetConstMacro(Upper, OutputImagePixelType);
+  void SetUpper(OutputPixelValueType val);
+
+  itkGetConstMacro(Upper, OutputPixelValueType);
 
 
 protected:
   ClampImageFilter();
-  ~ClampImageFilter() ITK_OVERRIDE {};
-  void PrintSelf(std::ostream& os, itk::Indent indent) const ITK_OVERRIDE;
-
-  /** ClampImageFilter can be implemented as a multithreaded filter.
-   * Therefore, this implementation provides a ThreadedGenerateData() routine
-   * which is called for each processing thread. The output image data is
-   * allocated automatically by the superclass prior to calling
-   * ThreadedGenerateData().  ThreadedGenerateData can only write to the
-   * portion of the output image specified by the parameter
-   * "outputRegionForThread"
-   *
-   * \sa ImageToImageFilter::ThreadedGenerateData(),
-   *     ImageToImageFilter::GenerateData()  */
-  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                            itk::ThreadIdType threadId ) ITK_OVERRIDE;
-
-  void GenerateOutputInformation(void) ITK_OVERRIDE
-  {
-    Superclass::GenerateOutputInformation();
+  ~ClampImageFilter() override {};
+  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
 
-    this->GetOutput()->SetNumberOfComponentsPerPixel( this->GetInput()->GetNumberOfComponentsPerPixel() );
-  }
+  void GenerateOutputInformation(void) override
+    {
+    Superclass::GenerateOutputInformation();
+    unsigned int sizeIn = this->GetInput()->GetNumberOfComponentsPerPixel();
+    this->GetFunctor().SetInputComponents( sizeIn );
+    this->GetOutput()->SetNumberOfComponentsPerPixel( 
+      this->GetFunctor().GetOutputSize () );
+    }
 
 private:
-  ClampImageFilter(const Self&); //purposely not implemented
-  void operator=(const Self&); //purposely not implemented
-
-  double m_DLower;
-  double m_DUpper;
+  ClampImageFilter(const Self&) = delete ;
+  void operator=(const Self&) = delete ;
 
-  OutputImagePixelType m_Lower;
-  OutputImagePixelType m_Upper;
+  OutputPixelValueType m_Lower;
+  OutputPixelValueType m_Upper;
 };
 
 
diff --git a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx
index fd1ed1320ec1cbe7768eb8ccb44f7b9ba317d8f9..b1ac37e2e3df315e4b2e402f9034a73ef25a4665 100644
--- a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx
+++ b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx
@@ -25,6 +25,7 @@
 #include "otbClampImageFilter.h"
 #include "itkImageRegionIterator.h"
 #include "itkNumericTraits.h"
+#include <limits>
 #include "itkObjectFactory.h"
 #include "itkProgressReporter.h"
 
@@ -38,13 +39,35 @@ template <class TInputImage, class TOutputImage>
 ClampImageFilter<TInputImage, TOutputImage>
 ::ClampImageFilter()
 {
-  m_Lower = itk::NumericTraits<OutputImagePixelType>::NonpositiveMin();
-  m_Upper = itk::NumericTraits<OutputImagePixelType>::max();
+  m_Lower = std::numeric_limits < OutputPixelValueType >::lowest();
+  m_Upper = std::numeric_limits < OutputPixelValueType >::max();
+}
 
-  m_DLower = static_cast<double>(m_Lower);
-  m_DUpper = static_cast<double>(m_Upper);
+template <class TInputImage, class TOutputImage>
+void
+ClampImageFilter<TInputImage, TOutputImage>
+::SetLower(OutputPixelValueType val)
+{
+  if ( m_Lower != val )
+    {
+    m_Lower = val;
+    this->GetFunctor().SetLowest( m_Lower );
+    this->Modified();  
+    }
 }
 
+template <class TInputImage, class TOutputImage>
+void
+ClampImageFilter<TInputImage, TOutputImage>
+::SetUpper(OutputPixelValueType val)
+{
+  if ( m_Upper != val )
+    {
+    m_Upper = val;
+    this->GetFunctor().SetHighest( m_Upper );
+    this->Modified();
+    }
+}
 
 /**
  *
@@ -70,14 +93,15 @@ ClampImageFilter<TInputImage, TOutputImage>
 template <class TInputImage, class TOutputImage>
 void
 ClampImageFilter<TInputImage, TOutputImage>
-::ClampAbove(const OutputImagePixelType &thresh)
+::ClampAbove(const OutputPixelValueType &thresh)
 {
   if (m_Upper != thresh
-      || m_Lower > itk::NumericTraits<OutputImagePixelType>::NonpositiveMin())
+      || m_Lower > std::numeric_limits < OutputPixelValueType >::lowest())
     {
-    m_Lower = itk::NumericTraits<OutputImagePixelType>::NonpositiveMin();
+    m_Lower = std::numeric_limits < OutputPixelValueType >::lowest();
     m_Upper = thresh;
-    m_DUpper = static_cast<double>(m_Upper);
+    this->GetFunctor().SetLowest( m_Lower );
+    this->GetFunctor().SetHighest( m_Upper );
     this->Modified();
     }
 }
@@ -88,13 +112,14 @@ ClampImageFilter<TInputImage, TOutputImage>
 template <class TInputImage, class TOutputImage>
 void
 ClampImageFilter<TInputImage, TOutputImage>
-::ClampBelow(const OutputImagePixelType &thresh)
+::ClampBelow(const OutputPixelValueType &thresh)
 {
-  if (m_Lower != thresh || m_Upper < itk::NumericTraits<OutputImagePixelType>::max())
+  if (m_Lower != thresh || m_Upper < std::numeric_limits < OutputPixelValueType >::max())
     {
+    m_Upper = std::numeric_limits < OutputPixelValueType >::max();
     m_Lower = thresh;
-    m_DLower = m_Lower;
-    m_Upper = itk::NumericTraits<InputImagePixelType>::max();
+    this->GetFunctor().SetLowest( m_Lower );
+    this->GetFunctor().SetHighest( m_Upper );
     this->Modified();
     }
 }
@@ -106,7 +131,7 @@ ClampImageFilter<TInputImage, TOutputImage>
 template <class TInputImage, class TOutputImage>
 void
 ClampImageFilter<TInputImage, TOutputImage>
-::ClampOutside(const OutputImagePixelType &lower, const OutputImagePixelType &upper)
+::ClampOutside(const OutputPixelValueType &lower, const OutputPixelValueType &upper)
 {
   if (lower > upper)
     {
@@ -118,73 +143,12 @@ ClampImageFilter<TInputImage, TOutputImage>
     {
     m_Lower = lower;
     m_Upper = upper;
-    m_DLower = m_Lower;
-    m_DUpper = m_Upper;
+    this->GetFunctor().SetLowest( m_Lower );
+    this->GetFunctor().SetHighest( m_Upper );
     this->Modified();
     }
 }
 
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-void
-ClampImageFilter<TInputImage, TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                       itk::ThreadIdType threadId)
-{
-  itkDebugMacro(<<"Actually executing");
-
-  // Get the input and output pointers
-  InputImagePointer  inputPtr  = this->GetInput();
-  OutputImagePointer outputPtr = this->GetOutput(0);
-
-  // Define/declare an iterator that will walk the output region for this
-  // thread.
-  typedef itk::ImageRegionConstIterator<TInputImage> InputIterator;
-  typedef itk::ImageRegionIterator<TOutputImage>      OutputIterator;
-
-  InputIterator  inIt(inputPtr, outputRegionForThread);
-  OutputIterator outIt(outputPtr, outputRegionForThread);
-
-  // support progress methods/callbacks
-  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
-
-  // walk the regions, threshold each pixel
-  while( !outIt.IsAtEnd() && !inIt.IsAtEnd()  )
-    {
-    // Cast the value of the pixel to double in order to compare
-    // with the double version of the upper and the lower bounds of
-    // output image
-    const double value = static_cast<double>(inIt.Get());
-    OutputImagePixelType      outPix = m_Lower;
-
-    if ( m_DLower <= value && value <= m_DUpper)
-      {
-      // pixel passes to output unchanged
-      outPix = static_cast<OutputImagePixelType>(value);
-      }
-    /* Already outPix is initialized with m_Lower even for preventing Warning.
-     *
-    else if ( value < m_DLower )
-      {
-      outPix = m_Lower;
-      }
-     */
-    else if ( value > m_DUpper)
-      {
-      outPix = m_Upper;
-      }
-
-    outIt.Set( outPix );
-
-    ++inIt;
-    ++outIt;
-    progress.CompletedPixel();
-    }
-}
-
 } // end namespace itk
 
 #endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h
index 053c3060001c7bc0961d1f4aac7d16ead7cd1fa2..50b43302e4bc18ff3d0cb89c998ee05c5fc710a2 100644
--- a/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h
@@ -21,6 +21,7 @@
 #ifndef otbClampVectorImageFilter_h
 #define otbClampVectorImageFilter_h
 
+#include <vcl_deprecated_header.h>
 #include "itkImageToImageFilter.h"
 
 namespace otb
diff --git a/Modules/Filtering/ImageManipulation/include/otbConvertTypeFunctor.h b/Modules/Filtering/ImageManipulation/include/otbConvertTypeFunctor.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5a73b5cb1591868f4f67a1ddf65df3b5544a6ff
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbConvertTypeFunctor.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef otbConvertTypeFunctor_h
+#define otbConvertTypeFunctor_h
+
+#include <limits>
+#include <type_traits>
+#include <boost/type_traits/is_complex.hpp>
+#include <boost/type_traits/is_scalar.hpp>
+
+#include "itkNumericTraits.h"
+#include "otbDefaultConvertPixelTraits.h"
+
+namespace otb
+{
+namespace Functor
+{
+
+template < class TInputPixelType , class TOutputPixelType >
+class ConvertTypeFunctor
+{
+public:
+  typedef TInputPixelType InputPixelType;
+  typedef TOutputPixelType OutputPixelType;
+  typedef ConvertTypeFunctor Self;
+
+  typedef typename itk::NumericTraits < InputPixelType > :: ValueType InputInternalPixelType;
+  typedef typename itk::NumericTraits < OutputPixelType > :: ValueType OutputInternalPixelType;
+
+  typedef typename itk::NumericTraits < InputInternalPixelType > :: ValueType InputPixelValueType;
+  typedef typename itk::NumericTraits < OutputInternalPixelType > :: ValueType OutputPixelValueType;
+
+  static constexpr bool m_cInPix = boost::is_complex < InputPixelType > :: value ;
+  static constexpr bool m_cOutPix = boost::is_complex < OutputPixelType > :: value ;
+  static constexpr bool m_cInInternalPix = boost::is_complex < InputInternalPixelType > :: value ;
+  static constexpr bool m_cOutInternalPix = boost::is_complex < OutputInternalPixelType > :: value ;
+
+  ConvertTypeFunctor()  
+  // m_cInPix ( boost::is_complex < InputPixelType > :: value ) ,
+  // m_cOutPix ( boost::is_complex < OutputPixelType > :: value ) ,
+  // m_cInInternalPix ( boost::is_complex < InputInternalPixelType > :: value ) ,
+  // m_cOutInternalPix ( boost::is_complex < OutputInternalPixelType > :: value )
+  {
+    m_LowestB = std::numeric_limits < OutputPixelValueType >::lowest();
+    m_HighestB = std::numeric_limits < OutputPixelValueType >::max();
+
+    m_LowestBD = static_cast < double > ( m_LowestB );
+    m_HighestBD = static_cast < double > ( m_HighestB );
+
+    // m_cInPix = boost::is_complex < InputPixelType > :: value ; 
+    // m_cOutPix = boost::is_complex < OutputPixelType > :: value ;
+    // m_cInInternalPix = boost::is_complex < InputInternalPixelType > :: value ; 
+    // m_cOutInternalPix = boost::is_complex < OutputInternalPixelType > :: value ;
+  }
+
+  // template < class InternalPixelType  >
+  void SetInputComponents( unsigned int sizeIn )
+    {
+    m_CompIn = sizeIn ;
+    if ( m_cInPix )
+      {
+      // needed as ITK thinks that one complex component is actually 
+      // two components...
+      m_CompIn /= 2 ;
+      }
+    }
+
+  unsigned int GetOutputSize()
+  {
+    if ( m_cInInternalPix || m_cInPix )
+      m_Scal = 2 * m_CompIn;
+    else
+      m_Scal = m_CompIn;
+
+    OutputPixelType out;
+    unsigned int size = 
+      itk::NumericTraits < OutputPixelType > :: GetLength( out );
+    if ( size == 0 ) // That means it is a variable size container
+      {
+      if ( m_cOutInternalPix )
+        m_CompOut = ( m_Scal + 1 ) / 2 ;
+      else
+        m_CompOut = m_Scal ;
+      }
+    // It is a fixed size container, m_CompOut should be equal to its size
+    else if ( m_cOutPix ) // one complex is one component
+      m_CompOut = 1 ;
+    else // fized size container or scalar
+      m_CompOut = size;
+    
+
+    return m_CompOut ;
+  }
+
+  void SetLowest( OutputPixelValueType & lowest )
+  {
+    m_LowestB = lowest;
+    m_LowestBD = static_cast < double > ( m_LowestB );
+  }
+
+  void SetHighest( OutputPixelValueType & highest )
+  {
+    m_HighestB = highest;
+    m_HighestBD = static_cast < double > ( m_HighestB );
+  }
+
+  OutputPixelType operator() ( InputPixelType const & in ) const
+  {
+    std::vector < double > vPixel;
+    for ( unsigned int i  = 0 ; i < m_CompIn ; i ++)
+      FillIn < InputPixelType > ( i , in , vPixel );
+    assert( m_Scal == vPixel.size() );
+    if (  ( m_cOutPix || m_cOutInternalPix ) && vPixel.size()%2 )
+      { 
+      vPixel.push_back(0); // last component has no imaginary part
+      }
+    Clamp( vPixel );
+    OutputPixelType out;
+
+    int hack = 1;
+    if ( m_cOutPix )
+      hack += 1; // needed in case we have OutputPixelType == complex<t> as 
+    // itk::NumericTraits::SetLength() will ask a length of 2!
+    itk::NumericTraits < OutputPixelType > :: SetLength( out , 
+        hack * m_CompOut );
+
+    for ( unsigned int i  = 0 ; i < m_CompOut ; i ++)
+      FillOut < OutputPixelType > ( i , out , vPixel );
+    return out;
+  }
+
+  ~ConvertTypeFunctor() {};
+
+protected:
+  
+  template <class PixelType ,
+    std::enable_if_t < std::is_arithmetic < PixelType > ::value  , int > = 0 >
+  void FillIn( unsigned int i ,
+               InputPixelType const & pix ,
+               std::vector < double > & vPix ) const
+    {
+      vPix.push_back( DefaultConvertPixelTraits < InputPixelType > ::
+          GetNthComponent( i , pix ) );
+    }
+
+  template <class PixelType ,
+    std::enable_if_t < boost::is_complex < PixelType > :: value , int > = 0 >
+  void FillIn( unsigned int i ,
+               InputPixelType const & pix ,
+               std::vector < double > & vPix ) const
+    {
+      PixelType comp = DefaultConvertPixelTraits < InputPixelType > ::
+          GetNthComponent( i , pix );
+      vPix.push_back( static_cast < double > ( real( comp ) ) );
+      vPix.push_back( static_cast < double > ( imag( comp ) ) );
+    }
+
+  template <class PixelType ,
+   std::enable_if_t <  !( boost::is_complex < PixelType > :: value 
+    || std::is_arithmetic < PixelType > ::value ) , int > = 0 > 
+  void FillIn( unsigned int i ,
+               InputPixelType const & pix ,
+               std::vector < double > & vPix ) const
+    {
+        FillIn < InputInternalPixelType > ( i , pix , vPix );
+    }
+
+  void Clamp( std::vector < double > & vPixel ) const
+    {
+    for ( double & comp : vPixel )
+      {
+        if ( comp >= m_HighestBD )
+          comp = m_HighestBD;
+        else if ( comp <= m_LowestBD )
+          comp = m_LowestBD;
+      }
+    }
+
+  template <class PixelType ,
+    std::enable_if_t < std::is_arithmetic < PixelType > ::value  , int > = 0 >
+  void FillOut( unsigned int i ,
+                OutputPixelType & pix ,
+                std::vector < double > & vPix ) const
+    {
+      DefaultConvertPixelTraits < OutputPixelType > ::
+          SetNthComponent( i , pix , vPix[i] );
+    }
+
+  template <class PixelType ,
+    std::enable_if_t < boost::is_complex < PixelType > :: value , int > = 0 >
+  void FillOut( unsigned int i ,
+                OutputPixelType & pix ,
+                std::vector < double > & vPix ) const
+    {
+      DefaultConvertPixelTraits < OutputPixelType > ::
+          SetNthComponent( i , pix , 
+            PixelType ( vPix[ 2 * i] , vPix[ 2 * i + 1] ) );
+    }
+
+  template <class PixelType ,
+   std::enable_if_t <  !( boost::is_complex < PixelType > :: value 
+    || std::is_arithmetic < PixelType > ::value ) , int > = 0 > 
+  void FillOut( unsigned int i ,
+                OutputPixelType & pix ,
+                std::vector < double > & vPix ) const
+    {
+      FillOut < OutputInternalPixelType > ( i , pix , vPix );
+    }
+
+private:
+  ConvertTypeFunctor(const Self &) = delete; 
+  void operator =(const Self&) = delete;
+
+  double m_LowestBD , m_HighestBD ;
+  OutputPixelValueType m_LowestB , m_HighestB ;
+  unsigned int m_CompIn , m_CompOut , m_Scal ;
+  // const bool m_cInPix , m_cOutPix , m_cInInternalPix , m_cOutInternalPix ;
+
+};
+
+} //end namespace Functor
+
+} //end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
index 8582158d36343dd3449f79e27e7135fb04a435b7..01fe68c1150b7ce971cc105833b431b980d3981a 100644
--- a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
+++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
@@ -21,6 +21,7 @@
 #ifndef otbOneRIBandImageToOneComplexBandImage_h
 #define otbOneRIBandImageToOneComplexBandImage_h
 
+#include <vcl_deprecated_header.h>
 #include "itkImageToImageFilter.h"
 #include "itkImage.h"
 #include "itkNumericTraits.h"
diff --git a/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h
index c426b5a2f9e5a2225d842b51cb92640841bcefbd..8e86ee82f3bf7df11abc7ba99955e673e3b522e8 100644
--- a/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h
@@ -21,6 +21,7 @@
 #ifndef otbRealImageToComplexImageFilter_h
 #define otbRealImageToComplexImageFilter_h
 
+#include <vcl_deprecated_header.h>
 #include "itkUnaryFunctorImageFilter.h"
 #include "vnl/vnl_math.h"
 
diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
index 538b07214964f53fb86a9238d9417b968ae13630..c4adb6a9f7b78e4b040a916ef1a970ff6be05627 100644
--- a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
+++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
@@ -21,6 +21,7 @@
 #ifndef otbTwoNRIBandsImageToNComplexBandsImage_h
 #define otbTwoNRIBandsImageToNComplexBandsImage_h
 
+#include <vcl_deprecated_header.h>
 #include "itkImageToImageFilter.h"
 #include "itkImage.h"
 #include "itkNumericTraits.h"
diff --git a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
index 386b4294793890480773aa72640551525dfaedcf..834a6d3da072adf5c4dbc385d46db7931132de97 100644
--- a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
+++ b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
@@ -58,7 +58,6 @@ otbStreamingInnerProductVectorImageFilter.cxx
 otbPhaseFunctorTest.cxx
 otbShiftScaleVectorImageFilterNew.cxx
 otbChangeLabelImageFilter.cxx
-otbClampVectorImageFilter.cxx
 otbPrintableImageFilterNew.cxx
 otbShiftScaleImageAdaptorNew.cxx
 otbStreamingInnerProductVectorImageFilterNew.cxx
@@ -442,20 +441,6 @@ otb_add_test(NAME bfTvChangeLabelImageFilter COMMAND otbImageManipulationTestDri
   255   # upper  threshold
   )
 
-
-otb_add_test(NAME bfTvClampVectorImageFilterTest COMMAND otbImageManipulationTestDriver
-  --compare-image 0.0001
-  ${BASELINE}/bfTvClampVectorImageFilterTest_Output.tif
-  ${TEMP}/bfTvClampVectorImageFilterTest_Output.tif
-  otbClampVectorImageFilterTest
-  ${INPUTDATA}/QB_TOULOUSE_MUL_Extract_500_500.tif
-  ${TEMP}/bfTvClampVectorImageFilterTest_Output.tif
-  )
-
-otb_add_test(NAME bfTuClampVectorImageFilterNew COMMAND otbImageManipulationTestDriver
-  otbClampVectorImageFilterNew
-  )
-
 otb_add_test(NAME bfTuPrintableImageFilterNew COMMAND otbImageManipulationTestDriver
   otbPrintableImageFilterNew)
 
@@ -638,6 +623,11 @@ otb_add_test(NAME bfTvClampImageFilterTest COMMAND otbImageManipulationTestDrive
   ${TEMP}/bfTvClampImageFilterTest_Output.tif
   )
 
+otb_add_test(NAME bfTvClampImageFilterConversionTest COMMAND otbImageManipulationTestDriver
+  otbClampImageFilterConversionTest
+  ${INPUTDATA}/veryverySmallFSATSW.tif
+  )
+
 otb_add_test(NAME coTvConcatenateVectorImageFilter COMMAND otbImageManipulationTestDriver
   --compare-image ${NOTOL}
   ${BASELINE}/coConcatenateVectorImageFilterOutput1.hdr
diff --git a/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx
index 82deca5f4fc74917e5e3bc5d78bf1acf5e0a41c6..29ac5602eacbc38ffda2b5914822024b2a20d0df 100644
--- a/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx
@@ -21,10 +21,14 @@
 
 #include "otbClampImageFilter.h"
 #include "otbImage.h"
+#include "otbVectorImage.h"
+#include <limits>
 
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
 
+#include "itkImageRegionConstIterator.h"
+
 /** Pixel typedefs */
 typedef double                                      InputPixelType;
 typedef unsigned int                                OutputPixelType;
@@ -65,3 +69,423 @@ int otbClampImageFilterTest(int itkNotUsed(argc), char* argv[])
 
   return EXIT_SUCCESS;
 }
+
+template < class InImageType , class OutImageType >
+typename OutImageType::Pointer
+Cross ( std::string const & inputFileName )
+{
+  typedef otb::ImageFileReader< InImageType > ReaderType;
+  typedef otb::ClampImageFilter< InImageType , OutImageType > ClampFilter;
+  typename ReaderType::Pointer reader ( ReaderType::New() );
+  reader->SetFileName( inputFileName );
+  typename ClampFilter::Pointer clamp ( ClampFilter::New() );
+  clamp->SetInput( reader->GetOutput() );
+  clamp->Update();
+  return clamp->GetOutput();
+}
+
+template < class OutImageType >
+typename OutImageType::Pointer
+Cross ( otb::VectorImage< std::complex<float> >::Pointer input )
+{
+  typedef otb::ClampImageFilter< otb::VectorImage< std::complex<float> > ,
+                                 OutImageType > ClampFilter;
+  typename ClampFilter::Pointer clamp ( ClampFilter::New() );
+  clamp->SetInput( input );
+  clamp->Update();
+  return clamp->GetOutput();
+}
+
+template < class OutImageType >
+typename OutImageType::Pointer
+Cross ( otb::Image< itk::FixedArray< std::complex<float> , 2 > >::Pointer input )
+{
+  typedef otb::ClampImageFilter< otb::Image< itk::FixedArray< std::complex<float> , 2 > > ,
+                                 OutImageType > ClampFilter;
+  typename ClampFilter::Pointer clamp ( ClampFilter::New() );
+  clamp->SetInput( input );
+  clamp->Update();
+  return clamp->GetOutput();
+}
+
+typedef otb::VectorImage<double> ImageRefType;
+
+template <class ImageType >
+bool
+CompareImageReal( const ImageRefType::Pointer imRef , 
+                  const ImageType * im )
+{
+  typedef typename ImageType::PixelType RealPixelType;
+
+  RealPixelType min = std::numeric_limits< RealPixelType >::lowest();
+  RealPixelType max = std::numeric_limits< RealPixelType >::max();
+  auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imRef , 
+    imRef->GetLargestPossibleRegion() );
+  auto it = itk::ImageRegionConstIterator< ImageType >( im , 
+    im->GetLargestPossibleRegion() );
+  itRef.GoToBegin();
+  it.GoToBegin();
+  RealPixelType val;
+  double ref;
+  while ( !it.IsAtEnd() )
+    {
+    val = it.Get();
+    ref = itRef.Get()[0];
+    if ( ref > static_cast<double>( max ) && val != max ) 
+      {
+      return false;
+      }
+    else if ( ref < static_cast<double>( min ) && val != min ) 
+      {
+      return false;
+      }
+    else if ( static_cast<RealPixelType>( ref ) !=  val )
+      {
+      return false;
+      }
+    ++it;
+    ++itRef;
+    }
+    return true;
+}
+
+template <class ImageType >
+bool
+CompareVectorReal( const ImageRefType::Pointer imRef , 
+                   const ImageType * im )
+{
+  typedef typename ImageType::InternalPixelType RealPixelType;
+  RealPixelType min = std::numeric_limits< RealPixelType >::lowest();
+  RealPixelType max = std::numeric_limits< RealPixelType >::max();
+  auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imRef , 
+    imRef->GetLargestPossibleRegion() );
+  auto it = itk::ImageRegionConstIterator< ImageType >( im , 
+    im->GetLargestPossibleRegion() );
+  itRef.GoToBegin();
+  it.GoToBegin();
+  unsigned int nbChanel = im->GetNumberOfComponentsPerPixel ();
+  // unsigned int nbChanelRef = imRef->GetNumberOfComponentsPerPixel ();
+  RealPixelType val;
+  double ref;
+  while ( !it.IsAtEnd() )
+    {
+    // std::cout<<it.Get()<<std::endl;
+    // std::cout<<itRef.Get()<<std::endl;
+    for ( unsigned int i = 0 ; i < nbChanel ; i++ )
+      {
+      val = it.Get()[i];
+      ref = itRef.Get()[i];
+
+      if ( ref > static_cast<double>( max ) && val != max ) 
+        {
+          std::cout<<"ref : "<<static_cast<RealPixelType>(ref)<<std::endl;
+          std::cout<<"val : "<<val<<std::endl;
+        return false;
+        }
+      else if ( ref < static_cast<double>( min ) && val != min ) 
+        {
+          std::cout<<"ref : "<<static_cast<RealPixelType>(ref)<<std::endl;
+          std::cout<<"val : "<<val<<std::endl;
+        return false;
+        }
+      else if ( static_cast<RealPixelType>(ref) !=  val )
+        {
+          std::cout<<"ref : "<<static_cast<RealPixelType>(ref)<<std::endl;
+          std::cout<<"val : "<<val<<std::endl;
+        return false;
+        }
+      }
+    ++it;
+    ++itRef;
+    }
+  return true;
+}
+
+template <class ImageType >
+bool
+CompareImageComplex( const ImageRefType::Pointer imageRef , 
+                     const ImageType * im )
+{
+  typedef typename ImageType::PixelType ComplexType;
+  typedef typename ComplexType::value_type RealType;
+
+  RealType min = std::numeric_limits< RealType >::lowest();
+  RealType max = std::numeric_limits< RealType >::max();
+  auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imageRef , 
+    imageRef->GetLargestPossibleRegion() );
+  auto it = itk::ImageRegionConstIterator< ImageType >( im , 
+    im->GetLargestPossibleRegion() );
+  itRef.GoToBegin();
+  it.GoToBegin();
+  ComplexType val;
+  double reRef , imRef;
+  while ( !it.IsAtEnd() )
+    {
+    val = it.Get();
+    reRef = itRef.Get()[0];
+    imRef = itRef.Get()[1];
+    if ( ( reRef > static_cast<double>( max ) && val.real() != max )
+      || ( imRef > static_cast<double>( max ) && val.imag() != max ) ) 
+      {
+      return false;
+      }
+    else if ( ( reRef < static_cast<double>( min ) && val.real() != min )
+           || ( imRef < static_cast<double>( min ) && val.imag() != min ) ) 
+      {
+      return false;
+      }
+    else if ( static_cast<RealType>( reRef ) !=  val.real() 
+           || static_cast<RealType>( imRef ) !=  val.imag() )
+      {
+      return false;
+      }
+    ++it;
+    ++itRef;
+    }
+    return true;
+}
+
+template <class ImageType >
+bool
+CompareVectorComplex( const ImageRefType::Pointer imageRef , 
+                     const ImageType * im )
+{
+  typedef typename ImageType::InternalPixelType ComplexType;
+  typedef typename ComplexType::value_type RealType;
+
+  RealType min = std::numeric_limits< RealType >::lowest();
+  RealType max = std::numeric_limits< RealType >::max();
+  auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imageRef , 
+    imageRef->GetLargestPossibleRegion() );
+  auto it = itk::ImageRegionConstIterator< ImageType >( im , 
+    im->GetLargestPossibleRegion() );
+  itRef.GoToBegin();
+  it.GoToBegin();
+  unsigned int nbChanel = im->GetNumberOfComponentsPerPixel ();
+  ComplexType val;
+  float reRef , imRef;
+  while ( !it.IsAtEnd() )
+    {
+    for (unsigned int i = 0 ; i < nbChanel ; i++ )
+      {
+      val = it.Get()[i];
+      reRef = itRef.Get()[ 2 * i ];
+      imRef = itRef.Get()[ 2 * i + 1 ];
+      if ( ( reRef > static_cast<double>( max ) && val.real() != max )
+        || ( imRef > static_cast<double>( max ) && val.imag() != max ) ) 
+        {
+        return false;
+        }
+      else if ( ( reRef < static_cast<double>( min ) && val.real() != min )
+             || ( imRef < static_cast<double>( min ) && val.imag() != min ) ) 
+        {
+        return false;
+        }
+      else if ( static_cast<RealType>( reRef ) != val.real()
+             || static_cast<RealType>( imRef ) != val.imag() )
+        {
+        return false;
+        }
+      }
+    ++it;
+    ++itRef;
+    }
+    return true;
+}
+
+template <class ImageType >
+bool
+CompareArrayComplex( const ImageRefType::Pointer imageRef , 
+                     const ImageType * im )
+{
+  typedef typename ImageType::PixelType ArrayType;
+  typedef typename ArrayType::ValueType ComplexType;
+  typedef typename ComplexType::value_type RealType;
+
+  RealType min = std::numeric_limits< RealType >::lowest();
+  RealType max = std::numeric_limits< RealType >::max();
+  auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imageRef , 
+    imageRef->GetLargestPossibleRegion() );
+  auto it = itk::ImageRegionConstIterator< ImageType >( im , 
+    im->GetLargestPossibleRegion() );
+  itRef.GoToBegin();
+  it.GoToBegin();
+  unsigned int nbChanel = im->GetNumberOfComponentsPerPixel ();
+  ComplexType val;
+  float reRef , imRef;
+  while ( !it.IsAtEnd() )
+    {
+    for (unsigned int i = 0 ; i < nbChanel ; i++ )
+      {
+      val = it.Get()[i];
+      reRef = itRef.Get()[ 2 * i ];
+      imRef = itRef.Get()[ 2 * i + 1 ];
+      if ( ( reRef > static_cast<double>( max ) && val.real() != max )
+        || ( imRef > static_cast<double>( max ) && val.imag() != max ) ) 
+        {
+        return false;
+        }
+      else if ( ( reRef < static_cast<double>( min ) && val.real() != min )
+             || ( imRef < static_cast<double>( min ) && val.imag() != min ) ) 
+        {
+        return false;
+        }
+      else if ( static_cast<RealType>( reRef ) != val.real()
+             || static_cast<RealType>( imRef ) != val.imag() )
+        {
+        return false;
+        }
+      }
+    ++it;
+    ++itRef;
+    }
+    return true;
+}
+
+int otbClampImageFilterConversionTest(int itkNotUsed(argc), char* argv[])
+{
+  typedef otb::ImageFileReader< ImageRefType > ReaderType;
+  ReaderType::Pointer reader ( ReaderType::New() );
+  reader->SetFileName( argv[1] );
+  reader->Update();
+  ImageRefType::Pointer imageRef = reader->GetOutput();
+
+  // vect<real> --> vect<real>
+  otb::VectorImage< short >::Pointer image0 = 
+    Cross < otb::VectorImage< double >  , otb::VectorImage< short > > ( argv[1] );
+  bool test0 = CompareVectorReal < otb::VectorImage< short > >( imageRef , image0 );
+  std::cout<< "Test 0 : "<<test0<<std::endl;
+  image0 =nullptr;
+
+  // vect<real> --> vect<complex>
+  otb::VectorImage< std::complex<unsigned short>>::Pointer image1 = 
+    Cross < otb::VectorImage< float >  , otb::VectorImage<std::complex<unsigned short>> > ( argv[1] );
+  bool test1 = CompareVectorComplex < otb::VectorImage<std::complex<unsigned short>> >( imageRef , image1 );
+  std::cout<< "Test 1 : "<<test1<<std::endl;
+  image1 = nullptr;
+
+  // vect<real> --> image<real>
+  otb::Image<int>::Pointer image2 = 
+    Cross < otb::VectorImage< float >  , otb::Image<int> > ( argv[1] );
+  bool test2 = CompareImageReal < otb::Image<int> >( imageRef , image2 );
+  std::cout<< "Test 2 : "<<test2<<std::endl;
+  image2 = nullptr;
+
+  // vect<real> --> image<complex>
+  otb::Image< std::complex<float>>::Pointer image3 = 
+    Cross < otb::VectorImage< float >  , otb::Image<std::complex<float>> > ( argv[1] );
+  bool test3 = CompareImageComplex < otb::Image<std::complex<float>> >( imageRef , image3 );
+  std::cout<< "Test 3 : "<<test3<<std::endl;
+  image3 = nullptr;
+
+  // image<real> --> image<real>
+  otb::Image< unsigned short >::Pointer image4 = 
+    Cross < otb::Image< itk::FixedArray < double , 4 > >  , otb::Image< unsigned short > > ( argv[1] );
+  bool test4 = CompareImageReal < otb::Image< unsigned short > >( imageRef , image4 );
+  std::cout<< "Test 4 : "<<test4<<std::endl;
+  image4 = nullptr;
+
+  // image<real> --> image<complex>
+  otb::Image< std::complex<int> >::Pointer image5 = 
+    Cross < otb::Image< itk::FixedArray < double , 4 > >  , otb::Image< std::complex<int> > > ( argv[1] );
+  bool test5 = CompareImageComplex < otb::Image< std::complex<int> > >( imageRef , image5 );
+  std::cout<< "Test 5 : "<<test5<<std::endl;
+  image5 = nullptr;
+
+  // image<real> --> vector<real>
+  otb::VectorImage< float >::Pointer image6 = 
+    Cross < otb::Image< itk::FixedArray < double , 4 > >  , otb::VectorImage< float > > ( argv[1] );
+  bool test6 = CompareVectorReal < otb::VectorImage< float > >( imageRef , image6 );
+  std::cout<< "Test 6 : "<<test6<<std::endl;
+  image6 = nullptr;
+
+  // image<real> --> vector<complex>
+  otb::VectorImage< std::complex<float> >::Pointer image7 = 
+    Cross < otb::Image< itk::FixedArray < double , 4 > >  , otb::VectorImage< std::complex<float> > > ( argv[1] );
+  bool test7 = CompareVectorComplex < otb::VectorImage< std::complex<float> > >( imageRef , image7 );
+  std::cout<< "Test 7 : "<<test7<<std::endl;  
+
+  // vector<complex> --> vector<real>
+  otb::VectorImage< int >::Pointer image8 = 
+    Cross <  otb::VectorImage< int > > ( image7 );
+  bool test8 = CompareVectorReal < otb::VectorImage< int > >( imageRef , image8 );
+  std::cout<< "Test 8 : "<<test8<<std::endl;
+  image8=nullptr;
+
+  // vector<complex> --> vector<complex>
+  otb::VectorImage< std::complex<int> >::Pointer image9 = 
+    Cross <  otb::VectorImage< std::complex<int> > > ( image7 );
+  bool test9 = CompareVectorComplex < otb::VectorImage< std::complex<int> > >( imageRef , image9 );
+  std::cout<< "Test 9 : "<<test9<<std::endl;
+  image9=nullptr;
+
+  // vector<complex> --> image<real>
+  otb::Image< int >::Pointer image10 = 
+    Cross <  otb::Image< int > > ( image7 );
+  bool test10 = CompareImageReal < otb::Image< int > >( imageRef , image10 );
+  std::cout<< "Test 10 : "<<test10<<std::endl;
+  image10=nullptr;
+
+  // vector<complex> --> image<complex>
+  otb::Image< std::complex<unsigned short> >::Pointer image11 = 
+    Cross <  otb::Image< std::complex<unsigned short> > > ( image7 );
+  bool test11 = CompareImageComplex < otb::Image< std::complex<unsigned short> > >( imageRef , image11 );
+  std::cout<< "Test 11 : "<<test11<<std::endl;
+  image11=nullptr;
+
+  // image<complex> --> vector<complex>
+  otb::VectorImage<std::complex<float>>::Pointer image12 = 
+    Cross < otb::Image< std::complex<float> >   , otb::VectorImage< std::complex<float>> > ( argv[1] );
+  bool test12 = CompareVectorComplex < otb::VectorImage<std::complex<float>> >( imageRef , image12 );
+  std::cout<< "Test 12 : "<<test12<<std::endl;
+  image12 = nullptr;
+
+  // image<complex> --> image<complex>
+  otb::Image< std::complex< short >>::Pointer image13 = 
+    Cross < otb::Image< std::complex<float> >   , otb::Image< std::complex< short >> > ( argv[1] );
+  bool test13 = CompareImageComplex < otb::Image< std::complex< short >> >( imageRef , image13 );
+  std::cout<< "Test 13 : "<<test13<<std::endl;
+  image13 = nullptr;
+
+  // image<complex> --> image<real>
+  otb::Image< int >::Pointer image14 = 
+    Cross < otb::Image< std::complex<float> >   , otb::Image< int > > ( argv[1] );
+  bool test14 = CompareImageReal < otb::Image< int > >( imageRef , image14 );
+  std::cout<< "Test 14 : "<<test14<<std::endl;
+  image14 = nullptr;
+
+  // image<complex> --> vector<real>
+  otb::VectorImage< unsigned short >::Pointer image15 = 
+    Cross < otb::Image< std::complex<float> >   , otb::VectorImage< unsigned short > > ( argv[1] );
+  bool test15 = CompareVectorReal < otb::VectorImage< unsigned short > >( imageRef , image15 );
+  std::cout<< "Test 15 : "<<test15<<std::endl;
+  image15 = nullptr;
+
+  // image<fixedarray<real>> --> image<fixedarray<complex>>
+  otb::Image< itk::FixedArray < std::complex<float> , 2 > >::Pointer image16 = 
+    Cross < otb::Image< itk::FixedArray < double , 4 > > ,
+            otb::Image< itk::FixedArray < std::complex<float> , 2 > > > ( argv[1] );
+  bool test16 = CompareArrayComplex < otb::Image< itk::FixedArray < std::complex<float> , 2 > > >( imageRef , image16 );
+  std::cout<< "Test 16 : "<<test16<<std::endl; 
+
+  // image<fixedarray<complex>> --> vectorimage<real>
+  otb::VectorImage< int >::Pointer image17 = 
+    Cross < otb::VectorImage< int > >( image16 );
+  bool test17 = CompareVectorReal < otb::VectorImage< int > >( imageRef , image17 );
+  std::cout<< "Test 17 : "<<test17<<std::endl; 
+  image17 = nullptr;
+
+  // vector<real> --> image<fixedarray<complex>>
+  otb::Image< itk::FixedArray < std::complex<float> , 2 > >::Pointer image18 = 
+    Cross < otb::VectorImage< int > ,
+            otb::Image< itk::FixedArray < std::complex<float> , 2 > > > ( argv[1] );
+  bool test18 = CompareArrayComplex < otb::Image< itk::FixedArray < std::complex<float> , 2 > > >( imageRef , image18 );
+  image18 = nullptr;
+  std::cout<< "Test 18 : "<<test18<<std::endl; 
+
+  if (test1 && test2 && test3 && test4 && test5 &&test6 && test7 && test8 
+   && test9 && test10 && test11 && test12 && test13 && test14 && test15 
+   && test16 && test17 && test18 )
+    return EXIT_SUCCESS;
+  return EXIT_FAILURE;
+}
diff --git a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
index b5176d976154edad57bcd2f470a2cff6eb76085c..c5b59f8ef2d62eb790adf085e5c9121db5f28d4a 100644
--- a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
@@ -61,8 +61,6 @@ void RegisterTests()
   REGISTER_TEST(otbPhaseFunctorTest);
   REGISTER_TEST(otbShiftScaleVectorImageFilterNew);
   REGISTER_TEST(otbChangeLabelImageFilter);
-  REGISTER_TEST(otbClampVectorImageFilterNew);
-  REGISTER_TEST(otbClampVectorImageFilterTest);
   REGISTER_TEST(otbPrintableImageFilterNew);
   REGISTER_TEST(otbShiftScaleImageAdaptorNew);
   REGISTER_TEST(otbStreamingInnerProductVectorImageFilterNew);
@@ -87,6 +85,7 @@ void RegisterTests()
   REGISTER_TEST(otbMultiplyByScalarImageFilterTest);
   REGISTER_TEST(otbClampImageFilterNew);
   REGISTER_TEST(otbClampImageFilterTest);
+  REGISTER_TEST(otbClampImageFilterConversionTest);
   REGISTER_TEST(otbConcatenateVectorImageFilter);
   REGISTER_TEST(otbBinaryImageMinimalBoundingRegionCalculatorNew);
   REGISTER_TEST(otbVectorRescaleIntensityImageFilterNew);
diff --git a/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
index b7d8de1665289709964b8938b56ab693ee62b93b..41a18d0bb3b611e3eee571932648c0803e92c3aa 100644
--- a/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
@@ -20,7 +20,8 @@
 
 #include "itkMacro.h"
 
-#include "otbOneRIBandImageToOneComplexBandImage.h"
+// #include "otbOneRIBandImageToOneComplexBandImage.h"
+#include "otbClampImageFilter.h"
 
 #include "otbImage.h"
 #include "otbVectorImage.h"
@@ -37,7 +38,7 @@ int otbOneRIBandImageToOneComplexBandImage(int itkNotUsed(argc), char * argv[])
   typedef otb::Image<OutputPixelType, 2> OutputImageType;
  
  
-  typedef otb::OneRIBandImageToOneComplexBandImage<InputImageType, OutputImageType> FilterType;
+  typedef otb::ClampImageFilter<InputImageType, OutputImageType> FilterType;
   typedef otb::ImageFileReader<InputImageType> ReaderType;
   typedef otb::ImageFileWriter<OutputImageType> WriterType;
 
diff --git a/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx b/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx
index f1d830132a227162ceb539c3435fd8436b085de4..b20416b4d77617e0c23ea967603cbd910489ea5c 100644
--- a/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx
+++ b/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx
@@ -72,7 +72,7 @@ StatisticsXMLFileWriter<TMeasurementVector>
     itkExceptionMacro(<<"The XML output FileName is empty, please set the filename via the method SetFileName");
 
   // Check that the right extension is given : expected .xml */
-  std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName);
+  const std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName);
   if (itksys::SystemTools::LowerCase(extension) != ".xml")
     {
     itkExceptionMacro(<<extension
diff --git a/Modules/IO/ImageIO/include/otbImageFileReader.txx b/Modules/IO/ImageIO/include/otbImageFileReader.txx
index 98a37bf87b51b5caade4258ab231a45b1f39c87a..87cc50b6e38b3de373d20c163872d5898b885666 100644
--- a/Modules/IO/ImageIO/include/otbImageFileReader.txx
+++ b/Modules/IO/ImageIO/include/otbImageFileReader.txx
@@ -398,18 +398,33 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
     {
 
     std::string lFileNameOssimKeywordlist = GetDerivedDatasetSourceFileName(m_FileName);
+    std::string extension = itksys::SystemTools::GetFilenameLastExtension(lFileNameOssimKeywordlist);
+    std::string attachedGeom = lFileNameOssimKeywordlist.substr(
+      0,
+      lFileNameOssimKeywordlist.size() - extension.size()) + std::string(".geom");
 
     // Update otb Keywordlist
     ImageKeywordlist otb_kwl;
-    if (!m_FilenameHelper->ExtGEOMFileNameIsSet())
+
+    // Case 1: external geom supplied through extended filename
+    if (m_FilenameHelper->ExtGEOMFileNameIsSet())
       {
-      otb_kwl = ReadGeometryFromImage(lFileNameOssimKeywordlist,!m_FilenameHelper->GetSkipRpcTag());
-      otbMsgDevMacro(<< "Loading internal kwl");
+      otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName());
+      otbMsgDevMacro(<< "Loading external kwl: "<< m_FilenameHelper->GetExtGEOMFileName());
       }
+    // Case 2: attached geom (if present)
+    else if (itksys::SystemTools::FileExists(attachedGeom))
+      {
+      otb_kwl = ReadGeometryFromGEOMFile(attachedGeom);
+      otbMsgDevMacro(<< "Loading attached kwl");
+      }
+    // Case 3: find an ossimPluginProjection
+    // Case 4: find an ossimProjection
+    // Case 5: find RPC tags in TIF
     else
       {
-      otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName());
-      otbMsgDevMacro(<< "Loading external kwl");
+      otb_kwl = ReadGeometryFromImage(lFileNameOssimKeywordlist,!m_FilenameHelper->GetSkipRpcTag());
+      otbMsgDevMacro(<< "Loading internal kwl");
       }
 
     // Don't add an empty ossim keyword list
diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
index 2973a7a8a3a2e251cdef0ffcf55f034eb6b217aa..502438a0d2a4ebb6bc1b85ce59e8e419fb16206a 100644
--- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
+++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
@@ -265,6 +265,11 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
       }
     this->m_InMemoryOutputs.push_back(tmpContainer);
     }
+
+  if (oSRS)
+    {
+    oSRS->Release();
+    }
 }
 
 template <class TInputImage, class TMaskImage>
@@ -734,7 +739,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
     }
 
   const unsigned int nbFeatThread = std::ceil(inLayer.GetFeatureCount(true) / (float) numberOfThreads);
-  assert(nbFeatThread > 0);
+  //assert(nbFeatThread > 0);
 
   OGRFeatureDefn &layerDefn = inLayer.GetLayerDefn();
   ogr::Layer::const_iterator featIt = inLayer.begin();
@@ -807,6 +812,11 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
       OGRFieldDefn fieldDefn(layerDefn.GetFieldDefn(k));
       outLayer.CreateField(fieldDefn);
       }
+
+    if (oSRS)
+      {
+      oSRS->Release();
+      }
     }
 
   // Add new fields
diff --git a/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx b/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx
index 138032ea734aad7266bdfb020d54d547be05a9b3..414a7730276e95d4f41392d04c458d9f3af80035 100644
--- a/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx
+++ b/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx
@@ -129,6 +129,7 @@ int otbImageSampleExtractorFilterUpdate(int argc, char* argv[])
   output->CreateLayer( inLayer.GetName(),
                        oSRS,
                        inLayer.GetLayerDefn().GetGeomType());
+  oSRS->Release();
   otb::ogr::Layer dstLayer = output->GetLayer(0);
   OGRFieldDefn labelField(classFieldName.c_str(),OFTString);
   dstLayer.CreateField(labelField, true);
diff --git a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
index d76968ecf1929a8f8034e016c8b13fa2d2ff3bfb..542b29e6f8c65dd98cd919bcf0f363cc8072c193 100644
--- a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
@@ -238,13 +238,36 @@ public:
     * \param[in] worldPoint World point to geocode
     * \param[out] azimuthTime Estimated zero-doppler azimuth time
     * \param[out] rangeTime Estimated range time
+    * \param[out] interpSensorPos interpolated ECEF sensor position
+    * \param[out] interpSensorVel interpolated ECEF sensor velocity
     * \return True if success, false otherwise. In this case,
     * azimuthTime and rangeTime will not be modified.
     */
-   /*virtual*/ bool worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime) const;
+   /*virtual*/ bool worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime, ossimEcefPoint & interpSensorPos, ossimEcefVector & interpSensorVel) const;
 
-   // TODO: document me
-   /*virtual*/ void lineSampleToAzimuthRangeTime(const ossimDpt & imPt, TimeType & azimuthTime, double & rangeTime) const;
+   /**
+    * This method implement inverse sar geolocation similar to
+    * worldToLineSample, except that it also returns (y,z)
+    * coordinates, defined as follows:
+    * Let n = |sensorPos|,
+    * ps2 = scalar_product(sensorPos,worldPoint)
+    * d = distance(sensorPos,worldPoint)
+    *
+    * z = n - ps2/n
+    * y = sqrt(d*d - z*z)
+    * 
+    * sign of y is furher adapted to be inverted if sensor is left or
+    * right looking 
+    *
+    * \param[in] worldPoint World point to geocode
+    * \param[out] imPt Corresponding estimated image point
+    * \param[out] y 
+    * \param[out] z 
+    * \return True if success, false otherwise. In this case,
+    */
+   void worldToLineSampleYZ(const ossimGpt& worldPt, ossimDpt& imPt, double & y, double & z) const;
+   
+   void lineSampleToAzimuthRangeTime(const ossimDpt & imPt, TimeType & azimuthTime, double & rangeTime) const;
 
    // TODO: document me
    bool autovalidateInverseModelFromGCPs(const double & xtol = 1, const double & ytol = 1, const double azTimeTol = 500, const double &rangeTimeTo=0.0000000001) const;
@@ -419,7 +442,8 @@ protected:
    ProductType                                 theProductType; // GRD/SLC
    DurationType                                theAzimuthTimeOffset; // Offset computed
    double                                      theRangeTimeOffset; // Offset in seconds, computed
-
+   bool                                        theRightLookingFlag;
+   
    static const double C;
 
    static const unsigned int thePluginVersion; // version of the SarSensorModel plugin
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
index ac695a2a4b790ebce7671fc7e27c62a954e91098..61e85f63c090b292f148b0019ddef1ac3ec59689 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
@@ -12,7 +12,7 @@
  *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
- *
+ 
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
@@ -137,7 +137,8 @@ namespace ossimplugins
       theRangeResolution(0.),
       theBistaticCorrectionNeeded(false),
       theAzimuthTimeOffset(seconds(0)),
-      theRangeTimeOffset(0.)
+      theRangeTimeOffset(0.),
+      theRightLookingFlag(true)
       {}
 
    ossimSarSensorModel::GCPRecordType const&
@@ -220,7 +221,58 @@ namespace ossimplugins
       TimeType azimuthTime;
       double rangeTime;
 
-      const bool success = worldToAzimuthRangeTime(worldPt, azimuthTime, rangeTime);
+      ossimEcefPoint sensorPos;
+      ossimEcefVector sensorVel;
+
+      const bool success = worldToAzimuthRangeTime(worldPt, azimuthTime, rangeTime, sensorPos, sensorVel);
+
+      if(!success)
+      {
+         imPt.makeNan();
+         return;
+      }
+      // std::clog << "AzimuthTime: " << azimuthTime << "\n";
+      // std::clog << "RangeTime: " << rangeTime << "\n";
+      // std::clog << "GRD: " << isGRD() << "\n";
+
+      // Convert azimuth time to line
+      azimuthTimeToLine(azimuthTime,imPt.y);
+
+      if(isGRD())
+      {
+         // GRD case
+         double groundRange(0);
+         slantRangeToGroundRange(rangeTime*C/2,azimuthTime,groundRange);
+         // std::clog << "GroundRange: " << groundRange << "\n";
+         // std::clog << "TheRangeResolution: " << theRangeResolution << "\n";
+
+         // Eq 32 p. 31
+         // TODO: possible micro-optimization: precompute 1/theRangeResolution, and
+         // use *
+         imPt.x = groundRange/theRangeResolution;
+      }
+      else
+      {
+         // std::clog << "TheNearRangeTime: " << theNearRangeTime << "\n";
+         // std::clog << "TheRangeSamplingRate: " << theRangeSamplingRate << "\n";
+         // SLC case
+         // Eq 23 and 24 p. 28
+         imPt.x = (rangeTime - theNearRangeTime)*theRangeSamplingRate;
+      }
+   }
+
+void ossimSarSensorModel::worldToLineSampleYZ(const ossimGpt& worldPt, ossimDpt & imPt, double & y, double & z) const
+   {
+      // std::clog << "ossimSarSensorModel::worldToLineSample()\n";
+      assert(theRangeResolution>0&&"theRangeResolution is null.");
+
+      // First compute azimuth and range time
+      TimeType azimuthTime;
+      double rangeTime;
+      ossimEcefPoint sensorPos;
+      ossimEcefVector sensorVel;
+
+      const bool success = worldToAzimuthRangeTime(worldPt, azimuthTime, rangeTime,sensorPos,sensorVel);
 
       if(!success)
       {
@@ -255,9 +307,35 @@ namespace ossimplugins
          // Eq 23 and 24 p. 28
          imPt.x = (rangeTime - theNearRangeTime)*theRangeSamplingRate;
       }
+
+      // Now computes Y and Z
+      ossimEcefPoint inputPt(worldPt);
+      double NormeS = sqrt(sensorPos[0]*sensorPos[0] + sensorPos[1]*sensorPos[1] + sensorPos[2]*sensorPos[2]);  /* distance du radar */                                                                           
+      double PS2 = inputPt[0]*sensorPos[0] + inputPt[1]*sensorPos[1] + inputPt[2]*sensorPos[2];
+
+      // TODO check for small NormesS to avoid division by zero ?
+      // Should never happen ...
+      assert(NormeS>1e-6);
+      z = NormeS - PS2/NormeS;
+
+      double distance = sqrt((sensorPos[0]-inputPt[0])*(sensorPos[0]-inputPt[0]) + 
+                             (sensorPos[1]-inputPt[1])*(sensorPos[1]-inputPt[1]) + 
+                             (sensorPos[2]-inputPt[2])*(sensorPos[2]-inputPt[2]));  
+
+      y = sqrt(distance*distance - z*z);
+
+      // Check view side and change sign of Y accordingly
+      if ( (( sensorVel[0] * (sensorPos[1]* inputPt[2] - sensorPos[2]* inputPt[1]) +
+              sensorVel[1] * (sensorPos[2]* inputPt[0] - sensorPos[0]* inputPt[2]) +
+              sensorVel[2] * (sensorPos[0]* inputPt[1] - sensorPos[1]* inputPt[0])) > 0) ^ theRightLookingFlag )
+        {
+        y = -y;
+        }
    }
 
-   bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime) const
+
+
+bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime, ossimEcefPoint & interpSensorPos, ossimEcefVector & interpSensorVel) const
    {
       // std::clog << "ossimSarSensorModel::worldToAzimuthRangeTime()\n";
       // First convert lat/lon to ECEF
@@ -265,8 +343,6 @@ namespace ossimplugins
 
       // Compute zero doppler time
       TimeType interpTime;
-      ossimEcefPoint interpSensorPos;
-      ossimEcefVector interpSensorVel;
 
       const bool success = zeroDopplerLookup(inputPt,azimuthTime,interpSensorPos,interpSensorVel);
 
@@ -857,7 +933,9 @@ namespace ossimplugins
          double   estimatedRangeTime;
 
          // Estimate times
-         const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime);
+         ossimEcefPoint sensorPos;
+         ossimEcefVector sensorVel;
+         const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime,sensorPos, sensorVel);
          this->worldToLineSample(gcpIt->worldPt,estimatedImPt);
 
          const bool thisSuccess
@@ -964,8 +1042,10 @@ namespace ossimplugins
          TimeType estimatedAzimuthTime;
          double   estimatedRangeTime;
 
+         ossimEcefPoint sensorPos;
+         ossimEcefVector sensorVel;
          // Estimate times
-         const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime);
+         const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime, sensorPos, sensorVel);
 
          if(s1)
          {
@@ -985,8 +1065,11 @@ namespace ossimplugins
          TimeType estimatedAzimuthTime;
          double   estimatedRangeTime;
 
+         ossimEcefPoint sensorPos;
+         ossimEcefVector sensorVel;
+
          // Estimate times
-         const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime);
+         const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime, sensorPos, sensorVel);
 
          if(s1)
          {
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
index f97134cbd1e4eb32f6768168b50eb5cab7c94158..c6317be14289016f5a5f9636b1af864a1d0c969c 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
@@ -592,11 +592,16 @@ public:
     {                                                                   \
     Image##Type::Pointer ret;                                           \
     Parameter* param = GetParameterByKey(parameter);                    \
-    if (dynamic_cast<InputImageParameter*>(param))                      \
+    InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param); \
+    ComplexInputImageParameter* paramDownC = dynamic_cast<ComplexInputImageParameter*>(param); \
+    if ( paramDown )                                                    \
       {                                                                 \
-      InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param); \
       ret = paramDown->Get##Image();                                    \
       }                                                                 \
+    else if ( paramDownC )  /* Support of ComplexInputImageParameter */ \
+      {                                                                 \
+      ret = paramDownC->Get##Image();                                   \
+      }                                                                 \
     return ret;                                                         \
     }
 
@@ -619,30 +624,16 @@ public:
   otbGetParameterImageMacro(UInt8RGBImage);
   otbGetParameterImageMacro(UInt8RGBAImage);
 
-  /* Get a complex image value
-   *
-   * Can be called for types :
-   * \li ParameterType_ComplexInputImage
-   */
-
-#define otbGetParameterComplexImageMacro( Image )                       \
-  Image##Type * GetParameter##Image( std::string parameter )            \
-    {                                                                   \
-    Image##Type::Pointer ret;                                           \
-    Parameter* param = GetParameterByKey(parameter);                    \
-    ComplexInputImageParameter* paramDown = dynamic_cast<ComplexInputImageParameter*>(param); \
-    if (paramDown)                                                      \
-      {                                                                 \
-      ret = paramDown->Get##Image();                                    \
-      }                                                                 \
-    return ret;                                                         \
-    }
-
-  otbGetParameterComplexImageMacro(ComplexFloatImage);
-  otbGetParameterComplexImageMacro(ComplexDoubleImage);
+  // Complex image
+  otbGetParameterImageMacro(ComplexInt16Image);
+  otbGetParameterImageMacro(ComplexInt32Image); 
+  otbGetParameterImageMacro(ComplexFloatImage);
+  otbGetParameterImageMacro(ComplexDoubleImage);
 
-  otbGetParameterComplexImageMacro(ComplexFloatVectorImage);
-  otbGetParameterComplexImageMacro(ComplexDoubleVectorImage);
+  otbGetParameterImageMacro(ComplexInt16VectorImage);
+  otbGetParameterImageMacro(ComplexInt32VectorImage);
+  otbGetParameterImageMacro(ComplexFloatVectorImage);
+  otbGetParameterImageMacro(ComplexDoubleVectorImage);
 
   /* Get an image list value
    *
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h
index 1fa00dd77d70660769bdd48e0031ac0d77d8e368..264967e376a209e0bf36929e4f4960b2e8cc5490 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h
@@ -60,12 +60,37 @@ public:
   ComplexFloatVectorImageType* GetImage();
 
   /** Get the input image as XXXImageType */
+  ComplexInt16ImageType* GetComplexInt16Image();
+  ComplexInt32ImageType* GetComplexInt32Image();
   ComplexFloatImageType*  GetComplexFloatImage();
   ComplexDoubleImageType* GetComplexDoubleImage();
 
+  ComplexInt16VectorImageType* GetComplexInt16VectorImage();
+  ComplexInt32VectorImageType* GetComplexInt32VectorImage();
   ComplexFloatVectorImageType*  GetComplexFloatVectorImage();
   ComplexDoubleVectorImageType* GetComplexDoubleVectorImage();
 
+/* Support for ComplexInputImageParameter. This has been done to support 
+the macro otbGetParameterImageMacro of otbWrapperApplication.h */
+  UInt8ImageType* GetUInt8Image();
+  UInt16ImageType* GetUInt16Image();
+  Int16ImageType* GetInt16Image();
+  UInt32ImageType* GetUInt32Image();
+  Int32ImageType* GetInt32Image();
+  FloatImageType* GetFloatImage();
+  DoubleImageType* GetDoubleImage();
+
+  UInt8VectorImageType* GetUInt8VectorImage();
+  UInt16VectorImageType* GetUInt16VectorImage();
+  Int16VectorImageType* GetInt16VectorImage();
+  UInt32VectorImageType* GetUInt32VectorImage();
+  Int32VectorImageType* GetInt32VectorImage();
+  FloatVectorImageType* GetFloatVectorImage();
+  DoubleVectorImageType* GetDoubleVectorImage();
+
+  UInt8RGBImageType* GetUInt8RGBImage();
+  UInt8RGBAImageType* GetUInt8RGBAImage();
+
   /** Get the input image as templated image type. */
   template <class TImageType>
     TImageType* GetImage();
@@ -81,15 +106,6 @@ public:
   template <class TComplexInputImage, class TOutputImage>
     TOutputImage* CastImage();
 
-  /** Cast an image to an image of the same type
-  * Image to Image, VectorImage to VectorImage, RGBAImage to RGBAImage. */
-  template <class TComplexInputImage, class TOutputImage>
-    TOutputImage* SimpleCastImage();
-
-  /** Cast an image to a vector image. */
-  template <class TComplexInputImage, class TOutputImage>
-    TOutputImage* CastVectorImageFromImage();
-
   bool HasValue() const ITK_OVERRIDE;
 
   void ClearValue() ITK_OVERRIDE;
@@ -107,9 +123,6 @@ protected:
 
 
   /** Readers typedefs */
-  typedef otb::ImageFileReader<ComplexFloatImageType> ComplexFloatReaderType;
-  typedef otb::ImageFileReader<ComplexDoubleImageType> ComplexDoubleReaderType;
-
   typedef otb::ImageFileReader<ComplexFloatVectorImageType> ComplexFloatVectorReaderType;
   typedef otb::ImageFileReader<ComplexDoubleVectorImageType> ComplexDoubleVectorReaderType;
 
@@ -128,33 +141,6 @@ private:
 
 }; // End class ComplexInputImage Parameter
 
-
-// template specializations of CastImage<> should be declared in header
-// so that the linker knows they exist when building OTB Applications
-
-#define otbDefineCastImageMacro(ComplexInputImageType, OutputImageType)   \
-  template<> OutputImageType *                                          \
-  ComplexInputImageParameter::CastImage<ComplexInputImageType , OutputImageType>();   \
-
-#define otbGenericDefineCastImageMacro(ComplexInputImageType, prefix)     \
-  otbDefineCastImageMacro(ComplexInputImageType, ComplexFloat##prefix##ImageType) \
-  otbDefineCastImageMacro(ComplexInputImageType, ComplexDouble##prefix##ImageType)
-
-
-/*********************************************************************
-********************** Image -> Image
-**********************************************************************/
-
-  otbGenericDefineCastImageMacro(ComplexFloatImageType, )
-  otbGenericDefineCastImageMacro(ComplexDoubleImageType, )
-
-
-/*********************************************************************
-********************** VectorImage -> VectorImage
-**********************************************************************/
-  otbGenericDefineCastImageMacro(ComplexFloatVectorImageType, Vector)
-  otbGenericDefineCastImageMacro(ComplexDoubleVectorImageType, Vector)
-
 } // End namespace Wrapper
 } // End namespace otb
 
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx
index 774dfdbf789b8cdb48252f76e7aad13bba90399c..92e8dfd32e135ecc522a178f90a2be8fd3e1386a 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx
@@ -24,8 +24,9 @@
 #include "otbWrapperComplexInputImageParameter.h"
 
 #include "itkUnaryFunctorImageFilter.h"
-#include "itkCastImageFilter.h"
-#include "otbImageToVectorImageCastFilter.h"
+// #include "itkCastImageFilter.h"
+// #include "otbImageToVectorImageCastFilter.h"
+#include "otbClampImageFilter.h"
 
 namespace otb
 {
@@ -91,7 +92,15 @@ ComplexInputImageParameter::GetImage()
       }
     else
       {
-      if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer()))
+      if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt16VectorImageType, TOutputImage>();
+        }
+      else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt32VectorImageType, TOutputImage>();
+        }
+      else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer()))
         {
         return CastImage<ComplexFloatVectorImageType, TOutputImage>();
         }
@@ -99,6 +108,14 @@ ComplexInputImageParameter::GetImage()
         {
         return CastImage<ComplexDoubleVectorImageType, TOutputImage>();
         }
+      else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt16ImageType, TOutputImage>();
+        }
+      else if (dynamic_cast<ComplexInt32ImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt32ImageType, TOutputImage>();
+        }
       else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer()))
         {
         return CastImage<ComplexFloatImageType, TOutputImage>();
@@ -119,38 +136,10 @@ ComplexInputImageParameter::GetImage()
 template <class TComplexInputImage, class TOutputImage>
 TOutputImage*
 ComplexInputImageParameter::CastImage()
-{
-  itkExceptionMacro("Cast from "<<typeid(TComplexInputImage).name()
-                    <<" to "<<typeid(TOutputImage).name()<<" not authorized.");
-}
-
-
-template <class TComplexInputImage, class TOutputImage>
-TOutputImage*
-ComplexInputImageParameter::SimpleCastImage()
-{
-  TComplexInputImage* realComplexInputImage = dynamic_cast<TComplexInputImage*>(m_Image.GetPointer());
-
-  typedef itk::CastImageFilter<TComplexInputImage, TOutputImage> CasterType;
-  typename CasterType::Pointer caster = CasterType::New();
-
-  caster->SetInput(realComplexInputImage);
-  caster->UpdateOutputInformation();
-
-  m_Image = caster->GetOutput();
-  m_Caster = caster;
-
-  return caster->GetOutput();
-}
-
-
-template <class TComplexInputImage, class TOutputImage>
-TOutputImage*
-ComplexInputImageParameter::CastVectorImageFromImage()
 {
   TComplexInputImage* realComplexInputImage = dynamic_cast<TComplexInputImage*>(m_Image.GetPointer());
 
-  typedef ImageToVectorImageCastFilter<TComplexInputImage, TOutputImage> CasterType;
+  typedef ClampImageFilter<TComplexInputImage, TOutputImage> CasterType;
   typename CasterType::Pointer caster = CasterType::New();
 
   caster->SetInput(realComplexInputImage);
@@ -160,6 +149,8 @@ ComplexInputImageParameter::CastVectorImageFromImage()
   m_Caster = caster;
 
   return caster->GetOutput();
+  // itkExceptionMacro("Cast from "<<typeid(TComplexInputImage).name()
+  //                   <<" to "<<typeid(TOutputImage).name()<<" not authorized.");
 }
 
 template <class TComplexInputImage>
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
index 371c4d416691d36e3e07ffe50ea69c1580c20284..0613816b47f09f9c38ceafa4ad9fccbedea2582e 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
@@ -122,23 +122,18 @@ protected:
   template <class TInputVectorImageType>
     void SwitchVectorImageWrite();
 
-  //FloatVectorImageType::Pointer m_Image;
   ImageBaseType::Pointer m_Image;
   std::string            m_FileName;
   ComplexImagePixelType         m_ComplexPixelType;
   ComplexImagePixelType         m_DefaultComplexPixelType;
 
-  typedef otb::ImageFileWriter<ComplexFloatImageType>  ComplexFloatWriterType;
-  typedef otb::ImageFileWriter<ComplexDoubleImageType> ComplexDoubleWriterType;
-
-
+  typedef otb::ImageFileWriter<ComplexInt16VectorImageType>  ComplexVectorInt16WriterType;
+  typedef otb::ImageFileWriter<ComplexInt32VectorImageType>  ComplexVectorInt32WriterType;
   typedef otb::ImageFileWriter<ComplexFloatVectorImageType>  ComplexVectorFloatWriterType;
   typedef otb::ImageFileWriter<ComplexDoubleVectorImageType> ComplexVectorDoubleWriterType;
 
-
-  ComplexFloatWriterType::Pointer  m_ComplexFloatWriter;
-  ComplexDoubleWriterType::Pointer m_ComplexDoubleWriter;
-
+  ComplexVectorInt16WriterType::Pointer  m_ComplexVectorInt16Writer;
+  ComplexVectorInt32WriterType::Pointer  m_ComplexVectorInt32Writer;
   ComplexVectorFloatWriterType::Pointer  m_ComplexVectorFloatWriter;
   ComplexVectorDoubleWriterType::Pointer m_ComplexVectorDoubleWriter;
 
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
index 6ff36eedeed7f32c1382aa06be580d2904741967..3f83839de104e5bb536c821d9efa2573d13e8890 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
@@ -80,6 +80,16 @@ public:
   UInt8RGBImageType* GetUInt8RGBImage();
   UInt8RGBAImageType* GetUInt8RGBAImage();
 
+  // Complex image
+  ComplexInt16ImageType*  GetComplexInt16Image();
+  ComplexInt32ImageType*  GetComplexInt32Image();
+  ComplexFloatImageType*  GetComplexFloatImage();
+  ComplexDoubleImageType* GetComplexDoubleImage();
+
+  ComplexInt16VectorImageType*  GetComplexInt16VectorImage();
+  ComplexInt32VectorImageType*  GetComplexInt32VectorImage();
+  ComplexFloatVectorImageType*  GetComplexFloatVectorImage();
+  ComplexDoubleVectorImageType* GetComplexDoubleVectorImage();
 
   /** Get the input image as templated image type. */
   template <class TImageType>
@@ -97,17 +107,6 @@ public:
   template <class TInputImage, class TOutputImage>
   TOutputImage*  CastImage();
 
-  /** Cast an image to an image of the same type
-  * Image to Image, VectorImage to VectorImage, RGBAImage to RGBAImage. */
-  template <class TInputImage, class TOutputImage>
-    TOutputImage* SimpleCastImage();
-
-
-  /** Cast an image to a vector image. */
-  template <class TInputImage, class TOutputImage>
-    TOutputImage* CastVectorImageFromImage();
-
-
   bool HasValue() const ITK_OVERRIDE;
 
   void ClearValue() ITK_OVERRIDE;
@@ -145,6 +144,17 @@ protected:
   typedef otb::ImageFileReader<UInt8RGBImageType>  UInt8RGBReaderType;
   typedef otb::ImageFileReader<UInt8RGBAImageType> UInt8RGBAReaderType;
 
+  // Complex
+  typedef otb::ImageFileReader<ComplexInt16ImageType> ComplexInt16ReaderType;
+  typedef otb::ImageFileReader<ComplexInt32ImageType> ComplexInt32ReaderType;
+  typedef otb::ImageFileReader<ComplexFloatImageType> ComplexFloatReaderType;
+  typedef otb::ImageFileReader<ComplexDoubleImageType> ComplexDoubleReaderType;
+
+  typedef otb::ImageFileReader<ComplexInt16VectorImageType> ComplexInt16VectorReaderType;
+  typedef otb::ImageFileReader<ComplexInt32VectorImageType> ComplexInt32VectorReaderType;
+  typedef otb::ImageFileReader<ComplexFloatVectorImageType> ComplexFloatVectorReaderType;
+  typedef otb::ImageFileReader<ComplexDoubleVectorImageType> ComplexDoubleVectorReaderType;
+
   itk::ProcessObject::Pointer m_Reader;
   itk::ProcessObject::Pointer m_Caster;
 
@@ -160,63 +170,6 @@ private:
 
 }; // End class InputImage Parameter
 
-
-// template specializations of CastImage<> should be declared in header
-// so that the linker knows they exist when building OTB Applications
-
-#define otbDeclareCastImageMacro(InputImageType, OutputImageType)   \
-  template<> OTBApplicationEngine_EXPORT OutputImageType *                                          \
-  InputImageParameter::CastImage<InputImageType , OutputImageType>();    \
-
-#define otbGenericDeclareCastImageMacro(InputImageType, prefix)     \
-  otbDeclareCastImageMacro(InputImageType, UInt8##prefix##ImageType) \
-  otbDeclareCastImageMacro(InputImageType, UInt16##prefix##ImageType) \
-  otbDeclareCastImageMacro(InputImageType, Int16##prefix##ImageType) \
-  otbDeclareCastImageMacro(InputImageType, UInt32##prefix##ImageType) \
-  otbDeclareCastImageMacro(InputImageType, Int32##prefix##ImageType) \
-  otbDeclareCastImageMacro(InputImageType, Float##prefix##ImageType) \
-  otbDeclareCastImageMacro(InputImageType, Double##prefix##ImageType)
-
-
-/*********************************************************************
-********************** Image -> Image
-**********************************************************************/
-otbGenericDeclareCastImageMacro(UInt8ImageType, )
-otbGenericDeclareCastImageMacro(Int16ImageType, )
-otbGenericDeclareCastImageMacro(UInt16ImageType, )
-otbGenericDeclareCastImageMacro(Int32ImageType, )
-otbGenericDeclareCastImageMacro(UInt32ImageType, )
-otbGenericDeclareCastImageMacro(FloatImageType, )
-otbGenericDeclareCastImageMacro(DoubleImageType, )
-
-
-/*********************************************************************
-********************** VectorImage -> VectorImage
-**********************************************************************/
-otbGenericDeclareCastImageMacro(UInt8VectorImageType, Vector)
-otbGenericDeclareCastImageMacro(Int16VectorImageType, Vector)
-otbGenericDeclareCastImageMacro(UInt16VectorImageType, Vector)
-otbGenericDeclareCastImageMacro(Int32VectorImageType, Vector)
-otbGenericDeclareCastImageMacro(UInt32VectorImageType, Vector)
-otbGenericDeclareCastImageMacro(FloatVectorImageType, Vector)
-otbGenericDeclareCastImageMacro(DoubleVectorImageType, Vector)
-
-
-/*********************************************************************
-********************** Image -> VectorImage
-**********************************************************************/
-otbGenericDeclareCastImageMacro(UInt8ImageType, Vector)
-otbGenericDeclareCastImageMacro(Int16ImageType, Vector)
-otbGenericDeclareCastImageMacro(UInt16ImageType, Vector)
-otbGenericDeclareCastImageMacro(Int32ImageType, Vector)
-otbGenericDeclareCastImageMacro(UInt32ImageType, Vector)
-otbGenericDeclareCastImageMacro(FloatImageType, Vector)
-otbGenericDeclareCastImageMacro(DoubleImageType, Vector)
-
-#undef otbDeclareCastImageMacro
-#undef otbGenericDeclareCastImageMacro
-
-
 } // End namespace Wrapper
 } // End namespace otb
 
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx
index 9db0e6140868eb635b115f0b46627f956615d178..74e7385133261080cf1e05a831fbac8608f94abe 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx
@@ -24,8 +24,7 @@
 #include "otbWrapperInputImageParameter.h"
 
 #include "itkUnaryFunctorImageFilter.h"
-#include "itkCastImageFilter.h"
-#include "otbImageToVectorImageCastFilter.h"
+#include "otbClampImageFilter.h"
 
 namespace otb
 {
@@ -138,6 +137,22 @@ InputImageParameter::GetImage()
         {
         return CastImage<DoubleImageType, TImageType> ();
         }
+      else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt16ImageType, TImageType>();
+        }
+      else if (dynamic_cast<ComplexInt32ImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt32ImageType, TImageType>();
+        }
+      else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexFloatImageType, TImageType>();
+        }
+      else if (dynamic_cast<ComplexDoubleImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexDoubleImageType, TImageType>();
+        }
       else if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer()))
         {
         return CastImage<UInt8VectorImageType, TImageType> ();
@@ -174,6 +189,22 @@ InputImageParameter::GetImage()
         {
         return CastImage<UInt8RGBImageType, TImageType> ();
         }
+      else if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt16VectorImageType, TImageType>();
+        }
+      else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexInt32VectorImageType, TImageType>();
+        }
+      else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexFloatVectorImageType, TImageType>();
+        }
+      else if (dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer()))
+        {
+        return CastImage<ComplexDoubleVectorImageType, TImageType>();
+        }
       else
         {
 #if INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION
@@ -190,14 +221,6 @@ InputImageParameter::GetImage()
 template <class TInputImage, class TOutputImage>
 TOutputImage*
 InputImageParameter::CastImage()
-{
-  itkExceptionMacro("Cast from "<<typeid(TInputImage).name()<<" to "<<typeid(TOutputImage).name()<<" not authorized.");
-}
-
-
-template <class TInputImage, class TOutputImage>
-TOutputImage*
-InputImageParameter::SimpleCastImage()
 {
   if ( dynamic_cast<TOutputImage*> (m_Image.GetPointer()) )
     {
@@ -207,7 +230,7 @@ InputImageParameter::SimpleCastImage()
     {
     TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());
 
-    typedef itk::CastImageFilter<TInputImage, TOutputImage> CasterType;
+    typedef ClampImageFilter<TInputImage, TOutputImage> CasterType;
     typename CasterType::Pointer caster = CasterType::New();
 
     caster->SetInput(realInputImage);
@@ -217,29 +240,10 @@ InputImageParameter::SimpleCastImage()
     m_Caster = caster;
 
     return caster->GetOutput();
-    }
+    } 
+  // itkExceptionMacro("Cast from "<<typeid(TInputImage).name()<<" to "<<typeid(TOutputImage).name()<<" not authorized.");
 }
 
-
-template <class TInputImage, class TOutputImage>
-TOutputImage*
-InputImageParameter::CastVectorImageFromImage()
-{
-  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());
-
-  typedef ImageToVectorImageCastFilter<TInputImage, TOutputImage> CasterType;
-  typename CasterType::Pointer caster = CasterType::New();
-
-  caster->SetInput(realInputImage);
-  caster->UpdateOutputInformation();
-
-  m_Image = caster->GetOutput();
-  m_Caster = caster;
-
-  return caster->GetOutput();
-}
-
-
 template <class TInputImage>
 void
 InputImageParameter::SetImage(TInputImage* image)
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
index b420299ff6b707f8ccbed39577b488684e527fae..fd0c392b706d11977caa60031c601b046860210c 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
@@ -119,9 +119,6 @@ protected:
   /** Destructor */
   ~OutputImageParameter() ITK_OVERRIDE;
 
-  template <class TInputImageType>
-    void SwitchImageWrite();
-
   template <class TInputVectorImageType>
     void SwitchVectorImageWrite();
 
@@ -137,14 +134,6 @@ protected:
   ImagePixelType         m_PixelType;
   ImagePixelType         m_DefaultPixelType;
 
-  typedef otb::ImageFileWriter<UInt8ImageType>  UInt8WriterType;
-  typedef otb::ImageFileWriter<Int16ImageType>  Int16WriterType;
-  typedef otb::ImageFileWriter<UInt16ImageType> UInt16WriterType;
-  typedef otb::ImageFileWriter<Int32ImageType>  Int32WriterType;
-  typedef otb::ImageFileWriter<UInt32ImageType> UInt32WriterType;
-  typedef otb::ImageFileWriter<FloatImageType>  FloatWriterType;
-  typedef otb::ImageFileWriter<DoubleImageType> DoubleWriterType;
-
   typedef otb::ImageFileWriter<UInt8VectorImageType>  VectorUInt8WriterType;
   typedef otb::ImageFileWriter<Int16VectorImageType>  VectorInt16WriterType;
   typedef otb::ImageFileWriter<UInt16VectorImageType> VectorUInt16WriterType;
@@ -156,13 +145,10 @@ protected:
   typedef otb::ImageFileWriter<UInt8RGBAImageType>  RGBAUInt8WriterType;
   typedef otb::ImageFileWriter<UInt8RGBImageType>   RGBUInt8WriterType;
 
-  UInt8WriterType::Pointer  m_UInt8Writer;
-  Int16WriterType::Pointer  m_Int16Writer;
-  UInt16WriterType::Pointer m_UInt16Writer;
-  Int32WriterType::Pointer  m_Int32Writer;
-  UInt32WriterType::Pointer m_UInt32Writer;
-  FloatWriterType::Pointer  m_FloatWriter;
-  DoubleWriterType::Pointer m_DoubleWriter;
+  typedef otb::ImageFileWriter<ComplexInt16VectorImageType>  ComplexVectorInt16WriterType;
+  typedef otb::ImageFileWriter<ComplexInt32VectorImageType>  ComplexVectorInt32WriterType;
+  typedef otb::ImageFileWriter<ComplexFloatVectorImageType>  ComplexVectorFloatWriterType;
+  typedef otb::ImageFileWriter<ComplexDoubleVectorImageType> ComplexVectorDoubleWriterType;
 
   VectorUInt8WriterType::Pointer  m_VectorUInt8Writer;
   VectorInt16WriterType::Pointer  m_VectorInt16Writer;
@@ -175,6 +161,11 @@ protected:
   RGBUInt8WriterType::Pointer   m_RGBUInt8Writer;
   RGBAUInt8WriterType::Pointer  m_RGBAUInt8Writer;
 
+  ComplexVectorInt16WriterType::Pointer  m_ComplexVectorInt16Writer;
+  ComplexVectorInt32WriterType::Pointer  m_ComplexVectorInt32Writer;
+  ComplexVectorFloatWriterType::Pointer  m_ComplexVectorFloatWriter;
+  ComplexVectorDoubleWriterType::Pointer m_ComplexVectorDoubleWriter;
+
 private:
   OutputImageParameter(const Parameter &); //purposely not implemented
   void operator =(const Parameter&); //purposely not implemented
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
index 63dafb639b432a1e3508084cdcc860b7c9efc7ae..8a31e1f2c45040b1a7c69334311bdbc762c4c2fa 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
@@ -77,10 +77,16 @@ typedef enum
   ImagePixelType_uint32,
   ImagePixelType_float,
   ImagePixelType_double,
+  ImagePixelType_cint16,
+  ImagePixelType_cint32,
+  ImagePixelType_cfloat,
+  ImagePixelType_cdouble,
 } ImagePixelType;
 
 typedef enum
 {
+  ComplexImagePixelType_int16,
+  ComplexImagePixelType_int32,
   ComplexImagePixelType_float,
   ComplexImagePixelType_double,
 } ComplexImagePixelType;
@@ -119,13 +125,19 @@ typedef otb::VectorImage<double>         DoubleVectorImageType;
 typedef otb::Image< itk::RGBPixel<unsigned char> >  UInt8RGBImageType;
 typedef otb::Image< itk::RGBAPixel<unsigned char> > UInt8RGBAImageType;
 
+typedef std::complex<short>  Int16ComplexPixelType;
+typedef std::complex<int>    Int32ComplexPixelType;
 typedef std::complex<float>  FloatComplexPixelType;
 typedef std::complex<double> DoubleComplexPixelType;
 
-// Complex Image Type (first : double and float)
+// Complex Image Type
+typedef otb::Image< Int16ComplexPixelType, 2 >  ComplexInt16ImageType;
+typedef otb::Image< Int32ComplexPixelType, 2 >  ComplexInt32ImageType;
 typedef otb::Image< FloatComplexPixelType, 2 >  ComplexFloatImageType;
 typedef otb::Image< DoubleComplexPixelType, 2 > ComplexDoubleImageType;
 
+typedef otb::VectorImage< Int16ComplexPixelType, 2 >  ComplexInt16VectorImageType;
+typedef otb::VectorImage< Int32ComplexPixelType, 2 >  ComplexInt32VectorImageType;
 typedef otb::VectorImage<FloatComplexPixelType, 2 >   ComplexFloatVectorImageType;
 typedef otb::VectorImage< DoubleComplexPixelType, 2 > ComplexDoubleVectorImageType;
 
diff --git a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt
index 343f9db8354ca588189b10f7fcf625413225f1e4..45d0427a4910b17dba0d51cbbce91ebc67492940 100644
--- a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt
+++ b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt
@@ -31,13 +31,6 @@ set( OTBApplicationEngine_SRC
   otbWrapperInputFilenameListParameter.cxx
   otbWrapperOutputImageParameter.cxx
   otbWrapperInputImageParameter.cxx
-  otbWrapperInputImageParameterUInt8.cxx
-  otbWrapperInputImageParameterInt16.cxx
-  otbWrapperInputImageParameterUInt16.cxx
-  otbWrapperInputImageParameterInt32.cxx
-  otbWrapperInputImageParameterUInt32.cxx
-  otbWrapperInputImageParameterFloat.cxx
-  otbWrapperInputImageParameterDouble.cxx
   otbWrapperParameterKey.cxx
   otbWrapperDocExampleStructure.cxx
   otbWrapperInputVectorDataParameter.cxx
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx
index 6c59ad4c83753feeacf012655642eba680586279..22629f407458a925afa397824fa678456a9878d6 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx
@@ -73,14 +73,18 @@ ComplexInputImageParameter::GetImage()
     return this->GetImage< image##Type > ();          \
   }
 
+otbGetImageMacro(ComplexInt16Image);
+otbGetImageMacro(ComplexInt32Image);
 otbGetImageMacro(ComplexFloatImage);
 otbGetImageMacro(ComplexDoubleImage);
 
+otbGetImageMacro(ComplexInt16VectorImage);
+otbGetImageMacro(ComplexInt32VectorImage);
 otbGetImageMacro(ComplexFloatVectorImage);
 otbGetImageMacro(ComplexDoubleVectorImage);
 
 
-#define otbCastImageMacro(ComplexInputImageType, OutputImageType, theMethod)   \
+/*#define otbCastImageMacro(ComplexInputImageType, OutputImageType, theMethod)   \
   template<> OutputImageType *                                          \
   ComplexInputImageParameter::CastImage<ComplexInputImageType , OutputImageType>()    \
   {                                                                     \
@@ -89,22 +93,22 @@ otbGetImageMacro(ComplexDoubleVectorImage);
 
 #define otbGenericCastImageMacro(ComplexInputImageType, theMethod, prefix)     \
   otbCastImageMacro(ComplexInputImageType, ComplexFloat##prefix##ImageType, theMethod) \
-  otbCastImageMacro(ComplexInputImageType, ComplexDouble##prefix##ImageType, theMethod)
+  otbCastImageMacro(ComplexInputImageType, ComplexDouble##prefix##ImageType, theMethod)*/
 
 
-/*********************************************************************
+/********************************************************************
 ********************** Image -> Image
-**********************************************************************/
+*********************************************************************/
 
-  otbGenericCastImageMacro(ComplexFloatImageType, SimpleCastImage, )
-  otbGenericCastImageMacro(ComplexDoubleImageType, SimpleCastImage, )
+//   otbGenericCastImageMacro(ComplexFloatImageType, SimpleCastImage, )
+//   otbGenericCastImageMacro(ComplexDoubleImageType, SimpleCastImage, )
 
 
 /*********************************************************************
 ********************** VectorImage -> VectorImage
 **********************************************************************/
-  otbGenericCastImageMacro(ComplexFloatVectorImageType, SimpleCastImage, Vector)
-  otbGenericCastImageMacro(ComplexDoubleVectorImageType, SimpleCastImage, Vector)
+//   otbGenericCastImageMacro(ComplexFloatVectorImageType, SimpleCastImage, Vector)
+//   otbGenericCastImageMacro(ComplexDoubleVectorImageType, SimpleCastImage, Vector)
 
   void
 ComplexInputImageParameter::SetImage(ComplexFloatVectorImageType* image)
@@ -133,6 +137,38 @@ ComplexInputImageParameter::ClearValue()
   m_UseFilename = true;
 }
 
+/* Support for ComplexInputImageParameter. This has been done to support 
+the macro otbGetParameterImageMacro of otbWrapperApplication.h */
+#define otbGetFalseImageMacro(image)                  \
+  image##Type *                                       \
+  ComplexInputImageParameter::Get##image ()           \
+  {                                                   \
+    return nullptr;                                   \
+  }
+
+otbGetFalseImageMacro(DoubleImage);
+otbGetFalseImageMacro(DoubleVectorImage);
+
+otbGetFalseImageMacro(FloatImage);
+otbGetFalseImageMacro(FloatVectorImage);
+
+otbGetFalseImageMacro(Int16Image);
+otbGetFalseImageMacro(Int16VectorImage);
+
+otbGetFalseImageMacro(UInt16Image);
+otbGetFalseImageMacro(UInt16VectorImage);
+
+otbGetFalseImageMacro(Int32Image);
+otbGetFalseImageMacro(Int32VectorImage);
+
+otbGetFalseImageMacro(UInt32Image);
+otbGetFalseImageMacro(UInt32VectorImage);
+
+otbGetFalseImageMacro(UInt8Image);
+otbGetFalseImageMacro(UInt8VectorImage);
+
+otbGetFalseImageMacro(UInt8RGBImage);
+otbGetFalseImageMacro(UInt8RGBAImage);
 
 }
 }
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
index 64ef3657181d767341ce804d642374d6ed7b6a27..6d86118c4591da5f17e8a932356fbede5d2cdc3d 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
@@ -20,8 +20,7 @@
 
 #include "otbWrapperComplexOutputImageParameter.h"
 #include "itkUnaryFunctorImageFilter.h"
-#include "itkCastImageFilter.h"
-#include "itkVectorCastImageFilter.h"
+#include "otbClampImageFilter.h"
 
 #ifdef OTB_USE_MPI
 
@@ -59,6 +58,16 @@ ComplexOutputImageParameter::ConvertPixelTypeToString(ComplexImagePixelType type
   std::string ret;
   switch(type)
     {
+    case ComplexImagePixelType_int16:
+      {
+      ret = "cint16";
+      break;
+      }
+    case ComplexImagePixelType_int32:
+      {
+      ret = "cint32";
+      break;
+      }
     case ComplexImagePixelType_float:
       {
       ret = "cfloat";
@@ -76,7 +85,11 @@ ComplexOutputImageParameter::ConvertPixelTypeToString(ComplexImagePixelType type
 bool
 ComplexOutputImageParameter::ConvertStringToPixelType(const std::string &value, ComplexImagePixelType &type)
 {
-  if (value == "cfloat")
+  if (value == "cint16")
+    type = ComplexImagePixelType_int16;
+  if (value == "cint32")
+    type = ComplexImagePixelType_int32;
+  else if (value == "cfloat")
     type = ComplexImagePixelType_float;
   else if (value == "cdouble")
     type = ComplexImagePixelType_double;
@@ -87,16 +100,15 @@ ComplexOutputImageParameter::ConvertStringToPixelType(const std::string &value,
 
 void ComplexOutputImageParameter::InitializeWriters()
 {
-  m_ComplexFloatWriter = ComplexFloatWriterType::New();
-  m_ComplexDoubleWriter = ComplexDoubleWriterType::New();
-
+  m_ComplexVectorInt16Writer = ComplexVectorInt16WriterType::New();
+  m_ComplexVectorInt32Writer = ComplexVectorInt32WriterType::New();
   m_ComplexVectorFloatWriter = ComplexVectorFloatWriterType::New();
   m_ComplexVectorDoubleWriter = ComplexVectorDoubleWriterType::New();
 }
 
 template <typename TInput, typename TOutput> void CastAndWriteImage(itk::ImageBase<2> * in, otb::ImageFileWriter<TOutput> * writer, const std::string & filename, const unsigned int & ramValue)
 {
-  typedef itk::CastImageFilter<TInput, TOutput> ClampFilterType; 
+  typedef ClampImageFilter<TInput, TOutput> ClampFilterType; 
   typename ClampFilterType::Pointer clampFilter = ClampFilterType::New();         
   clampFilter->SetInput( dynamic_cast<TInput*>(in));
   
@@ -157,46 +169,58 @@ ComplexOutputImageParameter::SwitchImageWrite()
 {
   switch(m_ComplexPixelType )
     {
-    case ComplexImagePixelType_float:
+    case ComplexImagePixelType_int16:
     {
-    CastAndWriteImage<TInputImageType,ComplexFloatImageType>(m_Image,m_ComplexFloatWriter,m_FileName,m_RAMValue);
+    CastAndWriteImage<TInputImageType,ComplexInt16VectorImageType>(
+      m_Image ,
+      m_ComplexVectorInt16Writer ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
-    case ComplexImagePixelType_double:
+    case ComplexImagePixelType_int32:
     {
-    CastAndWriteImage<TInputImageType,ComplexDoubleImageType>(m_Image,m_ComplexDoubleWriter,m_FileName,m_RAMValue);
+    CastAndWriteImage<TInputImageType,ComplexInt32VectorImageType>(
+      m_Image ,
+      m_ComplexVectorInt32Writer ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
-    }
-}
-
-
-template <class TInputVectorImageType>
-void
-ComplexOutputImageParameter::SwitchVectorImageWrite()
-  {
-  switch(m_ComplexPixelType )
-    {
     case ComplexImagePixelType_float:
     {
-    CastAndWriteImage<TInputVectorImageType,ComplexFloatVectorImageType>(m_Image,m_ComplexVectorFloatWriter,m_FileName,m_RAMValue);
+    CastAndWriteImage<TInputImageType,ComplexFloatVectorImageType>(
+      m_Image ,
+      m_ComplexVectorFloatWriter ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     case ComplexImagePixelType_double:
     {
-    CastAndWriteImage<TInputVectorImageType,ComplexDoubleVectorImageType>(m_Image,m_ComplexVectorDoubleWriter,m_FileName,m_RAMValue);
+    CastAndWriteImage<TInputImageType,ComplexDoubleVectorImageType>(
+      m_Image ,
+      m_ComplexVectorDoubleWriter ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     }
-  }
-
+}
 
 void
 ComplexOutputImageParameter::Write()
 {
   m_Image->UpdateOutputInformation();
-
-  if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer()))
+  if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer()))
+    {
+    SwitchImageWrite<ComplexInt16ImageType>();
+    }
+  else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer()))
+    {
+    SwitchImageWrite<ComplexInt16ImageType>();
+    }
+  else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer()))
     {
     SwitchImageWrite<ComplexFloatImageType>();
     }
@@ -204,13 +228,21 @@ ComplexOutputImageParameter::Write()
     {
     SwitchImageWrite<ComplexDoubleImageType>();
     }
+  else if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer()))
+    {
+    SwitchImageWrite<ComplexInt16VectorImageType>();
+    }
+  else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer()))
+    {
+    SwitchImageWrite<ComplexInt32VectorImageType>();
+    }
   else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer()))
     {
-    SwitchVectorImageWrite<ComplexFloatVectorImageType>();
+    SwitchImageWrite<ComplexFloatVectorImageType>();
     }
   else if (dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer()))
     {
-    SwitchVectorImageWrite<ComplexDoubleVectorImageType>();
+    SwitchImageWrite<ComplexDoubleVectorImageType>();
     }
   else
     {
@@ -221,33 +253,25 @@ ComplexOutputImageParameter::Write()
 itk::ProcessObject*
 ComplexOutputImageParameter::GetWriter()
 {
-  int type = 0;
-  // 0 : image
-  // 1 : VectorImage
-
-  if ( dynamic_cast<ComplexFloatVectorImageType*>( m_Image.GetPointer()) ||
-       dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer()))
-    {
-    type = 1;
-    }
-
   itk::ProcessObject* writer = ITK_NULLPTR;
   switch ( GetComplexPixelType() )
     {
+    case ComplexImagePixelType_int16:
+    {
+      writer = m_ComplexVectorInt16Writer;
+    }
+    case ComplexImagePixelType_int32:
+    {
+      writer = m_ComplexVectorInt32Writer;
+    }
     case ComplexImagePixelType_float:
     {
-    if( type == 1 )
       writer = m_ComplexVectorFloatWriter;
-    else
-      writer = m_ComplexFloatWriter;
     break;
     }
     case ComplexImagePixelType_double:
     {
-    if( type == 1 )
       writer = m_ComplexVectorDoubleWriter;
-    else
-      writer = m_ComplexDoubleWriter;
     break;
     }
     }
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
index f645553e03907713a71ffd57b2dcab6539d88ec5..726f1dbe3ca72c67b825b2a6a385844dbc826319 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
@@ -57,7 +57,11 @@ void ElevationParametersHandler::AddElevationParameters(Application::Pointer app
   oss.str("");
   oss << key<<".geoid";
   app->AddParameter(ParameterType_InputFilename, oss.str(), "Geoid File");
-  app->SetParameterDescription(oss.str(),"Use a geoid grid to get the height above the ellipsoid in case there is no DEM available, no coverage for some points or pixels with no_data in the DEM tiles. A version of the geoid can be found on the OTB website (https://git.orfeo-toolbox.org/otb-data.git/blob/HEAD:/Input/DEM/egm96.grd).");
+  app->SetParameterDescription(oss.str(),"Use a geoid grid to get the height "
+    "above the ellipsoid in case there is no DEM available, no coverage for "
+    "some points or pixels with no_data in the DEM tiles. A version of the "
+    "geoid can be found on the OTB website"
+    "(https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data/blob/master/Input/DEM/egm96.grd).");
   app->MandatoryOff(oss.str());
 
   std::string geoidFromConfig = otb::ConfigurationManager::GetGeoidFile();
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx
index 166ab2956ad5fc46a6bd1df6a1298e3066b4f23f..fe226ef2ffbd7ccb6f588e3926642181c31819ea 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx
@@ -70,6 +70,17 @@ InputImageParameter::GetImage()
 
 otbGetImageMacro(UInt8RGBImage);
 otbGetImageMacro(UInt8RGBAImage);
+otbGetImageAndVectorImageMacro(UInt8);
+otbGetImageAndVectorImageMacro(UInt16);
+otbGetImageAndVectorImageMacro(UInt32);
+otbGetImageAndVectorImageMacro(Int16);
+otbGetImageAndVectorImageMacro(Int32);
+otbGetImageAndVectorImageMacro(Float);
+otbGetImageAndVectorImageMacro(Double);
+otbGetImageAndVectorImageMacro(ComplexInt16);
+otbGetImageAndVectorImageMacro(ComplexInt32);
+otbGetImageAndVectorImageMacro(ComplexFloat);
+otbGetImageAndVectorImageMacro(ComplexDouble);
 
 
 void
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx
deleted file mode 100644
index e6a07bc294ff440924d5efa5f42f5634cffd1081..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbWrapperInputImageParameter.h"
-#include "itksys/SystemTools.hxx"
-#include "otbWrapperTypes.h"
-#include "otbWrapperInputImageParameterMacros.h"
-#include "otb_boost_string_header.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-otbGetImageMacro(DoubleImage);
-otbGetImageMacro(DoubleVectorImage)
-otbGenericCastImageMacro(DoubleImageType, SimpleCastImage, )
-otbGenericCastImageMacro(DoubleVectorImageType, SimpleCastImage, Vector)
-otbGenericCastImageMacro(DoubleImageType, CastVectorImageFromImage, Vector)
-}
-}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx
deleted file mode 100644
index fda1544048718215b7dd7757d37baeee12fbb6af..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbWrapperInputImageParameter.h"
-#include "otbWrapperInputImageParameterMacros.h"
-#include "itksys/SystemTools.hxx"
-#include "otbWrapperTypes.h"
-#include "otb_boost_string_header.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-otbGetImageMacro(FloatImage);
-otbGetImageMacro(FloatVectorImage)
-otbGenericCastImageMacro(FloatImageType, SimpleCastImage, )
-otbGenericCastImageMacro(FloatVectorImageType, SimpleCastImage, Vector)
-otbGenericCastImageMacro(FloatImageType, CastVectorImageFromImage, Vector)
-}
-}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx
deleted file mode 100644
index 22f617fce468169f23ed64db00e695902430f127..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbWrapperInputImageParameter.h"
-#include "itksys/SystemTools.hxx"
-#include "otbWrapperTypes.h"
-#include "otbWrapperInputImageParameterMacros.h"
-#include "otb_boost_string_header.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-otbGetImageMacro(Int16Image);
-otbGetImageMacro(Int16VectorImage)
-otbGenericCastImageMacro(Int16ImageType, SimpleCastImage, )
-otbGenericCastImageMacro(Int16VectorImageType, SimpleCastImage, Vector)
-otbGenericCastImageMacro(Int16ImageType, CastVectorImageFromImage, Vector)
-}
-}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx
deleted file mode 100644
index ab59107c9e357068ef461bd3b975ec3e16d524b2..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbWrapperInputImageParameter.h"
-#include "itksys/SystemTools.hxx"
-#include "otbWrapperTypes.h"
-#include "otbWrapperInputImageParameterMacros.h"
-#include "otb_boost_string_header.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-otbGetImageMacro(Int32Image);
-otbGetImageMacro(Int32VectorImage)
-otbGenericCastImageMacro(Int32ImageType, SimpleCastImage, )
-otbGenericCastImageMacro(Int32VectorImageType, SimpleCastImage, Vector)
-otbGenericCastImageMacro(Int32ImageType, CastVectorImageFromImage, Vector)
-}
-}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h
index 4cc9d4d7ae998e8aec82b0856b8ac6e44dcad377..2f1a7915b4f9b1491fde3ba0f9d77fc004e9e021 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h
@@ -28,22 +28,9 @@
     return this->GetImage< image##Type > ();          \
   }
 
-
-#define otbCastImageMacro(InputImageType, OutputImageType, theMethod)   \
-  template<> OutputImageType *                                          \
-  InputImageParameter::CastImage<InputImageType , OutputImageType>()    \
-  {                                                                     \
-    return this->theMethod<InputImageType , OutputImageType>();         \
-  }
-
-#define otbGenericCastImageMacro(InputImageType, theMethod, prefix)     \
-  otbCastImageMacro(InputImageType, UInt8##prefix##ImageType, theMethod) \
-  otbCastImageMacro(InputImageType, UInt16##prefix##ImageType, theMethod) \
-  otbCastImageMacro(InputImageType, Int16##prefix##ImageType, theMethod) \
-  otbCastImageMacro(InputImageType, UInt32##prefix##ImageType, theMethod) \
-  otbCastImageMacro(InputImageType, Int32##prefix##ImageType, theMethod) \
-  otbCastImageMacro(InputImageType, Float##prefix##ImageType, theMethod) \
-  otbCastImageMacro(InputImageType, Double##prefix##ImageType, theMethod)
+#define otbGetImageAndVectorImageMacro(type) \
+  otbGetImageMacro(type##Image);             \
+  otbGetImageMacro(type##VectorImage); 
 
 
 #endif
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx
deleted file mode 100644
index c63857e57bd7bfd30fb466f74e9e36bcc1ddeea7..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbWrapperInputImageParameter.h"
-#include "itksys/SystemTools.hxx"
-#include "otbWrapperTypes.h"
-#include "otbWrapperInputImageParameterMacros.h"
-#include "otb_boost_string_header.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-otbGetImageMacro(UInt16Image);
-otbGetImageMacro(UInt16VectorImage)
-otbGenericCastImageMacro(UInt16ImageType, SimpleCastImage, )
-otbGenericCastImageMacro(UInt16VectorImageType, SimpleCastImage, Vector)
-otbGenericCastImageMacro(UInt16ImageType, CastVectorImageFromImage, Vector)
-}
-}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx
deleted file mode 100644
index 50fdf0adf18aefe30b7b1efac80f2b5028619565..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbWrapperInputImageParameter.h"
-#include "itksys/SystemTools.hxx"
-#include "otbWrapperTypes.h"
-#include "otbWrapperInputImageParameterMacros.h"
-#include "otb_boost_string_header.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-otbGetImageMacro(UInt32Image);
-otbGetImageMacro(UInt32VectorImage)
-otbGenericCastImageMacro(UInt32ImageType, SimpleCastImage, )
-otbGenericCastImageMacro(UInt32VectorImageType, SimpleCastImage, Vector)
-otbGenericCastImageMacro(UInt32ImageType, CastVectorImageFromImage, Vector)
-}
-}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx
deleted file mode 100644
index d388456e4267e8ba0753d54ff05439657d2c2e13..0000000000000000000000000000000000000000
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbWrapperInputImageParameter.h"
-#include "itksys/SystemTools.hxx"
-#include "otbWrapperTypes.h"
-#include "otbWrapperInputImageParameterMacros.h"
-#include "otb_boost_string_header.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-otbGetImageMacro(UInt8Image);
-otbGetImageMacro(UInt8VectorImage)
-otbGenericCastImageMacro(UInt8ImageType, SimpleCastImage, )
-otbGenericCastImageMacro(UInt8VectorImageType, SimpleCastImage, Vector)
-otbGenericCastImageMacro(UInt8ImageType, CastVectorImageFromImage, Vector)
-}
-}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
index 2790bdce255aa5d0e8a3f92ab625e274ce48bf10..d0dd6678797767b6f50d61ba0a9667173d1a77e1 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
@@ -20,7 +20,6 @@
 
 #include "otbWrapperOutputImageParameter.h"
 #include "otbClampImageFilter.h"
-#include "otbClampVectorImageFilter.h"
 #include "otbImageIOFactory.h"
 #include "itksys/SystemTools.hxx"
 
@@ -94,6 +93,26 @@ std::string OutputImageParameter::ConvertPixelTypeToString(ImagePixelType type)
       ret = "double";
       break;
       }
+    case ImagePixelType_cint16:
+      {
+      ret = "cint16";
+      break;
+      }
+    case ImagePixelType_cint32:
+      {
+      ret = "cint32";
+      break;
+      }
+    case ImagePixelType_cfloat:
+      {
+      ret = "cfloat";
+      break;
+      }
+    case ImagePixelType_cdouble:
+      {
+      ret = "cdouble";
+      break;
+      }
     }
   return ret;
 }
@@ -115,6 +134,14 @@ OutputImageParameter::ConvertStringToPixelType(const std::string &value, ImagePi
     type = ImagePixelType_float;
   else if (value == "double")
     type = ImagePixelType_double;
+  else if (value == "cint16")
+    type = ImagePixelType_cint16;
+  else if (value == "cint32")
+    type = ImagePixelType_cint32;
+  else if (value == "cfloat")
+    type = ImagePixelType_cfloat;
+  else if (value == "cdouble")
+    type = ImagePixelType_cdouble;
   else
     return false;
   return true;
@@ -122,14 +149,6 @@ OutputImageParameter::ConvertStringToPixelType(const std::string &value, ImagePi
 
 void OutputImageParameter::InitializeWriters()
 {
-  m_UInt8Writer = UInt8WriterType::New();
-  m_Int16Writer = Int16WriterType::New();
-  m_UInt16Writer = UInt16WriterType::New();
-  m_Int32Writer = Int32WriterType::New();
-  m_UInt32Writer = UInt32WriterType::New();
-  m_FloatWriter = FloatWriterType::New();
-  m_DoubleWriter = DoubleWriterType::New();
-
   m_VectorUInt8Writer = VectorUInt8WriterType::New();
   m_VectorInt16Writer = VectorInt16WriterType::New();
   m_VectorUInt16Writer = VectorUInt16WriterType::New();
@@ -140,13 +159,24 @@ void OutputImageParameter::InitializeWriters()
 
   m_RGBUInt8Writer = RGBUInt8WriterType::New();
   m_RGBAUInt8Writer = RGBAUInt8WriterType::New();
+
+  m_ComplexVectorInt16Writer = ComplexVectorInt16WriterType::New();
+  m_ComplexVectorInt32Writer = ComplexVectorInt32WriterType::New();
+  m_ComplexVectorFloatWriter = ComplexVectorFloatWriterType::New();
+  m_ComplexVectorDoubleWriter = ComplexVectorDoubleWriterType::New();
 }
 
 
-template <typename TInput, typename TOutput> void ClampAndWriteImage(itk::ImageBase<2> * in, otb::ImageFileWriter<TOutput> * writer, const std::string & filename, const unsigned int & ramValue)
+template <typename TInput, typename TOutput> 
+void 
+ClampAndWriteVectorImage( itk::ImageBase<2> * in ,
+                    otb::ImageFileWriter<TOutput> * writer , 
+                    const std::string & filename , 
+                    const unsigned int & ramValue )
 {
-  typedef otb::ClampImageFilter<TInput, TOutput> ClampFilterType; 
-  typename ClampFilterType::Pointer clampFilter = ClampFilterType::New();         
+  typedef ClampImageFilter < TInput , TOutput > ClampFilterType;
+  typename ClampFilterType::Pointer clampFilter ( ClampFilterType::New() );
+
   clampFilter->SetInput( dynamic_cast<TInput*>(in));
   
   bool useStandardWriter = true;
@@ -200,152 +230,116 @@ template <typename TInput, typename TOutput> void ClampAndWriteImage(itk::ImageB
     }
 }
 
-template <typename TInput, typename TOutput > void ClampAndWriteVectorImage(itk::ImageBase<2> * in, otb::ImageFileWriter<TOutput > * writer, const std::string & filename, const unsigned int & ramValue)
-{
-  typedef otb::ClampVectorImageFilter<TInput, TOutput> ClampFilterType; 
-  typename ClampFilterType::Pointer clampFilter = ClampFilterType::New();         
-  clampFilter->SetInput( dynamic_cast<TInput*>(in));
-  
-  bool useStandardWriter = true;
-  
-#ifdef OTB_USE_MPI
-  
-  otb::MPIConfig::Pointer mpiConfig = otb::MPIConfig::Instance();
-  
-  if (mpiConfig->GetNbProcs() > 1)
-    {
-    useStandardWriter = false;
-    
-    // Get file extension
-    std::string extension = itksys::SystemTools::GetFilenameExtension(filename);
-    
-    if(extension == ".vrt")
-      {
-      // Use the WriteMPI function
-      WriteMPI(clampFilter->GetOutput(),filename,ramValue);      
-      }
-    #ifdef OTB_USE_SPTW
-    else if (extension == ".tif")
-      {
-      // Use simple parallel tiff writer
-      typedef otb::SimpleParallelTiffWriter<TOutput> SPTWriterType;
-      
-      typename SPTWriterType::Pointer sptWriter = SPTWriterType::New();
-      sptWriter->SetFileName(filename);
-      sptWriter->SetInput(clampFilter->GetOutput());
-      sptWriter->SetAutomaticAdaptativeStreaming(ramValue);
-      sptWriter->Update();
-      }
-    
-    #endif
-    else
-      {
-      itkGenericExceptionMacro("File format "<<extension<<" not supported for parallel writing with MPI. Supported formats are .vrt and .tif. Extended filenames are not supported.");
-      }
-    }
-  #endif
-  
-  if(useStandardWriter)
-    {
-    
-    writer->SetFileName( filename );                                     
-    writer->SetInput(clampFilter->GetOutput());                                     
-    writer->SetAutomaticAdaptativeStreaming(ramValue);
-    writer->Update();
-    }
-}
-
-
-template <class TInputImageType>
+template <class TInput>
 void
-OutputImageParameter::SwitchImageWrite()
-{
+OutputImageParameter::SwitchVectorImageWrite()
+  {
   switch(m_PixelType )
     {
     case ImagePixelType_uint8:
     {
-    ClampAndWriteImage<TInputImageType,UInt8ImageType>(m_Image,m_UInt8Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage< TInput , UInt8VectorImageType > (
+      m_Image ,
+      m_VectorUInt8Writer ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     case ImagePixelType_int16:
     {
-    ClampAndWriteImage<TInputImageType,Int16ImageType>(m_Image,m_Int16Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage< TInput , Int16VectorImageType > (
+      m_Image ,
+      m_VectorInt16Writer ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     case ImagePixelType_uint16:
     {
-    ClampAndWriteImage<TInputImageType,UInt16ImageType>(m_Image,m_UInt16Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage< TInput , UInt16VectorImageType > (
+      m_Image ,
+      m_VectorUInt16Writer ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     case ImagePixelType_int32:
     {
-    ClampAndWriteImage<TInputImageType,Int32ImageType>(m_Image,m_Int32Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage< TInput , Int32VectorImageType > (
+      m_Image ,
+      m_VectorInt32Writer ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     case ImagePixelType_uint32:
     {
-    ClampAndWriteImage<TInputImageType,UInt32ImageType>(m_Image,m_UInt32Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage< TInput , UInt32VectorImageType > (
+      m_Image ,
+      m_VectorUInt32Writer ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     case ImagePixelType_float:
     {
-    ClampAndWriteImage<TInputImageType,FloatImageType>(m_Image,m_FloatWriter,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage< TInput , FloatVectorImageType > (
+      m_Image ,
+      m_VectorFloatWriter ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
     case ImagePixelType_double:
     {
-    ClampAndWriteImage<TInputImageType,DoubleImageType>(m_Image,m_DoubleWriter,m_FileName,m_RAMValue);
-    break;
-    }
-    }
-}
-
-
-template <class TInputVectorImageType>
-void
-OutputImageParameter::SwitchVectorImageWrite()
-  {
-  switch(m_PixelType )
-    {
-    case ImagePixelType_uint8:
-    {
-    ClampAndWriteVectorImage<TInputVectorImageType,UInt8VectorImageType>(m_Image,m_VectorUInt8Writer,m_FileName,m_RAMValue);
-    break;
-    }
-    case ImagePixelType_int16:
-    {
-    ClampAndWriteVectorImage<TInputVectorImageType,Int16VectorImageType>(m_Image,m_VectorInt16Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage< TInput , DoubleVectorImageType > (
+      m_Image ,
+      m_VectorDoubleWriter ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
-    case ImagePixelType_uint16:
+    case ImagePixelType_cint16:
     {
-    ClampAndWriteVectorImage<TInputVectorImageType,UInt16VectorImageType>(m_Image,m_VectorUInt16Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage < TInput , ComplexInt16VectorImageType > (
+      m_Image ,
+      m_ComplexVectorInt16Writer ,
+      m_FileName ,
+      m_RAMValue ); 
     break;
     }
-    case ImagePixelType_int32:
+    case ImagePixelType_cint32:
     {
-    ClampAndWriteVectorImage<TInputVectorImageType,Int32VectorImageType>(m_Image,m_VectorInt32Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage < TInput , ComplexInt32VectorImageType > (
+      m_Image ,
+      m_ComplexVectorInt32Writer ,
+      m_FileName ,
+      m_RAMValue ); 
     break;
     }
-    case ImagePixelType_uint32:
+    case ImagePixelType_cfloat:
     {
-    ClampAndWriteVectorImage<TInputVectorImageType,UInt32VectorImageType>(m_Image,m_VectorUInt32Writer,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage < TInput , ComplexFloatVectorImageType > (
+      m_Image ,
+      m_ComplexVectorFloatWriter ,
+      m_FileName ,
+      m_RAMValue ); 
     break;
     }
-    case ImagePixelType_float:
+    case ImagePixelType_cdouble:
     {
-    ClampAndWriteVectorImage<TInputVectorImageType,FloatVectorImageType>(m_Image,m_VectorFloatWriter,m_FileName,m_RAMValue);
-    break;
-    }
-    case ImagePixelType_double:
-    {
-    ClampAndWriteVectorImage<TInputVectorImageType,DoubleVectorImageType>(m_Image,m_VectorDoubleWriter,m_FileName,m_RAMValue);
+    ClampAndWriteVectorImage < TInput , ComplexDoubleVectorImageType > (
+      m_Image ,
+      m_ComplexVectorDoubleWriter ,
+      m_FileName ,
+      m_RAMValue );
     break;
     }
+    default:
+      break;
     }
   }
 
-
 template <class TInputRGBAImageType>
 void
 OutputImageParameter::SwitchRGBAImageWrite()
@@ -383,31 +377,47 @@ OutputImageParameter::Write()
 
   if (dynamic_cast<UInt8ImageType*>(m_Image.GetPointer()))
     {
-    SwitchImageWrite<UInt8ImageType>();
+    SwitchVectorImageWrite<UInt8ImageType>();
     }
   else if (dynamic_cast<Int16ImageType*>(m_Image.GetPointer()))
     {
-    SwitchImageWrite<Int16ImageType>();
+    SwitchVectorImageWrite<Int16ImageType>();
     }
   else if (dynamic_cast<UInt16ImageType*>(m_Image.GetPointer()))
     {
-    SwitchImageWrite<UInt16ImageType>();
+    SwitchVectorImageWrite<UInt16ImageType>();
     }
   else if (dynamic_cast<Int32ImageType*>(m_Image.GetPointer()))
     {
-    SwitchImageWrite<Int32ImageType>();
+    SwitchVectorImageWrite<Int32ImageType>();
     }
   else if (dynamic_cast<UInt32ImageType*>(m_Image.GetPointer()))
     {
-    SwitchImageWrite<UInt32ImageType>();
+    SwitchVectorImageWrite<UInt32ImageType>();
     }
   else if (dynamic_cast<FloatImageType*>(m_Image.GetPointer()))
     {
-    SwitchImageWrite<FloatImageType>();
+    SwitchVectorImageWrite<FloatImageType>();
     }
   else if (dynamic_cast<DoubleImageType*>(m_Image.GetPointer()))
     {
-    SwitchImageWrite<DoubleImageType>();
+    SwitchVectorImageWrite<DoubleImageType>();
+    }
+  else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer()) )
+    {
+    SwitchVectorImageWrite<ComplexInt16ImageType>();
+    }
+  else if (dynamic_cast<ComplexInt32ImageType*>(m_Image.GetPointer()) )
+    {
+    SwitchVectorImageWrite<ComplexInt32ImageType>();
+    }
+  else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer()) )
+    {
+    SwitchVectorImageWrite<ComplexFloatImageType>();
+    }
+  else if (dynamic_cast<ComplexDoubleImageType*>(m_Image.GetPointer()) )
+    {
+    SwitchVectorImageWrite<ComplexDoubleImageType>();
     }
   else if (dynamic_cast<UInt8VectorImageType*>(m_Image.GetPointer()))
     {
@@ -437,6 +447,22 @@ OutputImageParameter::Write()
     {
     SwitchVectorImageWrite<DoubleVectorImageType>();
     }
+  else if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer()))
+    {
+    SwitchVectorImageWrite<ComplexInt16VectorImageType>();
+    }
+  else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer()))
+    {
+    SwitchVectorImageWrite<ComplexInt32VectorImageType>();
+    }
+  else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer()))
+    {
+    SwitchVectorImageWrite<ComplexFloatVectorImageType>();
+    }
+  else if (dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer()))
+    {
+    SwitchVectorImageWrite<ComplexDoubleVectorImageType>();
+    }
   else if (dynamic_cast<UInt8RGBImageType*>(m_Image.GetPointer()))
     {
     SwitchRGBImageWrite<UInt8RGBImageType>();
@@ -455,23 +481,14 @@ OutputImageParameter::Write()
 itk::ProcessObject*
 OutputImageParameter::GetWriter()
 {
-  int type = 0;
+  int type = 1;
   // 0 : image
   // 1 : VectorImage
   // 2 : RGBAImage
   // 3 : RGBImage
   itk::ProcessObject* writer = ITK_NULLPTR;
-  if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer())
-      || dynamic_cast<Int16VectorImageType*> (m_Image.GetPointer())
-      || dynamic_cast<UInt16VectorImageType*> (m_Image.GetPointer())
-      || dynamic_cast<Int32VectorImageType*> (m_Image.GetPointer())
-      || dynamic_cast<UInt32VectorImageType*> (m_Image.GetPointer())
-      || dynamic_cast<FloatVectorImageType*> (m_Image.GetPointer())
-      || dynamic_cast<DoubleVectorImageType*> (m_Image.GetPointer()))
-    {
-    type = 1;
-    }
-  else if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer()))
+
+  if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer()))
     {
     type = 2;
     writer = m_RGBAUInt8Writer;
@@ -492,9 +509,6 @@ OutputImageParameter::GetWriter()
       {
       switch(type)
         {
-        case 0:
-          writer = m_UInt8Writer;
-          break;
         case 1:
           writer = m_VectorUInt8Writer;
           break;
@@ -511,48 +525,60 @@ OutputImageParameter::GetWriter()
       {
       if (type == 1)
         writer = m_VectorInt16Writer;
-      else
-        if (type == 0) writer = m_Int16Writer;
       break;
       }
     case ImagePixelType_uint16:
       {
       if (type == 1)
         writer = m_VectorUInt16Writer;
-      else
-        if (type == 0) writer = m_UInt16Writer;
       break;
       }
     case ImagePixelType_int32:
       {
       if (type == 1)
         writer = m_VectorInt32Writer;
-      else
-        if (type == 0) writer = m_Int32Writer;
       break;
       }
     case ImagePixelType_uint32:
       {
       if (type == 1)
         writer = m_VectorUInt32Writer;
-      else
-        if (type == 0) writer = m_UInt32Writer;
       break;
       }
     case ImagePixelType_float:
       {
       if (type == 1)
         writer = m_VectorFloatWriter;
-      else
-        if (type == 0) writer = m_FloatWriter;
       break;
       }
     case ImagePixelType_double:
       {
       if (type == 1)
         writer = m_VectorDoubleWriter;
-      else
-        if (type == 0) writer = m_DoubleWriter;
+      break;
+      }
+    case ImagePixelType_cint16:
+      {
+      if( type == 1 )
+        writer = m_ComplexVectorInt16Writer;
+      break;
+      }
+    case ImagePixelType_cint32:
+      {
+      if( type == 1 )
+        writer = m_ComplexVectorInt32Writer;
+      break;
+      }
+    case ImagePixelType_cfloat:
+      {
+      if( type == 1 )
+        writer = m_ComplexVectorFloatWriter;
+      break;
+      }
+    case ImagePixelType_cdouble:
+      {
+      if( type == 1 )
+        writer = m_ComplexVectorDoubleWriter;
       break;
       }
     }
diff --git a/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt
index 860c8673636aff84ee7d5ae5f26c9c5ab0bc733d..319466cb4c49d21b321d55aa57ff0df847f56a53 100644
--- a/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt
+++ b/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt
@@ -171,6 +171,12 @@ otb_add_test(NAME owTvOutputImageParameter COMMAND otbApplicationEngineTestDrive
   "my description"
   )
 
+#~ otb_add_test(NAME owTvOutputImageParameterConversion COMMAND otbApplicationEngineTestDriver
+  #~ otbWrapperOutputImageParameterConversionTest
+  #~ ${INPUTDATA}/poupees.tif
+  #~ ${TEMP}/poupees_out.tif
+  #~ )
+
 otb_add_test(NAME owTvDocExampleStructureTest COMMAND otbApplicationEngineTestDriver
   --compare-ascii ${NOTOL}
   ${BASELINE}/owTuDocExampleStructureTest.txt
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx b/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx
index f5b3aabf3d5b4642044293927422883c491198f1..5ccef4965304591a54437f5f75e1d4070bff360a 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx
+++ b/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx
@@ -51,5 +51,6 @@ void RegisterTests()
   REGISTER_TEST(otbWrapperInputVectorDataParameterNew);
   REGISTER_TEST(otbWrapperOutputImageParameterNew);
   REGISTER_TEST(otbWrapperOutputImageParameterTest1);
+  //~ REGISTER_TEST(otbWrapperOutputImageParameterConversionTest);
   REGISTER_TEST(otbApplicationMemoryConnectTest);
 }
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx b/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx
index 76d6c6056e6ba55ed46f3edda89923fc1ad0c861..ea8899b8e0d50685f8e0973f17e1a50081dde7f5 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx
+++ b/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx
@@ -23,8 +23,10 @@
 #endif
 
 #include "otbWrapperOutputImageParameter.h"
+#include "otbWrapperInputImageParameter.h"
 #include "otbImageFileReader.h"
 #include "otbWrapperTypes.h"
+#include <vector>
 
 int otbWrapperOutputImageParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
 {
@@ -34,7 +36,6 @@ int otbWrapperOutputImageParameterNew(int itkNotUsed(argc), char * itkNotUsed(ar
   return EXIT_SUCCESS;
 }
 
-
 int otbWrapperOutputImageParameterTest1(int itkNotUsed(argc), char* argv[])
 {
   typedef otb::Wrapper::OutputImageParameter OutputImageParameterType;
@@ -59,3 +60,59 @@ int otbWrapperOutputImageParameterTest1(int itkNotUsed(argc), char* argv[])
 
   return EXIT_SUCCESS;
 }
+
+
+// template < typename ImageType >
+// void Cross( int p , std::string inputfilename, std::string outputfilename)
+// {
+//   otb::Wrapper::InputImageParameter::Pointer paramIn (
+//     otb::Wrapper::InputImageParameter::New() );
+//   paramIn->SetFromFileName( inputfilename ); 
+//   otb::Wrapper::OutputImageParameter::Pointer paramOut( 
+//     otb::Wrapper::OutputImageParameter::New() ); 
+//   paramOut->SetFileName( outputfilename );
+//   paramOut->SetImage(paramIn->GetImage<ImageType>());
+//   paramOut->InitializeWriters();
+//   paramOut->SetPixelType(static_cast<otb::Wrapper::ImagePixelType>(p));
+//   paramOut->Write();
+// }
+
+
+// int otbWrapperOutputImageParameterConversionTest(int , char* argv[])
+// {
+//   std::string filenamein = argv[1];
+//   std::string filenameout = argv[2] ;
+//   std::string extension = filenameout.substr( filenameout.find_last_of('.') );
+
+//   filenameout = filenameout.substr( 0 , filenameout.find_last_of('.') );
+
+//   for ( int i = otb::Wrapper::ImagePixelType_uint8 ; i < 11 ; i++ )
+//     {
+//       std::string type = 
+//       otb::Wrapper::OutputImageParameter::ConvertPixelTypeToString(
+//         static_cast<otb::Wrapper::ImagePixelType>(i) );
+//       Cross< otb::Wrapper::UInt8ImageType > (i , filenamein , filenameout+"_UInt8_"+ type + extension ) ;
+//       Cross< otb::Wrapper::Int16ImageType > ( i , filenamein , filenameout+"_Int16_"+ type + extension ) ;
+//       Cross< otb::Wrapper::UInt16ImageType > ( i , filenamein , filenameout+"_UInt16_"+ type + extension ) ;
+//       Cross< otb::Wrapper::Int32ImageType > ( i , filenamein , filenameout+"_Int21_"+ type + extension ) ;
+//       Cross< otb::Wrapper::UInt32ImageType > ( i , filenamein , filenameout+"_UInt32_"+ type + extension ) ;
+//       Cross< otb::Wrapper::FloatImageType > ( i , filenamein , filenameout+"_float_"+ type + extension ) ;
+//       Cross< otb::Wrapper::DoubleImageType > ( i , filenamein , filenameout+"_double_"+ type + extension ) ;
+//       Cross< otb::Wrapper::UInt8VectorImageType > ( i , filenamein , filenameout+"_UInt8Vect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::Int16VectorImageType > ( i , filenamein , filenameout+"_Int16Vect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::UInt16VectorImageType > ( i , filenamein , filenameout+"_UInt16Vect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::Int32VectorImageType > ( i , filenamein , filenameout+"_Int21Vect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::UInt32VectorImageType > ( i , filenamein , filenameout+"_UInt32Vect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::FloatVectorImageType > ( i , filenamein , filenameout+"_floatVect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::DoubleVectorImageType > ( i , filenamein , filenameout+"_doubleVect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexInt16ImageType > ( i , filenamein , filenameout+"_CInt16_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexInt32ImageType > ( i , filenamein , filenameout+"_CInt32_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexFloatImageType > ( i , filenamein , filenameout+"_Cfloat_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexDoubleImageType > ( i , filenamein , filenameout+"_Cdouble_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexInt16VectorImageType > ( i , filenamein , filenameout+"_CInt16Vect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexInt32VectorImageType > ( i , filenamein , filenameout+"_CInt32Vect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexFloatVectorImageType > ( i , filenamein , filenameout+"_CfloatVect_"+ type + extension ) ;
+//       Cross< otb::Wrapper::ComplexDoubleVectorImageType > ( i , filenamein , filenameout+"_CdoubleVect_"+ type + extension ) ;
+//     }
+//   return 0;
+// }
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx
index 0cd5800dfa462ba05af6123a247ca48c15d29d78..ab35389152756e9c4db507cd6478520ae5db9bba 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx
@@ -67,6 +67,8 @@ void QtWidgetComplexOutputImageParameter::DoCreateWidget()
   // Set the Output PixelType choice Combobox
   m_ComboBox = new QComboBox;
   m_ComboBox->setToolTip("Complex Output Pixel Type");
+  m_ComboBox->addItem( "cint16");
+  m_ComboBox->addItem( "cint32");
   m_ComboBox->addItem( "cfloat");
   m_ComboBox->addItem( "cdouble");
   m_ComboBox->setCurrentIndex(m_OutputImageParam->GetComplexPixelType());
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx
index 140ff6534f8487f97bbda7d0a99fc49128401843..9bcf5430d20d65864bb072d00a32792806610411 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx
@@ -75,6 +75,10 @@ void QtWidgetOutputImageParameter::DoCreateWidget()
   m_ComboBox->addItem( "uint 32");
   m_ComboBox->addItem( "float");
   m_ComboBox->addItem( "double");
+  m_ComboBox->addItem( "cint16");
+  m_ComboBox->addItem( "cint32");
+  m_ComboBox->addItem( "cfloat");
+  m_ComboBox->addItem( "cdouble");
   m_ComboBox->setCurrentIndex(m_OutputImageParam->GetPixelType());
   connect( m_ComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(SetPixelType(int)) );
   connect( m_ComboBox, SIGNAL(currentIndexChanged(int)), GetModel(), SLOT(NotifyUpdate()) );
diff --git a/PSC.md b/PSC.md
new file mode 100644
index 0000000000000000000000000000000000000000..c798cec66eaa4a3b3f4538861ed26ea12560c139
--- /dev/null
+++ b/PSC.md
@@ -0,0 +1,280 @@
+# Project Steering Committee
+
+This document describes the Project Steering Committee of the Orfeo ToolBox.
+
+## PSC scope
+
+The aim of the **OTB Project Steering committee (PSC)** is to provide
+high level guidance and coordination for the ORFEO ToolBox.
+
+It provides a central point of contact for the project and arbitrates
+disputes. It is also a stable base of “institutional knowledge” to the
+project and tries its best to involve more developers.
+
+It should help to guarantee that OTB remains open and company neutral.
+
+### Roadmaps
+
+The PSC gathers and publishes high level roadmaps for OTB:
+
+-   Feature roadmap
+-   Technical roadmap (developer and coding guidelines and workflows,
+    target systems, packaging ...)
+-   Infrastructure roadmap (SCM, wiki, dashboard ...)
+
+The PSC also publishes the guidelines and the acceptance policy for
+feature requests. It enforces them. It monitors and approves new feature
+requests.
+
+### Communication
+
+The PSC coordinates communication actions:
+
+-   Ensures that the wiki is up-to-date,
+-   Ensures that the website is up-to-date and proposes new content,
+-   Ensures regular posting on the blog and social networks,
+-   Keeps track of opportunities to communicate: Symposium and events
+    where OTB should be represented,
+-   Keeps track of opportunities from communities: Google Summer of Code
+    project, link with other OSGeo and FOSS projects,
+-   Is responsible for the organization of events around OTB (i.e. users
+    meetings and hackathon).
+
+### User support and documentation
+
+The PSC ensures that users are given an appropriate support:
+
+-   Ensures that support is working (unanswered questions, questions
+    from other places than the user list ...)
+-   Proposes addition to the documentation based on users feedback,
+-   Proposes new features for the roadmap based on users feedback,
+-   Proposes new ways for support and documentation
+
+### Contribution management
+
+The PSC publishes the guidelines and acceptance policy for
+contributions. It enforces them.
+
+It monitors and approves new proposals.
+
+It ensures that contribution is as easy as possible, by monitoring
+technical means for contribution and proposing evolutions to guidelines,
+policies and means.
+
+### Release planning
+
+The PSC publishes release guidelines and policies, and enforces them.
+
+The PSC puts together the next Release roadmap and proposes a planning.
+It is then responsible for the release preparation.
+
+The final approval for a release is given by the PSC (motion proposed to
+the otb-developers mailing list).
+
+### Handling of legal issues
+
+The PSC is responsible for addressing any issue about copyright or
+licensing that may occur, and most importantly, it is responsible for
+taking preventive actions about those issues.
+
+## How does the PSC work?
+
+This section describes how the PSC works. It is inspired by existing
+governance statuses in other open source community projects related to
+OTB like
+[GDAL](https://trac.osgeo.org/gdal/wiki/GovernanceAndCommunity),
+[Quantum
+GIS](http://www2.qgis.org/en/site/getinvolved/governance/index.html) or
+[GRASS](http://trac.osgeo.org/grass/wiki/PSC).
+
+### PSC members
+
+All members have equal standing and voice in the PSC. The PSC seats are
+non-expiring. PSC members may resign their position, or be asked to
+vacate their seat after a unanimous vote of no confidence from the
+remaining PSC members.
+
+The expectations on PSC members are:
+
+-   Be willing to commit to the OTB development effort
+-   Be responsive to requests for information from fellow members
+-   Be able and willing to attend on-line meetings
+-   Act in the best interests of the project
+
+It is important to note that the PSC is not a legal entity!
+
+### Roles
+
+Members can be assigned roles corresponding to each category of the PSC
+scope described above.
+
+Being assigned a role does not mean undertaking all necessary actions,
+but rather ensuring that actions will be undertaken.
+
+In addition to their specific roles, members of the PSC commit to
+participate actively in discussions and votes.
+
+One member of the PSC is designated as the Chair and is the ultimate
+adjudicator in case of deadlock or irretrievable break down of
+decision-making, or in case of disputes over voting.
+
+### When is a PSC vote required?
+
+A vote of the PSC is required in the following cases:
+
+1.  Merge Request
+2.  Addition or removal of PSC members (including the selection of a new
+    Chair)
+3.  Release process
+
+In addition, a vote can be summoned for:
+
+1.  Changing PSC rules and processes
+2.  Anything else that might be controversial
+
+#### Merge Request
+
+A Merge Request describes a change in Orfeo ToolBox code, API,
+infrastructure or processes that need to be submitted to the PSC vote:
+
+-   Anything that could cause backward compatibility issues,
+-   Adding substantial amounts of new code,
+-   Changing inter-subsystem APIs, or objects,
+
+It should describe :
+
+1.  What changes will be made and why they will make a better Orfeo
+    ToolBox
+2.  When will those changes be available (target release or date)
+3.  Who will be developing the proposed changes
+
+Those elements can be provided in an email to the developer list or on a
+git hosted platform (GitLab, GitHub, etc.).
+
+#### Add or remove PSC members
+
+To be eligible for membership in the PSC, a person should demonstrate
+**a substantial and ongoing involvement in OTB**. The PSC is not only
+composed of OTB developers as there are many ways to join and contribute
+to the project. Anyone is eligible to be nominated to the OTB PSC.
+Ideally, nominees would be OTB users or developers who have a deep
+understanding of the project. In addition, nominees should meet the
+qualifications set forth in this document. Anyone can submit a
+nomination.
+
+#### Release phases
+
+The release manager (the PSC member in charge of release planning)
+submits to vote the following release decisions:
+
+1.  Date of the next release
+2.  Codename of the next release
+3.  Date and revision of Release Candidate
+4.  Date and revision of Final Release
+5.  Date and revision of bug-fixes Release
+
+### Process
+
+-   Proposals are written up and submitted as GitLab merge requests or on the
+    otb-developers mailing list for discussion and voting, by any interested
+    party, not just committee members. Proposals are available for review for at
+    least three days before a vote can be closed. It is acknowledged that some
+    more complex issues may require more time for discussion and deliberation.
+-   Respondents may vote “+1” to indicate support for the proposal and a
+    willingness to support implementation.
+-   Respondents may vote “-1” to veto a proposal, but must provide
+    argumented reasoning and alternate approaches to resolve the problem
+    within the two days.
+-   A vote of -0 indicates mild disagreement, but has no effect. A 0
+    indicates no opinion. A +0 indicates mild support, but has no
+    effect.
+-   Anyone may comment and vote on proposals on the list or on the merge request
+    thread, but only members of the PSC's votes (including the Chair) will be
+    counted (“eligible voters”).
+-   A proposal will be accepted if it receives at least +2 (including
+    the proponent) and no vetos (-1)
+-   If a proposal is vetoed, and it cannot be revised to satisfy all
+    parties, then it can be resubmitted for an override vote in which a
+    majority of all eligible voters indicating +1 is sufficient to pass
+    it. Note that this is a majority of all committee members, not just
+    those who actively vote.
+-   The Chair adjudicates in cases of disputes about voting.
+
+A summary of discussions is published in a dedicated section of the wiki
+[Requests for Changes](https://wiki.orfeo-toolbox.org/index.php/Requests_for_Changes).
+
+## Current members and roles
+
+In March 2015, CNES nominated 3 persons deeply involved in OTB as
+initial PSC members. They are responsible for defining PSC rules and
+establishing a fully functioning PSC. PSC has now 4 members.
+
+**Name**                    | **Affiliation**  | **Email**                        | **Role**                                   |
+----------------------------|------------------|----------------------------------|--------------------------------------------|
+Manuel Grizonnet (resigned) | CNES             | manuel.grizonnet AT cnes DOT fr  | Infrastructure, legal issues               |
+Rémi Cresson                | IRSTEA           | cresson.r AT gmail DOT com       | Release Manager for release 5.2            |
+Guillaume Pasero            | CS-SI            | guillaume.pasero AT c-s DOT fr   | release planner                            |
+Jordi Inglada (resigned)    | CNES/CESBIO      | jordi.inglada AT cesbio DOT eu   |                                            |
+Julien Michel               | CNES             | julien.michel AT cnes DOT fr     | Communication, contributions               |
+Victor Poughon              | CNES             | victor.poughon AT cnes DOT fr    | User support and documentation, roadmaps   |
+
+## Release manager
+
+A **release manager** is nominated for each release. Nomination is made
+shortly after previous release announcement. A **backup release
+manager** is also nominated, to assist and possibly step in if the
+official release manager is not available. The **release manager** and
+his/her backup can be a member of the PSC, but also another member of
+otb-developers list willing to take the spot.
+
+The **release manager** is in charge of :
+
+1.  Listing and tracking all major features proposed for next release
+    (from call for contribution in the early phase and then approved
+    RFCs)
+2.  Planing release date and ensures sync with RFCs execution,
+3.  Approving feature branch merges (if possible, leave at least 3 days
+    between RFC submission and merge, so that people have time to do a
+    review)
+4.  Actually merging feature branches when authors do not have commit
+    rights (github pull request for instance)
+5.  Tracking remote module that can be candidate for official inclusion
+    in next release, and ensuring they will be included (see
+    [Contributors guidelines](CONTRIBUTING.md))
+6.  Submitting the start of the [release
+    process](https://wiki.orfeo-toolbox.org/index.php/How_to_Release) to PSC vote
+7.  Ensuring proper execution of [release
+    process](https://wiki.orfeo-toolbox.org/index.php/How_to_Release)
+
+**Feature freeze:** Starting the release process is also called *feature
+freeze* which describes the period between the creation of the release
+branch and the announcement of the release. It's an important time for
+the RM who should ensures the proper execution of the release process
+and facilitate the communication between developers. The RM is among
+other things responsible of gathering feedback on bugs that need to be
+fixed before the release, making a list that is public to be able to
+follow progression of the release process.
+
+**Remember:** all new features must be submitted by Merge Requests and
+approved by the PSC. The release manager only approves the feature
+branches merge.
+
+### Feature branch merge acceptance checklist
+
+1.  The feature branch corresponds to an [approved
+    Merge Request](#process)
+2.  The feature branch is synched with develop
+3.  The feature branch is tested on the dashboard
+    and has no major failure
+    (compilation errors, tremendous amount of warning or failing tests,
+    segfault or not executed tests)
+4.  Feature branch author are available during days following the merge
+    to analyse dashboard and fix things in case of unexpected issues
+    after the merge
+
+It is important to note that a feature branch should be kept relatively
+small and does not necessarily correspond to the full implementation of
+a RFC. Small consistent branches implementing parts of RFC can be merged
+early. Further evolutions and implementations of the RFC can be done by
+continuing the feature branch or opening new branches, and approval of
+Release Manager should be requested again before merging.
diff --git a/README.md b/README.md
index 7ae06474de74ecf4067b6d10a725c8488155d0aa..657504a2dc83be7443ec9802656653346b3f7426 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# ![OTB](https://git.orfeo-toolbox.org/otb.git/blob_plain/HEAD:/Utilities/Doxygen/logoVectoriel.png) Orfeo Toolbox
+# ![OTB](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/raw/master/Utilities/Doxygen/logoVectoriel.png) Orfeo Toolbox
 ## Open Source processing of remote sensing images
 
 Orfeo ToolBox (OTB) is an open-source project for state-of-the-art remote
@@ -23,12 +23,12 @@ not a black box!
 * [OTB's website](https://www.orfeo-toolbox.org/)
 * [Documentation](https://www.orfeo-toolbox.org/documentation/)
 * [Downloads](https://www.orfeo-toolbox.org/download/)
-* [Public git repositories](https://git.orfeo-toolbox.org/)
+* [Public git repositories](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb)
 * [GitHub mirror](https://github.com/orfeotoolbox/)
 * [Build status](http://dash.orfeo-toolbox.org/index.php?project=OTB)
-* [Bug tracker](https://bugs.orfeo-toolbox.org/)
+* [Bug tracker](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues?label_name%5B%5D=bug)
 * [Wiki](http://wiki.orfeo-toolbox.org/index.php/Main_Page)
-* [Task tracking](http://scrum.orfeo-toolbox.org)
+* [Task tracking](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues)
 
 ### Join the community
 Get help, share your experience and contribute to the Orfeo-Toolbox project by
@@ -37,10 +37,13 @@ joining our community and mailing lists.
 [https://www.orfeo-toolbox.org/community/](https://www.orfeo-toolbox.org/community/)
 
 ### Contributing
-Please see the wiki for contributors guidelines.
+Please see [CONTRIBUTING.md](CONTRIBUTING.md) for contributors guidelines.
 
 ### License
 Please see the license and the Copyright directory for legal issues on the use of the software.
 
 ### Issues
-Please report any issue you might encouter to [our bugtracker](http://bugs.orfeo-toolbox.org).
+Please report any issue you might encouter to [our bugtracker](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues?label_name%5B%5D=bug).
+
+### Governance
+The Orfeo ToolBox project is governed by the [Project Steering Committee](PSC.md) and its members.