[otb] 01/11: New upstream version 6.4.0~rc1+dfsg

Bas Couwenberg sebastic at debian.org
Thu Jan 25 12:28:52 UTC 2018


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository otb.

commit 47b8955ccb7882dfccf4cf245c210363099b1ee3
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Thu Jan 25 07:49:31 2018 +0100

    New upstream version 6.4.0~rc1+dfsg
---
 CMake/CTestCustom.cmake.in                         |   5 +-
 CMake/FindOssim.cmake                              |  28 +-
 CMake/UseSWIGLocal.cmake                           |   4 -
 CMakeLists.txt                                     |  18 +-
 Examples/Application/ApplicationExample.cxx        | 112 +--
 Examples/Application/test/CMakeLists.txt           |   2 +-
 .../ClassificationMapRegularizationExample.cxx     |   2 -
 Examples/DataRepresentation/Image/Image4.cxx       |  10 +-
 .../Path/PolyLineParametricPath1.cxx               |   2 +-
 .../SimpleDisparityMapEstimationExample.cxx        |   4 +-
 .../RightAngleDetectionExample.cxx                 |   2 +-
 Examples/FeatureExtraction/SURFExample.cxx         |   2 +-
 Examples/IO/MetadataExample.cxx                    |   2 +-
 .../Iterators/ImageLinearIteratorWithIndex2.cxx    |   4 +-
 Examples/Iterators/ImageRegionIterator.cxx         |   4 +-
 .../EstimateAffineTransformationExample.cxx        |   2 +-
 Examples/Patented/SIFTDisparityMapEstimation.cxx   |   2 +-
 Examples/Patented/SIFTExample.cxx                  |   2 +-
 Examples/Patented/SIFTFastExample.cxx              |   2 +-
 .../Projections/GeometriesProjectionExample.cxx    |   2 +-
 Examples/Projections/SensorModelExample.cxx        |   4 +-
 .../Projections/VectorDataExtractROIExample.cxx    |   8 +-
 .../Projections/VectorDataProjectionExample.cxx    |   2 +-
 Examples/Registration/ImageRegistration1.cxx       |   2 +-
 Examples/Registration/ImageRegistration2.cxx       |   2 +-
 Examples/Registration/ImageRegistration5.cxx       |   6 +-
 Examples/Registration/ImageRegistration9.cxx       |   2 +-
 .../src/otbGeometriesToGeometriesFilter.cxx        |   7 +-
 Modules/Adapters/OSSIMAdapters/src/CMakeLists.txt  |  11 +-
 .../OSSIMAdapters/src/otbRPCSolverAdapter.cxx      |   4 +
 Modules/Adapters/QtAdapters/src/otbQtAdapters.cxx  |  13 +-
 .../AppChangeDetection/app/CMakeLists.txt          |   5 -
 .../AppClassification/app/CMakeLists.txt           |  37 +-
 .../app/otbComputePolylineFeatureFromImage.cxx     |   6 +-
 .../app/otbKMeansClassification.cxx                |   2 +
 .../AppClassification/app/otbTrainRegression.cxx   |  94 +-
 .../app/otbTrainVectorClassifier.cxx               |   6 +-
 .../Applications/AppDescriptors/app/CMakeLists.txt |   9 -
 .../app/otbHomologousPointsExtraction.cxx          |   2 +-
 .../AppDimensionalityReduction/app/CMakeLists.txt  |   7 -
 Modules/Applications/AppEdge/app/CMakeLists.txt    |   9 -
 .../AppEdge/app/otbLineSegmentDetection.cxx        |   2 +-
 .../Applications/AppFiltering/app/CMakeLists.txt   |  11 +-
 .../AppFiltering/app/otbContrastEnhancement.cxx    | 995 +++++++++++++++++++++
 .../Applications/AppFiltering/app/otbSmoothing.cxx | 101 ++-
 Modules/Applications/AppFiltering/otb-module.cmake |   3 +
 .../Applications/AppFiltering/test/CMakeLists.txt  |  55 ++
 Modules/Applications/AppFusion/app/CMakeLists.txt  |   8 -
 .../AppHyperspectral/app/CMakeLists.txt            |   7 -
 .../app/otbVertexComponentAnalysis.cxx             |  29 +-
 .../Applications/AppImageUtils/app/CMakeLists.txt  |  23 +-
 .../AppImageUtils/app/otbConcatenateImages.cxx     |  10 +-
 .../Applications/AppImageUtils/app/otbConvert.cxx  |   7 +-
 .../AppImageUtils/app/otbDownloadSRTMTiles.cxx     |   2 +-
 .../AppImageUtils/app/otbDynamicConvert.cxx        | 534 +++++++++++
 .../AppImageUtils/app/otbReadImageInfo.cxx         |   4 +-
 .../Applications/AppImageUtils/app/otbRescale.cxx  |   2 +-
 .../AppImageUtils/app/otbSplitImage.cxx            |  15 +-
 .../AppImageUtils/app/otbTileFusion.cxx            |   4 +-
 .../Applications/AppImageUtils/test/CMakeLists.txt |  47 +-
 Modules/Applications/AppIndices/app/CMakeLists.txt |   6 -
 Modules/Applications/AppKMZ/app/CMakeLists.txt     |   4 -
 .../Applications/AppMathParser/app/CMakeLists.txt  |   8 -
 .../Applications/AppMathParser/app/otbBandMath.cxx |  39 +-
 .../Applications/AppMathParserX/app/CMakeLists.txt |   7 -
 .../AppMathParserX/app/otbBandMathX.cxx            | 137 ++-
 Modules/Applications/AppMoments/app/CMakeLists.txt |   6 -
 .../AppMoments/app/otbLocalStatisticExtraction.cxx |   2 -
 .../Applications/AppMorphology/app/CMakeLists.txt  |   7 -
 .../app/otbBinaryMorphologicalOperation.cxx        | 122 +--
 .../app/otbGrayScaleMorphologicalOperation.cxx     |   2 -
 .../app/otbMorphologicalClassification.cxx         | 100 ++-
 .../otbMorphologicalMultiScaleDecomposition.cxx    |   1 -
 .../app/otbMorphologicalProfilesAnalysis.cxx       |   1 -
 .../AppOpticalCalibration/app/CMakeLists.txt       |   7 -
 .../Applications/AppProjection/app/CMakeLists.txt  |  15 -
 .../app/otbConvertCartoToGeoPoint.cxx              |  12 +-
 .../AppProjection/app/otbOrthoRectification.cxx    |  13 +-
 .../app/otbRigidTransformResample.cxx              |   6 +-
 .../AppProjection/app/otbSuperimpose.cxx           |   4 +-
 .../app/otbVectorDataReprojection.cxx              |   4 +-
 .../AppSARCalibration/app/CMakeLists.txt           |   5 -
 .../AppSARDecompositions/app/CMakeLists.txt        |   7 -
 .../AppSARPolarMatrixConvert/app/CMakeLists.txt    |   7 -
 .../AppSARPolarSynth/app/CMakeLists.txt            |   7 -
 .../Applications/AppSARUtils/app/CMakeLists.txt    |  26 +-
 .../AppSegmentation/app/CMakeLists.txt             |  23 -
 .../app/otbConnectedComponentSegmentation.cxx      |   2 +-
 Modules/Applications/AppStereo/app/CMakeLists.txt  |  15 -
 .../AppStereo/app/otbStereoFramework.cxx           | 170 ++--
 .../app/otbStereoRectificationGridGenerator.cxx    |  88 +-
 Modules/Applications/AppTest/app/CMakeLists.txt    |   4 -
 .../AppTest/app/otbTestApplication.cxx             |  73 +-
 .../Applications/AppTextures/app/CMakeLists.txt    |   8 -
 .../app/otbHaralickTextureExtraction.cxx           |  56 +-
 .../AppTextures/app/otbSFSTextureExtraction.cxx    |  24 +-
 .../AppVectorDataTranslation/app/CMakeLists.txt    |   6 -
 .../app/otbRasterization.cxx                       |   2 +-
 .../Applications/AppVectorUtils/app/CMakeLists.txt |   9 -
 .../app/otbConcatenateVectorData.cxx               |  26 +-
 .../AppVectorUtils/app/otbOSMDownloader.cxx        |  47 +-
 .../AppVectorUtils/app/otbVectorDataTransform.cxx  |  44 +-
 Modules/Core/Common/include/otbFilterWatcherBase.h |  10 +-
 Modules/Core/Common/include/otbImportImageFilter.h |   2 +-
 .../Core/Common/include/otbImportImageFilter.txx   |   2 +-
 .../Common/include/otbImportVectorImageFilter.h    |   2 +-
 .../Common/include/otbImportVectorImageFilter.txx  |   2 +-
 Modules/Core/Common/include/otbStopwatch.h         |  85 ++
 .../Common/include/otbStringToHTML.h}              |  59 +-
 Modules/Core/Common/include/otbWriterWatcherBase.h |  11 +-
 Modules/Core/Common/src/CMakeLists.txt             |   4 +-
 Modules/Core/Common/src/otbFilterWatcherBase.cxx   |   4 +-
 .../Core/Common/src/otbStandardFilterWatcher.cxx   |   6 +-
 .../Common/src/otbStandardOneLineFilterWatcher.cxx |   6 +-
 .../Core/Common/src/otbStandardWriterWatcher.cxx   |   6 +-
 Modules/Core/Common/src/otbStopwatch.cxx           | 119 +++
 Modules/Core/Common/src/otbStringToHTML.cxx        |  68 ++
 Modules/Core/Common/src/otbWriterWatcherBase.cxx   |   4 +-
 Modules/Core/Common/test/CMakeLists.txt            |   4 +
 Modules/Core/Common/test/otbCommonTestDriver.cxx   |   1 +
 Modules/Core/Common/test/otbStopwatchTest.cxx      |  92 ++
 .../Core/ImageBase/include/otbExtractROIBase.txx   |   4 +-
 Modules/Core/ImageBase/include/otbImage.h          |  58 ++
 Modules/Core/ImageBase/include/otbImage.txx        |  45 +
 Modules/Core/ImageBase/include/otbVectorImage.h    |   7 +
 Modules/Core/ImageBase/include/otbVectorImage.txx  |  45 +
 Modules/Core/ImageBase/src/otbImageIOBase.cxx      |   4 +-
 Modules/Core/ImageBase/test/otbImageTest.cxx       |   2 +-
 .../ImageBase/test/otbMultiChannelExtractROI.cxx   |  15 +-
 Modules/Core/ImageBase/test/otbVectorImageTest.cxx |   2 +-
 .../include/otbBSplineInterpolateImageFunction.txx |   2 +-
 .../test/otbProlateValidationTest.cxx              |   2 +-
 .../include/otbShapeAttributesLabelMapFilter.txx   |  14 +-
 .../LabelMap/test/otbLabelObjectMapVectorizer.cxx  |  13 +-
 Modules/Core/Metadata/include/otbNoDataHelper.h    |  13 +-
 .../src/otbSentinel1ImageMetadataInterface.cxx     |   2 +-
 Modules/Core/ObjectList/include/otbObjectList.h    |  15 +-
 .../otbSpatialObjectToImageDrawingFilter.txx       |   4 +-
 .../Core/Transform/include/otbGenericRSTransform.h |   4 +-
 .../include/otbStreamingWarpImageFilter.h          |  13 +
 .../include/otbStreamingWarpImageFilter.txx        |  51 +-
 .../Core/VectorDataBase/include/otbVectorData.h    |   2 +-
 .../include/otbGenericRoadExtractionFilter.txx     |   2 +-
 .../include/otbImageToPathListAlignFilter.txx      |   2 +-
 .../include/otbKeyPointDensityImageFilter.txx      |   2 +-
 .../include/otbPointSetToDensityImageFilter.txx    |   2 +-
 .../test/otbPointSetToDensityImageFilterTest.cxx   |   2 +-
 ...otbForwardFourierMellinTransformImageFilter.txx |   2 +-
 .../include/otbImageToSIFTKeyPointSetFilter.txx    |  10 +-
 .../include/otbImageToSURFKeyPointSetFilter.txx    |   2 +-
 .../test/otbFourierMellinDescriptors.cxx           |   2 +-
 ...ramOfOrientedGradientCovariantImageFunction.cxx |   1 +
 .../otbImageToSIFTKeyPointSetFilterDistanceMap.cxx |   6 +-
 .../otbImageToSIFTKeyPointSetFilterOutputImage.cxx |   2 +-
 .../otbHoughTransform2DLinesImageFilter.txx        |   2 +-
 .../Edge/include/otbLineSegmentDetector.txx        |   2 +-
 .../Feature/Edge/include/otbLocalHoughFilter.txx   |   2 +-
 .../include/otbTouziEdgeDetectorImageFilter.txx    |   2 +-
 .../test/otbFlusserMomentsImageFunction.cxx        |   2 +-
 .../Moments/test/otbHuMomentsImageFunction.cxx     |   2 +-
 .../include/otbAddCarvingPathFilter.txx            |   4 +-
 .../include/otbRemoveCarvingPathFilter.txx         |   4 +-
 .../otbScalarImageToAdvancedTexturesFilter.txx     |   4 +-
 .../otbScalarImageToHigherOrderTexturesFilter.txx  |   4 +-
 .../include/otbScalarImageToTexturesFilter.txx     |   4 +-
 .../Contrast/CMakeLists.txt}                       |   3 +-
 .../Contrast/include/otbApplyGainFilter.h          | 145 +++
 .../Contrast/include/otbApplyGainFilter.txx        | 224 +++++
 .../include/otbCLHistogramEqualizationFilter.h     | 186 ++++
 .../include/otbCLHistogramEqualizationFilter.txx   | 102 +++
 .../Contrast/include/otbComputeGainLutFilter.h     | 128 +++
 .../Contrast/include/otbComputeGainLutFilter.txx   | 191 ++++
 .../Contrast/include/otbComputeHistoFilter.h       | 160 ++++
 .../Contrast/include/otbComputeHistoFilter.txx     | 369 ++++++++
 .../Contrast}/otb-module.cmake                     |  11 +-
 Modules/Filtering/Contrast/test/CMakeLists.txt     |  88 ++
 .../Filtering/Contrast/test/otbApplyGainFilter.cxx |  66 ++
 .../Contrast/test/otbApplyGainFilterNew.cxx}       |  48 +-
 .../test/otbCLHistogramEqualizationFilter.cxx      |  57 ++
 .../test/otbCLHistogramEqualizationFilterNew.cxx}  |  43 +-
 .../Contrast/test/otbComputeGainLutFilter.cxx      |  68 ++
 .../Contrast/test/otbComputeGainLutFilterNew.cxx}  |  40 +-
 .../Contrast/test/otbComputeHistoFilter.cxx        |  59 ++
 .../Contrast/test/otbComputeHistoFilterNew.cxx}    |  45 +-
 .../Contrast/test/otbContrastTestDriver.cxx        |  34 +
 Modules/Filtering/Contrast/test/otbHelperCLAHE.cxx |  92 ++
 ...pSaveAndClassicalConvolutionWithGaborFilter.cxx |  14 +-
 .../Filtering/DEM/include/otbDEMToImageGenerator.h |   2 +-
 .../DEM/include/otbDEMToImageGenerator.txx         |   2 +-
 .../include/otbGridResampleImageFilter.txx         |  15 +-
 .../include/otbInPlacePassFilter.h                 |  99 ++
 .../include/otbStreamingResampleImageFilter.h      |  15 +-
 .../include/otbStreamingResampleImageFilter.txx    |  30 +-
 .../include/otbStreamingShrinkImageFilter.txx      |   4 +-
 .../include/otbTileImageFilter.txx                 |   4 +-
 .../otbTwoNRIBandsImageToNComplexBandsImage.txx    |  21 +-
 .../test/otbGridResampleImageFilter.cxx            |  19 +-
 .../MathParser/include/otbBandMathImageFilter.txx  |   2 +-
 .../MathParser/test/otbBandMathImageFilter.cxx     |   6 +-
 .../include/otbBandMathXImageFilter.txx            |   4 +-
 .../MathParserX/test/otbBandMathXImageFilter.cxx   |   6 +-
 .../include/otbMorphologicalPyramidResampler.txx   |   9 +-
 .../otbRegionImageToRectangularPathListFilter.txx  |   2 +-
 ...otbMultiChannelsPolarimetricSynthesisFilter.txx |   4 +-
 .../include/otbGenericRSResampleImageFilter.txx    |   4 +-
 .../include/otbGroundSpacingImageFunction.txx      |   2 +-
 .../include/otbImportGeoInformationImageFilter.txx |   2 +-
 .../otbPhysicalToRPCSensorModelImageFilter.txx     |   4 +-
 .../otbVectorDataIntoImageProjectionFilter.h       |   2 +-
 .../otbVectorDataIntoImageProjectionFilter.txx     |   4 +-
 .../include/otbVectorDataProjectionFilter.h        |   4 +-
 .../include/otbVectorDataProjectionFilter.txx      |   7 +-
 .../include/otbVectorDataTransformFilter.txx       |   6 +-
 .../otbGeometriesProjectionFilterFromGeoToMap.cxx  |   2 +-
 ...otbGeometriesProjectionFilterFromMapToImage.cxx |   2 +-
 ...tbGeometriesProjectionFilterFromMapToSensor.cxx |   2 +-
 .../test/otbImportGeoInformationImageFilter.cxx    |   2 +-
 .../test/otbTileImageFilterRSTransformTest.cxx     |   4 +-
 .../otbVectorDataIntoImageProjectionFilterTest.cxx |   2 +-
 ...otbVectorDataProjectionFilterFromMapToImage.cxx |   2 +-
 ...tbVectorDataProjectionFilterFromMapToSensor.cxx |   2 +-
 .../test/otbVectorDataTransformFilter.cxx          |   2 +-
 .../Statistics/include/otbListSampleGenerator.txx  |   2 +-
 ...ContinuousMinimumMaximumImageCalculatorTest.cxx |   2 +-
 .../include/otbConcatenateVectorDataFilter.txx     |   1 -
 .../include/otbVectorDataExtractROI.txx            |   7 +-
 .../include/otbVectorDataToVectorDataFilter.txx    |   7 +-
 .../include/otbVectorDataToMapFilter.h             |   2 +-
 .../include/otbVectorDataToMapFilter.txx           |   7 +-
 .../test/otbVectorDataToMapFilterSensorModel.cxx   |   2 +-
 ...tbNeighborhoodMajorityVotingImageFilterTest.cxx |   4 +-
 .../test/otbExtendedFilenameTest.cxx               |   2 +-
 Modules/IO/IOGDAL/src/otbGDALImageIO.cxx           |  32 +-
 Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx  |  28 +-
 Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx           |  11 +-
 Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx       |   7 +-
 Modules/IO/IOKML/src/otbKMLVectorDataIO.cxx        |   7 +-
 Modules/IO/IORAD/src/otbRADImageIO.cxx             |  10 +-
 Modules/IO/IOTileMap/src/otbTileMapImageIO.cxx     |   3 +-
 Modules/IO/ImageIO/include/otbImageFileReader.txx  |  13 +-
 Modules/IO/ImageIO/include/otbImageFileWriter.txx  |  10 +-
 Modules/IO/ImageIO/test/negativespacing.cxx        |  61 ++
 .../IO/ImageIO/test/otbImageFileReaderMSTAR.cxx    |   4 +-
 .../test/otbImageFileWriterTestWithoutInput.cxx    |   4 +-
 ...otbImageStreamingFileWriterTestWithoutInput.cxx |   4 +-
 .../otbVectorImageFileWriterTestWithoutInput.cxx   |   4 +-
 ...torImageStreamingFileWriterTestWithoutInput.cxx |   4 +-
 Modules/IO/TestKernel/src/otbTestHelper.cxx        |   6 +-
 .../test/otbVectorDataFileGeoReaderWriter.cxx      |   2 +-
 .../include/otbMachineLearningModel.txx            |   2 +-
 Modules/Learning/SOM/test/otbSOMClassifier.cxx     |   2 +-
 .../include/otbOGRDataToSamplePositionFilter.txx   |   3 +-
 .../include/otbPersistentSamplingFilterBase.txx    |  40 +-
 .../test/otbImageSampleExtractorFilterTest.cxx     | 102 ++-
 .../test/otbOGRDataToClassStatisticsFilterTest.cxx |   4 +-
 .../test/otbOGRDataToSamplePositionFilterTest.cxx  |   8 +-
 .../include/otbSimpleParallelTiffWriter.h          |   4 -
 .../include/otbSimpleParallelTiffWriter.txx        |  72 +-
 Modules/MPI/MPIVrtWriter/include/otbMPIVrtWriter.h |   8 +-
 .../include/otbSarDeburstImageFilter.txx           |   2 +-
 .../test/otbSarDeburstFilterTest.cxx               |  18 +-
 .../include/otbImageSimulationMethod.txx           |   4 +-
 .../include/otbDisparityMapEstimationMethod.txx    |   4 +-
 .../include/otbDisparityMapTo3DFilter.txx          |   2 +-
 .../include/otbDisparityMapToDEMFilter.txx         |   4 +-
 .../include/otbFineRegistrationImageFilter.txx     |   8 +-
 .../include/otbMultiDisparityMapTo3DFilter.txx     |   4 +-
 .../include/otbNCCRegistrationFunction.txx         |   2 +-
 .../otbPixelWiseBlockMatchingImageFilter.txx       |  10 +-
 .../include/otbSubPixelDisparityImageFilter.txx    |   4 +-
 .../test/otbFineRegistrationImageFilterTest.cxx    |   9 +-
 .../otbPointSetToDisplacementFieldGenerator.txx    |   2 +-
 .../Stereo/include/otbAdhesionCorrectionFilter.txx |   8 +-
 .../Stereo/include/otbMulti3DMapToDEMFilter.txx    |  16 +-
 ...bStereorectificationDisplacementFieldSource.txx |  28 +-
 Modules/Remote/Mosaic.remote.cmake                 |   2 +-
 Modules/Remote/SertitObject.remote.cmake           |   6 +-
 Modules/Remote/otbFFSforGMM.remote.cmake           |   2 +-
 Modules/Remote/temporal-gapfilling.remote.cmake    |   3 +-
 ...ComponentSegmentationOBIAToVectorDataFilter.txx |   4 +-
 .../include/otbLabelImageToOGRDataSourceFilter.txx |  18 +-
 .../include/otbLabelImageToVectorDataFilter.txx    |  16 +-
 .../include/otbOGRDataSourceToLabelImageFilter.h   |   2 +-
 .../include/otbOGRDataSourceToLabelImageFilter.txx |  13 +-
 .../include/otbPersistentImageToOGRDataFilter.txx  |  10 +-
 .../include/otbPersistentImageToOGRLayerFilter.txx |  10 +-
 .../include/otbRasterizeVectorDataFilter.txx       |   8 +-
 .../include/otbVectorDataToLabelImageFilter.h      |   2 +-
 .../include/otbVectorDataToLabelImageFilter.txx    |  13 +-
 .../include/otbVectorDataToLabelMapFilter.h        |   2 +-
 .../otbVectorDataToLabelMapWithAttributesFilter.h  |   2 +-
 .../test/otbLabelMapToVectorDataFilter.cxx         |   2 +-
 .../test/otbVectorDataToLabelMapFilter.cxx         |   1 -
 .../include/otbOGRLayerStreamStitchingFilter.txx   |   7 +-
 ...bStreamingImageToOGRLayerSegmentationFilter.txx |  27 +-
 .../QtWidget => ThirdParty/GSL}/CMakeLists.txt     |   7 +-
 .../ThirdParty/GSL/otb-module-init.cmake           |  18 +-
 .../GSL}/otb-module.cmake                          |  17 +-
 .../itkTransformToDisplacementFieldSource.hxx      |   4 +-
 .../ITK/include/itkUnaryFunctorImageFilter.hxx     |   2 +-
 Modules/ThirdParty/Ossim/otb-module-init.cmake     |   2 +
 .../ossim/ossimKeyWordListUtilities.h              |   4 +-
 .../ossim/ossimOperatorUtilities.h                 |   0
 .../{src => include}/ossim/ossimRangeUtilities.h   |   0
 .../{src => include}/ossim/ossimSarSensorModel.h   |  24 +-
 .../ossim/ossimSarSensorModelPathsAndKeys.h        |   2 +
 .../{src => include}/ossim/ossimStringUtilities.h  |   0
 .../{src => include}/ossim/ossimTimeUtilities.h    |   4 +-
 .../{src => include}/ossim/ossimTraceHelpers.h     |   0
 .../{src => include}/ossim/ossimXmlTools.h         |   4 +-
 .../{src => include}/ossimPluginConstants.h        |   0
 .../src/ossim/ossimPluginProjectionFactory.cpp     |  19 +-
 .../OssimPlugins/src/ossim/ossimSarSensorModel.cpp | 157 +++-
 .../src/ossim/ossimSarSensorModelPathsAndKeys.cpp  |   4 +-
 .../OssimPlugins/src/ossim/ossimSentinel1Model.cpp |  47 +-
 .../OssimPlugins/src/ossim/ossimSentinel1Model.h   |  10 +-
 .../src/ossim/ossimSentinel1SarSensorModel.cpp     |   2 +-
 .../src/ossim/ossimSentinel1SarSensorModel.h       |   2 +-
 .../src/ossim/ossimStringUtilities.cpp             |   2 +-
 .../src/ossim/ossimTerraSarXSarSensorModel.cpp     |   2 +-
 .../src/ossim/ossimTerraSarXSarSensorModel.h       |   2 +-
 .../OssimPlugins/src/ossim/ossimTimeUtilities.cpp  |   4 +-
 .../src/ossim/ossimWin32FindFileHandle.cpp         |   2 +-
 .../OssimPlugins/src/ossim/ossimXmlTools.cpp       |   4 +-
 .../OssimPlugins/test/ossimSarSensorModelTest.cpp  |   2 +-
 .../OssimPlugins/test/ossimStringUtilitiesTest.cpp |   2 +-
 .../OssimPlugins/test/ossimTimeUtilitiesTest.cpp   |   4 +-
 Modules/Visualization/Ice/src/otbGlImageActor.cxx  |   4 +-
 .../Ice/src/otbNonOptGlImageActor.cxx              |   2 +-
 Modules/Visualization/Mapla/src/CMakeLists.txt     |   2 +-
 .../Visualization/Mapla/src/mvdMaplaMainWindow.qrc |   2 +
 .../Visualization/Monteverdi/src/CMakeLists.txt    |   2 +-
 .../Visualization/Monteverdi/src/mvdMainWindow.qrc |   2 +
 .../Monteverdi/src/mvdPreferencesDialog.ui         |   4 +-
 .../MonteverdiCore/include/mvdAbstractImageModel.h |  12 +-
 .../MonteverdiCore/src/mvdOverviewBuilder.cxx      |   2 +-
 .../MonteverdiCore/src/mvdVectorImageModel.cxx     |  78 +-
 .../MonteverdiGui/include/mvdLayerStackItemModel.h |  19 +-
 .../include/mvdQtWidgetParameterInitializers.h     | 172 ++--
 .../MonteverdiGui/include/mvdQtWidgetView.h        |   2 +
 .../MonteverdiGui/src/mvdApplicationsToolBox.ui    |   2 +-
 .../MonteverdiGui/src/mvdQtWidgetView.cxx          |  53 +-
 .../include/otbWrapperAbstractParameterList.h      |  88 ++
 .../include/otbWrapperApplication.h                |  40 +-
 .../otbWrapperComplexInputImageParameter.txx       |  11 +-
 .../otbWrapperComplexOutputImageParameter.h        |   4 +
 .../include/otbWrapperInputFilenameListParameter.h |  83 +-
 .../include/otbWrapperInputImageListParameter.h    | 111 +--
 .../include/otbWrapperInputImageParameter.h        |   8 +-
 .../include/otbWrapperInputImageParameter.txx      |  28 +-
 .../otbWrapperInputVectorDataListParameter.h       | 104 ++-
 .../include/otbWrapperInputVectorDataParameter.h   |   7 +-
 .../include/otbWrapperOutputImageParameter.h       |   4 +
 .../include/otbWrapperParameter.h                  |  45 +-
 .../include/otbWrapperParameterList.h              | 205 +++++
 .../include/otbWrapperParameterList.txx            | 487 ++++++++++
 .../include/otbWrapperProxyParameter.h             |   5 +
 .../include/otbWrapperStringListInterface.h        | 126 +++
 .../include/otbWrapperStringListParameter.h        | 131 ++-
 .../include/otbWrapperStringParameter.h            |   6 +-
 .../ApplicationEngine/include/otbWrapperTags.h     |   1 +
 .../ApplicationEngine/include/otbWrapperTypes.h    |   2 +-
 .../Wrappers/ApplicationEngine/src/CMakeLists.txt  |   8 +-
 .../otbWrapperAbstractParameterList.cxx}           |  40 +-
 .../src/otbWrapperApplication.cxx                  | 125 +--
 .../src/otbWrapperApplicationHtmlDocGenerator.cxx  |  27 +-
 .../src/otbWrapperApplicationRegistry.cxx          |  30 +-
 .../src/otbWrapperComplexInputImageParameter.cxx   |  25 +-
 .../src/otbWrapperComplexOutputImageParameter.cxx  |  12 +
 .../src/otbWrapperDocExampleStructure.cxx          |   5 +-
 .../src/otbWrapperElevationParametersHandler.cxx   |   2 +-
 .../src/otbWrapperInputFilenameListParameter.cxx   | 207 ++---
 .../src/otbWrapperInputImageListParameter.cxx      | 349 ++++----
 .../src/otbWrapperInputImageParameter.cxx          |  19 +-
 .../src/otbWrapperInputProcessXMLParameter.cxx     |  17 +-
 .../src/otbWrapperInputVectorDataListParameter.cxx | 350 +++-----
 .../src/otbWrapperInputVectorDataParameter.cxx     |  62 +-
 .../otbWrapperMapProjectionParametersHandler.cxx   |   4 +-
 .../src/otbWrapperOutputImageParameter.cxx         |  22 +
 .../otbWrapperParameterList.cxx}                   |  37 +-
 .../src/otbWrapperStringListInterface.cxx          | 105 +++
 .../src/otbWrapperStringListParameter.cxx          | 133 +++
 .../Wrappers/ApplicationEngine/test/CMakeLists.txt |  10 -
 .../test/otbApplicationEngineTestDriver.cxx        |   2 -
 .../test/otbWrapperApplicationDocTests.cxx         |   2 +-
 .../src/otbWrapperCommandLineLauncher.cxx          | 304 +++----
 Modules/Wrappers/QtWidget/CMakeLists.txt           |   6 +
 .../otbWrapperQtWidgetInputFilenameListParameter.h |  52 +-
 .../otbWrapperQtWidgetInputImageListParameter.h    |  63 +-
 ...tbWrapperQtWidgetInputVectorDataListParameter.h |  59 +-
 .../include/otbWrapperQtWidgetListEditItemModel.h} | 174 ++--
 .../include/otbWrapperQtWidgetListEditWidget.h     | 207 +++++
 .../include/otbWrapperQtWidgetParameterBase.h      |  10 +-
 ...terBase.h => otbWrapperQtWidgetParameterList.h} |  64 +-
 .../otbWrapperQtWidgetStringListParameter.h        |  53 +-
 .../QtWidget/include/otbWrapperQtWidgetView.h      |   1 +
 Modules/Wrappers/QtWidget/src/CMakeLists.txt       |  19 +-
 .../src/otbWrapperQtWidgetChoiceParameter.cxx      |   4 +-
 ...tbWrapperQtWidgetComplexInputImageParameter.cxx |   4 +-
 ...bWrapperQtWidgetComplexOutputImageParameter.cxx |   4 +-
 .../src/otbWrapperQtWidgetDirectoryParameter.cxx   |   4 +-
 .../src/otbWrapperQtWidgetFloatParameter.cxx       |   6 +-
 ...tbWrapperQtWidgetInputFilenameListParameter.cxx | 373 +-------
 .../otbWrapperQtWidgetInputFilenameParameter.cxx   |   4 +-
 .../otbWrapperQtWidgetInputImageListParameter.cxx  | 385 +-------
 .../src/otbWrapperQtWidgetInputImageParameter.cxx  |   6 +-
 .../otbWrapperQtWidgetInputProcessXMLParameter.cxx |   4 +-
 ...WrapperQtWidgetInputVectorDataListParameter.cxx | 370 +-------
 .../otbWrapperQtWidgetInputVectorDataParameter.cxx |   4 +-
 .../src/otbWrapperQtWidgetIntParameter.cxx         |   4 +-
 .../src/otbWrapperQtWidgetListEditItemModel.cxx    | 483 ++++++++++
 .../src/otbWrapperQtWidgetListEditWidget.cxx       | 657 ++++++++++++++
 .../src/otbWrapperQtWidgetListEditWidget.ui        | 143 +++
 .../src/otbWrapperQtWidgetListViewParameter.cxx    |   4 +-
 .../QtWidget/src/otbWrapperQtWidgetModel.cxx       |  37 +-
 .../otbWrapperQtWidgetOutputFilenameParameter.cxx  |   4 +-
 .../src/otbWrapperQtWidgetOutputImageParameter.cxx |   4 +-
 ...otbWrapperQtWidgetOutputProcessXMLParameter.cxx |   4 +-
 ...otbWrapperQtWidgetOutputVectorDataParameter.cxx |   4 +-
 .../src/otbWrapperQtWidgetParameterBase.cxx        |  15 +
 .../src/otbWrapperQtWidgetParameterFactory.cxx     |  55 +-
 .../src/otbWrapperQtWidgetParameterList.cxx        |  94 ++
 .../src/otbWrapperQtWidgetRAMParameter.cxx         |   4 +-
 .../src/otbWrapperQtWidgetSimpleProgressReport.cxx |   2 +
 .../src/otbWrapperQtWidgetStringListParameter.cxx  | 110 +--
 .../src/otbWrapperQtWidgetStringParameter.cxx      |   8 +-
 .../QtWidget/src/otbWrapperQtWidgetView.cxx        |  13 +-
 Modules/Wrappers/SWIG/otb-module-init.cmake        |  61 +-
 Modules/Wrappers/SWIG/src/CMakeLists.txt           | 110 +--
 Modules/Wrappers/SWIG/src/java/CMakeLists.txt      |  70 ++
 Modules/Wrappers/SWIG/src/otbApplication.i         |  97 +-
 Modules/Wrappers/SWIG/src/python/CMakeLists.txt    |  72 ++
 .../SWIG/src/{ => python}/itkPyCommand.cxx         |   0
 .../Wrappers/SWIG/src/{ => python}/itkPyCommand.h  |   0
 Modules/Wrappers/SWIG/src/python3/CMakeLists.txt   |  73 ++
 Modules/Wrappers/SWIG/test/java/CMakeLists.txt     |   2 +-
 Modules/Wrappers/SWIG/test/python/Bug1498.py       |  38 +
 Modules/Wrappers/SWIG/test/python/Bug823.py        |   2 +-
 Modules/Wrappers/SWIG/test/python/CMakeLists.txt   |   8 +
 .../SWIG/test/python/PythonConnectApplications.py  |   2 +-
 .../test/python/PythonNewStyleParametersTest.py    |   2 +-
 Packaging/CMakeLists.txt                           |  15 +-
 Packaging/Files/mapla.bat                          |   7 +-
 Packaging/Files/monteverdi.bat                     |   7 +-
 Packaging/Files/otbenv.profile                     |  15 -
 Packaging/Files/selftester.sh                      |  41 +-
 Packaging/Files/uninstall_otb.bat                  |  92 +-
 Packaging/Files/uninstall_otb.sh                   |   4 +-
 ..._bindings.cmake => install_java_bindings.cmake} |  10 +-
 Packaging/install_python_bindings.cmake            |   8 +
 Packaging/install_rule.cmake                       |   2 +
 RELEASE_NOTES.txt                                  |  43 +-
 Utilities/Data/Icons/forbidden-24x24.png           | Bin 0 -> 1290 bytes
 Utilities/Maintenance/SuperbuildDownloadList.sh    |  39 +-
 i18n/fr_FR.ts                                      |  44 +-
 455 files changed, 11221 insertions(+), 4837 deletions(-)

diff --git a/CMake/CTestCustom.cmake.in b/CMake/CTestCustom.cmake.in
index a2416c6..9d7cc2a 100644
--- a/CMake/CTestCustom.cmake.in
+++ b/CMake/CTestCustom.cmake.in
@@ -62,8 +62,9 @@ set(CTEST_CUSTOM_COVERAGE_EXCLUDE
  ".*/Utilities/.*"
 
  # Exclude SWIG wrappers files
- ".*/Modules/Wrappers/SWIG/src/otbApplicationPYTHON_wrap.*"
- ".*/Modules/Wrappers/SWIG/src/otbApplicationJAVA_wrap.*"
+ ".*/Modules/Wrappers/SWIG/src/python/otbApplicationPYTHON_wrap.*"
+ ".*/Modules/Wrappers/SWIG/src/python3/otbApplicationPYTHON_wrap.*"
+ ".*/Modules/Wrappers/SWIG/src/java/otbApplicationJAVA_wrap.*"
 
  # Exclude Qt moc file
  ".*moc_.*"
diff --git a/CMake/FindOssim.cmake b/CMake/FindOssim.cmake
index bc15b82..228c334 100644
--- a/CMake/FindOssim.cmake
+++ b/CMake/FindOssim.cmake
@@ -35,14 +35,10 @@ find_path( OSSIM_INCLUDE_DIR
            NAMES ossim/init/ossimInit.h )
 
 # Version checking
+set(OSSIM_VERSION)
 if(EXISTS "${OSSIM_INCLUDE_DIR}/ossim/ossimVersion.h")
   file(READ "${OSSIM_INCLUDE_DIR}/ossim/ossimVersion.h" _ossim_version_h_CONTENTS)
   string(REGEX REPLACE ".*# *define OSSIM_VERSION *\"([0-9.]+)\".*" "\\1" OSSIM_VERSION "${_ossim_version_h_CONTENTS}")
-  string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" OSSIM_MAJOR_VERSION_NUMBER "${OSSIM_VERSION}")
-  string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" OSSIM_MINOR_VERSION_NUMBER "${OSSIM_VERSION}")
-  string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\3" OSSIM_PATCH_VERSION_NUMBER "${OSSIM_VERSION}")
-  math(EXPR OSSIM_VERSION_NUMBER
-    "((${OSSIM_MAJOR_VERSION_NUMBER})*100+${OSSIM_MINOR_VERSION_NUMBER})*100+${OSSIM_PATCH_VERSION_NUMBER}")
   if("${OSSIM_VERSION}" VERSION_LESS "1.8.20")
     message(WARNING "The OSSIM include directory detected by OTB is: '${OSSIM_INCLUDE_DIR}'."
       "This version (${OSSIM_VERSION}) is not fully compatible with OTB."
@@ -67,6 +63,28 @@ else()
   endif()
 endif()
 
+# Hack to detect version 2.2.0, without ossimVersion.h
+if(EXISTS "${OSSIM_INCLUDE_DIR}/ossim/projection/ossimRpcSolver.h")
+  file(STRINGS "${OSSIM_INCLUDE_DIR}/ossim/projection/ossimRpcSolver.h" _ossim_rpc_solv_content)
+  if(_ossim_rpc_solv_content MATCHES "const +ossimRefPtr<ossimRpcModel> +getRpcModel\\(\\)")
+    if((NOT OSSIM_VERSION) OR (OSSIM_VERSION VERSION_LESS "2.2.0"))
+      set(OSSIM_VERSION "2.2.0")
+    endif()
+  endif()
+endif()
+
+if(OSSIM_VERSION)
+  string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" OSSIM_MAJOR_VERSION_NUMBER "${OSSIM_VERSION}")
+  string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" OSSIM_MINOR_VERSION_NUMBER "${OSSIM_VERSION}")
+  string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\3" OSSIM_PATCH_VERSION_NUMBER "${OSSIM_VERSION}")
+  math(EXPR OSSIM_VERSION_NUMBER
+    "((${OSSIM_MAJOR_VERSION_NUMBER})*100+${OSSIM_MINOR_VERSION_NUMBER})*100+${OSSIM_PATCH_VERSION_NUMBER}")
+else()
+  # Unknown version : default to 0
+  set(OSSIM_VERSION_NUMBER 0)
+endif()
+
+# Look for the library
 find_library(OSSIM_LIBRARY
              NAMES ossim)
 
diff --git a/CMake/UseSWIGLocal.cmake b/CMake/UseSWIGLocal.cmake
index 639143c..3f7b798 100644
--- a/CMake/UseSWIGLocal.cmake
+++ b/CMake/UseSWIGLocal.cmake
@@ -122,10 +122,6 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
 
   set(swig_generated_file_fullname
     "${CMAKE_CURRENT_BINARY_DIR}")
-  if(swig_source_file_relative_path)
-    set(swig_generated_file_fullname
-      "${swig_generated_file_fullname}/${swig_source_file_relative_path}")
-  endif()
   # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
   if(CMAKE_SWIG_OUTDIR)
     set(swig_outdir ${CMAKE_SWIG_OUTDIR})
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0d5309f..c99b0c7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -47,6 +47,19 @@ set(CMAKE_CXX_STANDARD 14)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS OFF)
 
+# Check compiler versions
+set(OTB_MIN_GNU_VER 5)
+set(OTB_MIN_MSVC_VER 19)
+set(OTB_MIN_Clang_VER 3.4)
+if(DEFINED OTB_MIN_${CMAKE_CXX_COMPILER_ID}_VER)
+  if(CMAKE_CXX_COMPILER_VERSION AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${OTB_MIN_${CMAKE_CXX_COMPILER_ID}_VER})
+    message(STATUS "WARNING: the version of your ${CMAKE_CXX_COMPILER_ID} "
+      "compiler is not supported by Orfeo ToolBox (C++14 support might be "
+      "incomplete). Please consider updating your compiler to version "
+      "${OTB_MIN_${CMAKE_CXX_COMPILER_ID}_VER} or later.")
+  endif()
+endif()
+
 include(CMakeDependentOption)
 #
 # use ExternalProject
@@ -110,7 +123,7 @@ set(main_project_name ${_OTBModuleMacros_DEFAULT_LABEL})
 #-----------------------------------------------------------------------------
 # OTB version number.
 set(OTB_VERSION_MAJOR "6")
-set(OTB_VERSION_MINOR "2")
+set(OTB_VERSION_MINOR "4")
 set(OTB_VERSION_PATCH "0")
 set(OTB_VERSION_STRING "${OTB_VERSION_MAJOR}.${OTB_VERSION_MINOR}.${OTB_VERSION_PATCH}")
 
@@ -145,6 +158,9 @@ endif()
 if(NOT OTB_INSTALL_PYTHON_DIR)
   set(OTB_INSTALL_PYTHON_DIR "lib/otb/python")
 endif()
+if(NOT OTB_INSTALL_PYTHON3_DIR)
+  set(OTB_INSTALL_PYTHON3_DIR "lib/otb/python3")
+endif()
 if(NOT OTB_INSTALL_JAVA_DIR)
   set(OTB_INSTALL_JAVA_DIR "lib/otb/java")
 endif()
diff --git a/Examples/Application/ApplicationExample.cxx b/Examples/Application/ApplicationExample.cxx
index 007a204..420adc0 100644
--- a/Examples/Application/ApplicationExample.cxx
+++ b/Examples/Application/ApplicationExample.cxx
@@ -81,11 +81,8 @@ public:
   //  Software Guide : EndLatex
 
   //  Software Guide : BeginCodeSnippet
-  itkNewMacro(Self)
-;
-
-  itkTypeMacro(ExampleApplication, otb::Application)
-;
+  itkNewMacro(Self);
+  itkTypeMacro(ExampleApplication, otb::Application);
   //  Software Guide : EndCodeSnippet
 
 
@@ -136,7 +133,7 @@ private:
 
     // Software Guide : BeginLatex
     // \code{AddDocTag()} method categorize the application using relevant tags.
-    // \code{Code/ApplicationEngine/otbWrapperTags.h} contains some predefined tags defined in \code{Tags} namespace.
+    // The header file \code{otbWrapperTags.h} in OTB sources contains some predefined tags defined in \code{Tags} namespace.
     // Software Guide : EndLatex
 
     //  Software Guide : BeginCodeSnippet
@@ -146,52 +143,63 @@ private:
 
     // Software Guide : BeginLatex
     // Application parameters declaration is done using \code{AddParameter()} method.
-    // \code{AddParameter()} requires Parameter type, its name and description.
+    // \code{AddParameter()} requires the input parameter type
+    // (ParameterType_InputImage, ParameterType_Int, ParameterType_Float), its name and description.
     // \subdoxygen{otb}{Wrapper}{Application} class contains methods to set parameters characteristics.
     // Software Guide : EndLatex
 
     //  Software Guide : BeginCodeSnippet
     AddParameter(ParameterType_InputImage, "in", "Input Image");
+
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
-    AddParameter(ParameterType_Empty, "boolean", "Boolean");
-    MandatoryOff("boolean");
-    AddParameter(ParameterType_Int, "int", "Integer");
-    MandatoryOff("int");
-    SetDefaultParameterInt("int", 1);
-    SetMinimumParameterIntValue("int", 0);
-    SetMaximumParameterIntValue("int", 10);
-    AddParameter(ParameterType_Float, "float", "Float");
-    MandatoryOff("float");
-    SetDefaultParameterFloat("float", 0.2);
-    SetMinimumParameterFloatValue("float", -1.0);
-    SetMaximumParameterFloatValue("float", 15.0);
-    AddParameter(ParameterType_String, "string", "String");
-    MandatoryOff("string");
-    AddParameter(ParameterType_InputFilename, "filename", "File name");
-    MandatoryOff("filename");
-    AddParameter(ParameterType_Directory, "directory", "Directory name");
-    MandatoryOff("directory");
-
-    AddParameter(ParameterType_Choice, "choice", "Choice");
-    AddChoice("choice.choice1", "Choice 1");
-    AddChoice("choice.choice2", "Choice 2");
-    AddChoice("choice.choice3", "Choice 3");
-    AddParameter(ParameterType_Float, "choice.choice1.floatchoice1"
-                 , "Float of choice1");
-    SetDefaultParameterFloat("choice.choice1.floatchoice1", 0.125);
-    AddParameter(ParameterType_Float, "choice.choice3.floatchoice3"
-                 , "Float of choice3");
-    SetDefaultParameterFloat("choice.choice3.floatchoice3", 5.0);
-
-    AddParameter(ParameterType_Group, "ingroup", "Input Group");
+
+    AddParameter(ParameterType_Empty, "param1", "Example of boolean parameter");
+    MandatoryOff("param1");
+
+    AddParameter(ParameterType_Int, "param2", "Example of integer parameter");
+    MandatoryOff("param2");
+    SetDefaultParameterInt("param2", 1);
+    SetMinimumParameterIntValue("param2", 0);
+    SetMaximumParameterIntValue("param2", 10);
+
+    AddParameter(ParameterType_Float, "param3", "Example of float parameter");
+    MandatoryOff("param3");
+    SetDefaultParameterFloat("param3", 0.2);
+    SetMinimumParameterFloatValue("param3", -1.0);
+    SetMaximumParameterFloatValue("param3", 15.0);
+
+    AddParameter(ParameterType_String, "param4", "Example of string parameter");
+    MandatoryOff("param4");
+
+    AddParameter(ParameterType_InputFilename, "param5", "Example of filename");
+    MandatoryOff("param5");
+
+    AddParameter(ParameterType_Directory, "param6", "Example of directory name");
+    MandatoryOff("param6");
+
+    AddParameter(ParameterType_Choice, "inchoice", "Example of choice parameter");
+    AddChoice("inchoice.choice1", "Choice 1");
+    AddChoice("inchoice.choice2", "Choice 2");
+    AddChoice("inchoice.choice3", "Choice 3");
+      
+    AddParameter(ParameterType_Float, "inchoice.choice1.floatchoice1"
+                 , "Example of float parameter for choice1");
+    SetDefaultParameterFloat("inchoice.choice1.floatchoice1", 0.125);
+
+    AddParameter(ParameterType_Float, "inchoice.choice3.floatchoice3"
+                 , "Example of float parameter for choice3");
+    SetDefaultParameterFloat("inchoice.choice3.floatchoice3", 5.0);
+
+    AddParameter(ParameterType_Group, "ingroup", "Input group");
     MandatoryOff("ingroup");
-    AddParameter(ParameterType_Int, "ingroup.integer", "Integer of Group");
-    MandatoryOff("ingroup.integer");
-    AddParameter(ParameterType_Group, "ingroup.images", "Input Images Group");
+    AddParameter(ParameterType_Int, "ingroup.valint", "Example of integer parameter for group");
+    MandatoryOff("ingroup.valint");
+    AddParameter(ParameterType_Group, "ingroup.images", "Input Images group");
     AddParameter(ParameterType_InputImage, "ingroup.images.inputimage"
                  , "Input Image");
     MandatoryOff("ingroup.images.inputimage");
-    AddParameter(ParameterType_Group, "outgroup", "Output Group");
+
+    AddParameter(ParameterType_Group, "outgroup", "Output group");
     MandatoryOff("outgroup");
     AddParameter(ParameterType_OutputImage, "outgroup.outputimage"
                  , "Output Image");
@@ -199,7 +207,7 @@ private:
     AddParameter(ParameterType_InputImageList, "il", "Input image list");
     MandatoryOff("il");
 
-    AddParameter(ParameterType_ListView, "cl", "Output Image channels");
+    AddParameter(ParameterType_ListView, "cl", "Output image channels");
     AddChoice("cl.choice1", "cl.choice1");
     AddChoice("cl.choice2", "cl.choice2");
     MandatoryOff("cl");
@@ -208,14 +216,14 @@ private:
     SetDefaultParameterInt("ram", 256);
     MandatoryOff("ram");
 
-    AddParameter(ParameterType_ComplexInputImage, "cin", "Input Complex Image");
-    AddParameter(ParameterType_ComplexOutputImage, "cout", "Output Complex Image");
+    AddParameter(ParameterType_ComplexInputImage, "cin", "Input complex image");
+    AddParameter(ParameterType_ComplexOutputImage, "cout", "Output complex image");
     MandatoryOff("cin");
     MandatoryOff("cout");
     //  Software Guide : EndCodeSnippet
 
     // Software Guide : BeginLatex
-    // An example commandline is automatically generated. Method \code{SetDocExampleParameterValue()} is
+    // An example of command-line is automatically generated. Method \code{SetDocExampleParameterValue()} is
     // used to set parameters. Dataset should be located in  \code{OTB-Data/Examples} directory.
     // Software Guide : EndLatex
 
@@ -231,7 +239,7 @@ private:
   // gives a complete description of this method.
   // Software Guide : EndLatex
   //  Software Guide :BeginCodeSnippet
-  void DoUpdateParameters() ITK_OVERRIDE
+  void DoUpdateParameters() override
   {
   }
   //  Software Guide : EndCodeSnippet
@@ -241,13 +249,13 @@ private:
   // gives a complete description of this method.
   // Software Guide : EndLatex
   //  Software Guide :BeginCodeSnippet
-  void DoExecute() ITK_OVERRIDE
+  void DoExecute() override
   {
     FloatVectorImageType::Pointer inImage = GetParameterImage("in");
 
-    int paramInt = GetParameterInt("int");
-    otbAppLogDEBUG( << paramInt <<std::endl );
-    int paramFloat = GetParameterFloat("float");
+    int paramInt = GetParameterInt("param2");
+    otbAppLogDEBUG( << paramInt << std::endl );
+    int paramFloat = GetParameterFloat("param3");
     otbAppLogINFO( << paramFloat );
 
     SetParameterOutputImage("out", inImage);
@@ -260,7 +268,7 @@ private:
 }
 
 // Software Guide : BeginLatex
-// Finally \code{OTB\_APPLICATION\_EXPORT} is called.
+// Finally \code{OTB\_APPLICATION\_EXPORT} is called:
 // Software Guide : EndLatex
 //  Software Guide :BeginCodeSnippet
 OTB_APPLICATION_EXPORT(otb::Wrapper::ApplicationExample)
diff --git a/Examples/Application/test/CMakeLists.txt b/Examples/Application/test/CMakeLists.txt
index 94e3fa9..5d82907 100644
--- a/Examples/Application/test/CMakeLists.txt
+++ b/Examples/Application/test/CMakeLists.txt
@@ -21,6 +21,6 @@
 otb_test_application(NAME apTeGenerateAnApplicationExample
   APP ApplicationExample
   OPTIONS -in ${OTB_DATA_ROOT}/Examples/QB_Suburb.png
-          -out ${TEMP}/apTeGenerateAnApplicationExampleOutput.png)
+          -out ${TEMP}/apTeGenerateAnApplicationExampleOutput.png uint8)
 
 set_tests_properties(apTeGenerateAnApplicationExample PROPERTIES DEPENDS otbapp_ApplicationExample)
diff --git a/Examples/Classification/ClassificationMapRegularizationExample.cxx b/Examples/Classification/ClassificationMapRegularizationExample.cxx
index 4f96cee..d0d2339 100644
--- a/Examples/Classification/ClassificationMapRegularizationExample.cxx
+++ b/Examples/Classification/ClassificationMapRegularizationExample.cxx
@@ -46,8 +46,6 @@
 #include <otbImageFileReader.h>
 #include "otbImageFileWriter.h"
 
-#include "itkTimeProbe.h"
-
 
 int main(int itkNotUsed(argc), char * argv[])
 {
diff --git a/Examples/DataRepresentation/Image/Image4.cxx b/Examples/DataRepresentation/Image/Image4.cxx
index 269524c..d085b71 100644
--- a/Examples/DataRepresentation/Image/Image4.cxx
+++ b/Examples/DataRepresentation/Image/Image4.cxx
@@ -114,20 +114,20 @@ int main(int, char *[])
   // Software Guide : BeginLatex
   //
   // The array can be assigned to the image using
-  // the \code{SetSpacing()} method.
+  // the \code{SetSignedSpacing()} method.
   //
-  // \index{otb::Image!SetSpacing()}
+  // \index{otb::Image!SetSignedSpacing()}
   //
   // Software Guide : EndLatex
 
   // Software Guide : BeginCodeSnippet
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
   // Software Guide : EndCodeSnippet
 
   //  Software Guide : BeginLatex
   //
   // The spacing information can be retrieved from an image by using the
-  // \code{GetSpacing()} method. This method returns a reference to a
+  // \code{GetSignedSpacing()} method. This method returns a reference to a
   // \code{FixedArray}. The returned object can then be used to read the
   // contents of the array. Note the use of the \code{const} keyword to indicate
   // that the array will not be modified.
@@ -135,7 +135,7 @@ int main(int, char *[])
   //  Software Guide : EndLatex
 
   // Software Guide : BeginCodeSnippet
-  const ImageType::SpacingType& sp = image->GetSpacing();
+  const ImageType::SpacingType& sp = image->GetSignedSpacing();
 
   std::cout << "Spacing = ";
   std::cout << sp[0] << ", " << sp[1] << std::endl;
diff --git a/Examples/DataRepresentation/Path/PolyLineParametricPath1.cxx b/Examples/DataRepresentation/Path/PolyLineParametricPath1.cxx
index da850ee..0847b7d 100644
--- a/Examples/DataRepresentation/Path/PolyLineParametricPath1.cxx
+++ b/Examples/DataRepresentation/Path/PolyLineParametricPath1.cxx
@@ -99,7 +99,7 @@ int main(int argc, char * argv[])
 
   ImagePointType origin = image->GetOrigin();
 
-  ImageType::SpacingType spacing = image->GetSpacing();
+  ImageType::SpacingType spacing = image->GetSignedSpacing();
   ImageType::SizeType    size    = image->GetBufferedRegion().GetSize();
 
   ImagePointType point;
diff --git a/Examples/DisparityMap/SimpleDisparityMapEstimationExample.cxx b/Examples/DisparityMap/SimpleDisparityMapEstimationExample.cxx
index 22d646b..ff70de1 100644
--- a/Examples/DisparityMap/SimpleDisparityMapEstimationExample.cxx
+++ b/Examples/DisparityMap/SimpleDisparityMapEstimationExample.cxx
@@ -374,7 +374,7 @@ int main(int argc, char* argv[])
 
   // Software Guide : BeginCodeSnippet
   generator->SetOutputOrigin(fixedReader->GetOutput()->GetOrigin());
-  generator->SetOutputSpacing(fixedReader->GetOutput()->GetSpacing());
+  generator->SetOutputSpacing(fixedReader->GetOutput()->GetSignedSpacing());
   generator->SetOutputSize(fixedReader->GetOutput()
                            ->GetLargestPossibleRegion().GetSize());
   // Software Guide : EndCodeSnippet
@@ -439,7 +439,7 @@ int main(int argc, char* argv[])
   warper->SetInput(movingReader->GetOutput());
   warper->SetDisplacementField(generator->GetOutput());
   warper->SetOutputOrigin(fixedReader->GetOutput()->GetOrigin());
-  warper->SetOutputSpacing(fixedReader->GetOutput()->GetSpacing());
+  warper->SetOutputSpacing(fixedReader->GetOutput()->GetSignedSpacing());
   // Software Guide : EndCodeSnippet
 
   // Software Guide : BeginLatex
diff --git a/Examples/FeatureExtraction/RightAngleDetectionExample.cxx b/Examples/FeatureExtraction/RightAngleDetectionExample.cxx
index 04eaaf3..453ebe1 100644
--- a/Examples/FeatureExtraction/RightAngleDetectionExample.cxx
+++ b/Examples/FeatureExtraction/RightAngleDetectionExample.cxx
@@ -179,7 +179,7 @@ int main(int argc, char * argv[])
 
   vectorDataRenderer->SetSize(reader->GetOutput()->GetLargestPossibleRegion().GetSize());
   vectorDataRenderer->SetOrigin(reader->GetOutput()->GetOrigin());
-  vectorDataRenderer->SetSpacing(reader->GetOutput()->GetSpacing());
+  vectorDataRenderer->SetSpacing(reader->GetOutput()->GetSignedSpacing());
   vectorDataRenderer->SetRenderingStyleType(VectorDataRendererType::Binary);
 
   blendingFilter->SetInput1(reader->GetOutput());
diff --git a/Examples/FeatureExtraction/SURFExample.cxx b/Examples/FeatureExtraction/SURFExample.cxx
index 8259160..f9432cd 100644
--- a/Examples/FeatureExtraction/SURFExample.cxx
+++ b/Examples/FeatureExtraction/SURFExample.cxx
@@ -237,7 +237,7 @@ int main(int argc, char * argv[])
 // Software Guide : EndLatex
 
  // Software Guide : BeginCodeSnippet
- ImageType::SpacingType spacing = reader->GetOutput()->GetSpacing();
+ ImageType::SpacingType spacing = reader->GetOutput()->GetSignedSpacing();
  ImageType::PointType origin = reader->GetOutput()->GetOrigin();
  //OutputImageType::SizeType size = outputImage->GetLargestPossibleRegion().GetSize();
 
diff --git a/Examples/IO/MetadataExample.cxx b/Examples/IO/MetadataExample.cxx
index a77e107..cfd2158 100644
--- a/Examples/IO/MetadataExample.cxx
+++ b/Examples/IO/MetadataExample.cxx
@@ -116,7 +116,7 @@ int main(int itkNotUsed(argc), char* argv[])
 //  SoftwareGuide: EndLatex
 
 // SoftwareGuide : BeginCodeSnippet
-  file << "Spacing " << image->GetSpacing() << std::endl;
+  file << "Spacing " << image->GetSignedSpacing() << std::endl;
   file << "Origin " << image->GetOrigin() << std::endl;
 
   file << "Projection REF " << image->GetProjectionRef() << std::endl;
diff --git a/Examples/Iterators/ImageLinearIteratorWithIndex2.cxx b/Examples/Iterators/ImageLinearIteratorWithIndex2.cxx
index e1d40f7..a18ffe3 100644
--- a/Examples/Iterators/ImageLinearIteratorWithIndex2.cxx
+++ b/Examples/Iterators/ImageLinearIteratorWithIndex2.cxx
@@ -104,7 +104,7 @@ int main(int argc, char *argv[])
 
   Index4DType   index4D   = region4D.GetIndex();
   Size4DType    size4D    = region4D.GetSize();
-  Spacing4DType spacing4D = image4D->GetSpacing();
+  Spacing4DType spacing4D = image4D->GetSignedSpacing();
   Origin4DType  origin4D  = image4D->GetOrigin();
 
   for (unsigned int i = 0; i < 3; ++i)
@@ -115,7 +115,7 @@ int main(int argc, char *argv[])
     origin3D[i]  = origin4D[i];
     }
 
-  image3D->SetSpacing(spacing3D);
+  image3D->SetSignedSpacing(spacing3D);
   image3D->SetOrigin(origin3D);
 
   Region3DType region3D;
diff --git a/Examples/Iterators/ImageRegionIterator.cxx b/Examples/Iterators/ImageRegionIterator.cxx
index 06441e2..11eed02 100644
--- a/Examples/Iterators/ImageRegionIterator.cxx
+++ b/Examples/Iterators/ImageRegionIterator.cxx
@@ -170,7 +170,7 @@ int main(int argc, char *argv[])
 // Software Guide : BeginCodeSnippet
   ImageType::Pointer outputImage = ImageType::New();
   outputImage->SetRegions(outputRegion);
-  const ImageType::SpacingType& spacing = reader->GetOutput()->GetSpacing();
+  const ImageType::SpacingType& spacing = reader->GetOutput()->GetSignedSpacing();
   const ImageType::PointType&   inputOrigin = reader->GetOutput()->GetOrigin();
   double                        outputOrigin[Dimension];
 
@@ -179,7 +179,7 @@ int main(int argc, char *argv[])
     outputOrigin[i] = inputOrigin[i] + spacing[i] * inputStart[i];
     }
 
-  outputImage->SetSpacing(spacing);
+  outputImage->SetSignedSpacing(spacing);
   outputImage->SetOrigin(outputOrigin);
   outputImage->Allocate();
 // Software Guide : EndCodeSnippet
diff --git a/Examples/Patented/EstimateAffineTransformationExample.cxx b/Examples/Patented/EstimateAffineTransformationExample.cxx
index 0ad58c9..40554e5 100644
--- a/Examples/Patented/EstimateAffineTransformationExample.cxx
+++ b/Examples/Patented/EstimateAffineTransformationExample.cxx
@@ -321,7 +321,7 @@ int main(int argc, char* argv[])
   resampler->SetTransform(estimator->GetAffineTransform());
   resampler->SetSize(fixedImage->GetLargestPossibleRegion().GetSize());
   resampler->SetOutputOrigin(fixedImage->GetOrigin());
-  resampler->SetOutputSpacing(fixedImage->GetSpacing());
+  resampler->SetOutputSpacing(fixedImage->GetSignedSpacing());
   resampler->SetDefaultPixelValue(100);
   // Software Guide : EndCodeSnippet
 
diff --git a/Examples/Patented/SIFTDisparityMapEstimation.cxx b/Examples/Patented/SIFTDisparityMapEstimation.cxx
index 0bc424d..f6799c4 100644
--- a/Examples/Patented/SIFTDisparityMapEstimation.cxx
+++ b/Examples/Patented/SIFTDisparityMapEstimation.cxx
@@ -304,7 +304,7 @@ int main(int argc, char* argv[])
   // Software Guide : BeginCodeSnippet
   ImageType::ConstPointer fixedImage = fixedReader->GetOutput();
 
-  deformer->SetOutputSpacing(fixedImage->GetSpacing());
+  deformer->SetOutputSpacing(fixedImage->GetSignedSpacing());
   deformer->SetOutputOrigin(fixedImage->GetOrigin());
   deformer->SetOutputRegion(fixedImage->GetLargestPossibleRegion());
   // Software Guide : EndCodeSnippet
diff --git a/Examples/Patented/SIFTExample.cxx b/Examples/Patented/SIFTExample.cxx
index 5936983..a7cf97e 100644
--- a/Examples/Patented/SIFTExample.cxx
+++ b/Examples/Patented/SIFTExample.cxx
@@ -234,7 +234,7 @@ int main(int argc, char * argv[])
     }
 
   PointsIteratorType        pIt = filter->GetOutput()->GetPoints()->Begin();
-  ImageType::SpacingType    spacing = reader->GetOutput()->GetSpacing();
+  ImageType::SpacingType    spacing = reader->GetOutput()->GetSignedSpacing();
   ImageType::PointType      origin = reader->GetOutput()->GetOrigin();
   OutputImageType::SizeType size =
     outputImage->GetLargestPossibleRegion().GetSize();
diff --git a/Examples/Patented/SIFTFastExample.cxx b/Examples/Patented/SIFTFastExample.cxx
index 9c5eefb..22b3b43 100644
--- a/Examples/Patented/SIFTFastExample.cxx
+++ b/Examples/Patented/SIFTFastExample.cxx
@@ -239,7 +239,7 @@ int main(int argc, char * argv[])
 // Software Guide : EndLatex
 
 // Software Guide : BeginCodeSnippet
-  ImageType::SpacingType    spacing = reader->GetOutput()->GetSpacing();
+  ImageType::SpacingType    spacing = reader->GetOutput()->GetSignedSpacing();
   ImageType::PointType      origin = reader->GetOutput()->GetOrigin();
 // Software Guide : EndCodeSnippet
 
diff --git a/Examples/Projections/GeometriesProjectionExample.cxx b/Examples/Projections/GeometriesProjectionExample.cxx
index ce5ed38..023c869 100644
--- a/Examples/Projections/GeometriesProjectionExample.cxx
+++ b/Examples/Projections/GeometriesProjectionExample.cxx
@@ -129,7 +129,7 @@ int main(int argc, char* argv[])
   // necessary for sensors
   filter->SetOutputOrigin(imageReader->GetOutput()->GetOrigin());
   // necessary for sensors
-  filter->SetOutputSpacing(imageReader->GetOutput()->GetSpacing());
+  filter->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing());
   // ~ wkt
   filter->SetOutputProjectionRef( imageReader->GetOutput()->GetProjectionRef());
   // Software Guide : EndCodeSnippet
diff --git a/Examples/Projections/SensorModelExample.cxx b/Examples/Projections/SensorModelExample.cxx
index 5fd771e..2fab615 100644
--- a/Examples/Projections/SensorModelExample.cxx
+++ b/Examples/Projections/SensorModelExample.cxx
@@ -93,7 +93,7 @@ int main(int argc, char* argv[])
   reader->GenerateOutputInformation();
 
   std::cout << "Original input imagine spacing: " <<
-  reader->GetOutput()->GetSpacing() << std::endl;
+  reader->GetOutput()->GetSignedSpacing() << std::endl;
 // Software Guide : EndCodeSnippet
 
 // Software Guide : BeginLatex
@@ -197,7 +197,7 @@ int main(int argc, char* argv[])
 
   outputImage->SetOrigin(origin);
   outputImage->SetRegions(region);
-  outputImage->SetSpacing(spacing);
+  outputImage->SetSignedSpacing(spacing);
   outputImage->Allocate();
 // Software Guide : EndCodeSnippet
 
diff --git a/Examples/Projections/VectorDataExtractROIExample.cxx b/Examples/Projections/VectorDataExtractROIExample.cxx
index 5bd357e..dfe1552 100644
--- a/Examples/Projections/VectorDataExtractROIExample.cxx
+++ b/Examples/Projections/VectorDataExtractROIExample.cxx
@@ -105,13 +105,13 @@ int main(int argc, char* argv[])
   TypedRegion::IndexType index;
 
   size[0]  = imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[0]
-             * imageReader->GetOutput()->GetSpacing()[0];
+             * imageReader->GetOutput()->GetSignedSpacing()[0];
   size[1]  = imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[1]
-             * imageReader->GetOutput()->GetSpacing()[1];
+             * imageReader->GetOutput()->GetSignedSpacing()[1];
   index[0] = imageReader->GetOutput()->GetOrigin()[0]
-             - 0.5 * imageReader->GetOutput()->GetSpacing()[0];
+             - 0.5 * imageReader->GetOutput()->GetSignedSpacing()[0];
   index[1] = imageReader->GetOutput()->GetOrigin()[1]
-             - 0.5 * imageReader->GetOutput()->GetSpacing()[1];
+             - 0.5 * imageReader->GetOutput()->GetSignedSpacing()[1];
   region.SetSize(size);
   region.SetOrigin(index);
 
diff --git a/Examples/Projections/VectorDataProjectionExample.cxx b/Examples/Projections/VectorDataProjectionExample.cxx
index 685960f..46cc784 100644
--- a/Examples/Projections/VectorDataProjectionExample.cxx
+++ b/Examples/Projections/VectorDataProjectionExample.cxx
@@ -143,7 +143,7 @@ int main(int argc, char* argv[])
   vectorDataProjection->SetOutputOrigin(
     imageReader->GetOutput()->GetOrigin());
   vectorDataProjection->SetOutputSpacing(
-    imageReader->GetOutput()->GetSpacing());
+    imageReader->GetOutput()->GetSignedSpacing());
   vectorDataProjection->SetOutputProjectionRef(
     imageReader->GetOutput()->GetProjectionRef());
   // Software Guide : EndCodeSnippet
diff --git a/Examples/Registration/ImageRegistration1.cxx b/Examples/Registration/ImageRegistration1.cxx
index 9bbc67b..06b1731 100644
--- a/Examples/Registration/ImageRegistration1.cxx
+++ b/Examples/Registration/ImageRegistration1.cxx
@@ -596,7 +596,7 @@ int main(int argc, char *argv[])
   FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput();
   resampler->SetSize(fixedImage->GetLargestPossibleRegion().GetSize());
   resampler->SetOutputOrigin(fixedImage->GetOrigin());
-  resampler->SetOutputSpacing(fixedImage->GetSpacing());
+  resampler->SetOutputSpacing(fixedImage->GetSignedSpacing());
   resampler->SetDefaultPixelValue(100);
   // Software Guide : EndCodeSnippet
 
diff --git a/Examples/Registration/ImageRegistration2.cxx b/Examples/Registration/ImageRegistration2.cxx
index 92924c5..497e3cf 100644
--- a/Examples/Registration/ImageRegistration2.cxx
+++ b/Examples/Registration/ImageRegistration2.cxx
@@ -481,7 +481,7 @@ int main(int argc, char *argv[])
 
   resample->SetSize(fixedImage->GetLargestPossibleRegion().GetSize());
   resample->SetOutputOrigin(fixedImage->GetOrigin());
-  resample->SetOutputSpacing(fixedImage->GetSpacing());
+  resample->SetOutputSpacing(fixedImage->GetSignedSpacing());
   resample->SetDefaultPixelValue(100);
 
   typedef  unsigned char OutputPixelType;
diff --git a/Examples/Registration/ImageRegistration5.cxx b/Examples/Registration/ImageRegistration5.cxx
index 6585c8b..cc5ef6d 100644
--- a/Examples/Registration/ImageRegistration5.cxx
+++ b/Examples/Registration/ImageRegistration5.cxx
@@ -277,7 +277,7 @@ int main(int argc, char *argv[])
   // Software Guide : BeginCodeSnippet
   FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput();
 
-  const SpacingType fixedSpacing = fixedImage->GetSpacing();
+  const SpacingType fixedSpacing = fixedImage->GetSignedSpacing();
   const OriginType  fixedOrigin  = fixedImage->GetOrigin();
   const RegionType  fixedRegion  = fixedImage->GetLargestPossibleRegion();
   const SizeType    fixedSize    = fixedRegion.GetSize();
@@ -297,7 +297,7 @@ int main(int argc, char *argv[])
   // Software Guide : BeginCodeSnippet
   MovingImageType::Pointer movingImage = movingImageReader->GetOutput();
 
-  const SpacingType movingSpacing = movingImage->GetSpacing();
+  const SpacingType movingSpacing = movingImage->GetSignedSpacing();
   const OriginType  movingOrigin  = movingImage->GetOrigin();
   const RegionType  movingRegion  = movingImage->GetLargestPossibleRegion();
   const SizeType    movingSize    = movingRegion.GetSize();
@@ -528,7 +528,7 @@ int main(int argc, char *argv[])
 
   resample->SetSize(fixedImage->GetLargestPossibleRegion().GetSize());
   resample->SetOutputOrigin(fixedImage->GetOrigin());
-  resample->SetOutputSpacing(fixedImage->GetSpacing());
+  resample->SetOutputSpacing(fixedImage->GetSignedSpacing());
   resample->SetDefaultPixelValue(100);
 
   typedef otb::ImageFileWriter<FixedImageType> WriterFixedType;
diff --git a/Examples/Registration/ImageRegistration9.cxx b/Examples/Registration/ImageRegistration9.cxx
index 1a063f3..87e62f7 100644
--- a/Examples/Registration/ImageRegistration9.cxx
+++ b/Examples/Registration/ImageRegistration9.cxx
@@ -544,7 +544,7 @@ int main(int argc, char *argv[])
 
   resampler->SetSize(fixedImage->GetLargestPossibleRegion().GetSize());
   resampler->SetOutputOrigin(fixedImage->GetOrigin());
-  resampler->SetOutputSpacing(fixedImage->GetSpacing());
+  resampler->SetOutputSpacing(fixedImage->GetSignedSpacing());
   resampler->SetDefaultPixelValue(100);
 
   typedef  unsigned char OutputPixelType;
diff --git a/Modules/Adapters/GdalAdapters/src/otbGeometriesToGeometriesFilter.cxx b/Modules/Adapters/GdalAdapters/src/otbGeometriesToGeometriesFilter.cxx
index 6082d4e..a01d804 100644
--- a/Modules/Adapters/GdalAdapters/src/otbGeometriesToGeometriesFilter.cxx
+++ b/Modules/Adapters/GdalAdapters/src/otbGeometriesToGeometriesFilter.cxx
@@ -25,7 +25,7 @@
 #include "otbGeometriesToGeometriesFilter.h"
 #include <cassert>
 #include "otbGeometriesSet.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include "otbMacro.h"
 
 /*===========================================================================*/
@@ -200,8 +200,7 @@ void otb::GeometriesToGeometriesFilter::GenerateData(void )
   assert(output && "Cann't filter a nil geometries set");
 
   // Start recursive processing
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   if (input)
     {
     this->Process(*input, *output);
@@ -212,7 +211,7 @@ void otb::GeometriesToGeometriesFilter::GenerateData(void )
     }
 
   chrono.Stop();
-  otbMsgDevMacro(<< "GeometriesToGeometriesFilter: geometries processed in " << chrono.GetMean() << " seconds.");
+  otbMsgDevMacro(<< "GeometriesToGeometriesFilter: geometries processed in " << chrono.GetElapsedMilliseconds() << " ms.");
 }
 
 /*virtual*/
diff --git a/Modules/Adapters/OSSIMAdapters/src/CMakeLists.txt b/Modules/Adapters/OSSIMAdapters/src/CMakeLists.txt
index 20046e7..5bb6d44 100644
--- a/Modules/Adapters/OSSIMAdapters/src/CMakeLists.txt
+++ b/Modules/Adapters/OSSIMAdapters/src/CMakeLists.txt
@@ -41,7 +41,16 @@ target_link_libraries(OTBOSSIMAdapters
   ${OTBOssim_LIBRARIES}
   ${OTBOssimPlugins_LIBRARIES}
   ${OTBOpenThreads_LIBRARIES}
-
   )
 
 otb_module_target(OTBOSSIMAdapters)
+
+# add the OTB_OSSIM_VERSION definition
+get_target_property(_OTBOSSIMAdapters_COMP_DEF OTBOSSIMAdapters COMPILE_DEFINITIONS)
+if(_OTBOSSIMAdapters_COMP_DEF)
+  set_target_properties(OTBOSSIMAdapters
+    PROPERTIES COMPILE_DEFINITIONS "${_OTBOSSIMAdapters_COMP_DEF};OTB_OSSIM_VERSION=${OTB_OSSIM_VERSION}")
+else()
+  set_target_properties(OTBOSSIMAdapters
+    PROPERTIES COMPILE_DEFINITIONS "OTB_OSSIM_VERSION=${OTB_OSSIM_VERSION}")
+endif()
diff --git a/Modules/Adapters/OSSIMAdapters/src/otbRPCSolverAdapter.cxx b/Modules/Adapters/OSSIMAdapters/src/otbRPCSolverAdapter.cxx
index dce63c8..493cd5f 100644
--- a/Modules/Adapters/OSSIMAdapters/src/otbRPCSolverAdapter.cxx
+++ b/Modules/Adapters/OSSIMAdapters/src/otbRPCSolverAdapter.cxx
@@ -112,7 +112,11 @@ RPCSolverAdapter::Solve(const GCPsContainerType& gcpContainer,
   rmsError = rpcSolver->getRmsError();
 
   // Retrieve the output RPC projection
+#if OTB_OSSIM_VERSION < 20200
   ossimRefPtr<ossimRpcProjection> rpcProjection = dynamic_cast<ossimRpcProjection*>(rpcSolver->createRpcProjection()->getProjection());
+#else
+  ossimRefPtr<ossimRpcModel> rpcProjection = rpcSolver->getRpcModel();
+#endif
 
   // Export the sensor model in an ossimKeywordlist
   ossimKeywordlist geom_kwl;
diff --git a/Modules/Adapters/QtAdapters/src/otbQtAdapters.cxx b/Modules/Adapters/QtAdapters/src/otbQtAdapters.cxx
index e34a2f1..89f457d 100644
--- a/Modules/Adapters/QtAdapters/src/otbQtAdapters.cxx
+++ b/Modules/Adapters/QtAdapters/src/otbQtAdapters.cxx
@@ -211,11 +211,13 @@ SetWorkingDir( const QString & filepath )
   QFileInfo finfo( filepath );
 
 #if 0
-  return QDir::setCurrent(
-    finfo.isDir()
-    ? filepath
-    : finfo.path()
-  );
+  return
+    QDir::setCurrent(
+      finfo.isDir()
+      ? filepath
+      : finfo.path()
+    );
+
 #else
   // TODO : add mutex if needed
   QString dir = finfo.isDir() ? filepath : finfo.path();
@@ -223,6 +225,7 @@ SetWorkingDir( const QString & filepath )
     return false;
   RecentDirectory = finfo.isDir() ? filepath : finfo.path();
   return true;
+
 #endif
 }
 
diff --git a/Modules/Applications/AppChangeDetection/app/CMakeLists.txt b/Modules/Applications/AppChangeDetection/app/CMakeLists.txt
index cf5f9c2..71af979 100644
--- a/Modules/Applications/AppChangeDetection/app/CMakeLists.txt
+++ b/Modules/Applications/AppChangeDetection/app/CMakeLists.txt
@@ -18,11 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppChangeDetection_LINK_LIBS
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBChangeDetection_LIBRARIES}
-)
-
 otb_create_application(
   NAME           MultivariateAlterationDetector
   SOURCES        otbMultivariateAlterationDetector.cxx
diff --git a/Modules/Applications/AppClassification/app/CMakeLists.txt b/Modules/Applications/AppClassification/app/CMakeLists.txt
index cfa104e..3e1dbd8 100644
--- a/Modules/Applications/AppClassification/app/CMakeLists.txt
+++ b/Modules/Applications/AppClassification/app/CMakeLists.txt
@@ -18,33 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppClassification_LINK_LIBS
-  ${OTBVectorDataBase_LIBRARIES}
-  ${OTBConversion_LIBRARIES}
-  ${OTBStatistics_LIBRARIES}
-  ${OTBColorMap_LIBRARIES}
-  ${OTBBoost_LIBRARIES}
-  ${OTBInterpolation_LIBRARIES}
-  ${OTBMajorityVoting_LIBRARIES}
-  ${OTBVectorDataIO_LIBRARIES}
-  ${OTBSOM_LIBRARIES}
-  ${OTBSVMLearning_LIBRARIES}
-  ${OTBLearningBase_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBIndices_LIBRARIES}
-  ${OTBMathParser_LIBRARIES}
-  ${OTBDempsterShafer_LIBRARIES}
-  ${OTBGdalAdapters_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBIOXML_LIBRARIES}
-  ${OTBVectorDataManipulation_LIBRARIES}
-  ${OTBStreaming_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-  ${OTBCommon_LIBRARIES}
-)
-
 otb_create_application(
   NAME           ComputeOGRLayersFeaturesStatistics
   SOURCES        otbComputeOGRLayersFeaturesStatistics.cxx
@@ -80,10 +53,12 @@ otb_create_application(
   SOURCES        otbComputePolylineFeatureFromImage.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
 
-otb_create_application(
-  NAME           KMeansClassification
-  SOURCES        otbKMeansClassification.cxx
-  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+if(OTB_USE_SHARK)
+  otb_create_application(
+    NAME           KMeansClassification
+    SOURCES        otbKMeansClassification.cxx
+    LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+endif()
 
 otb_create_application(
   NAME           TrainImagesClassifier
diff --git a/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx b/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx
index 385a97c..1e098e7 100644
--- a/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx
+++ b/Modules/Applications/AppClassification/app/otbComputePolylineFeatureFromImage.cxx
@@ -219,10 +219,10 @@ private:
 
       TransformType::ParametersType params;
       params.SetSize(6);
-      params[0] = inImage->GetSpacing()[0];
+      params[0] = inImage->GetSignedSpacing()[0];
       params[1] = 0;
       params[2] = 0;
-      params[3] = inImage->GetSpacing()[1];
+      params[3] = inImage->GetSignedSpacing()[1];
       params[4] = inImage->GetOrigin()[0];
       params[5] = inImage->GetOrigin()[1];
 
@@ -250,7 +250,7 @@ private:
         vproj->SetOutputKeywordList(inImage->GetImageKeywordlist());
         vproj->SetOutputProjectionRef(inImage->GetProjectionRef());
         vproj->SetOutputOrigin(inImage->GetOrigin());
-        vproj->SetOutputSpacing(inImage->GetSpacing());
+        vproj->SetOutputSpacing(inImage->GetSignedSpacing());
 
         // Setup the DEM Handler
         otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev");
diff --git a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
index d8e2342..a5067bf 100644
--- a/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
+++ b/Modules/Applications/AppClassification/app/otbKMeansClassification.cxx
@@ -405,6 +405,8 @@ private:
       "KMeansClassification is a composite application, "
       "using an existing training and classification application."
       "The SharkKMeans model is used.\n"
+      "KMeansClassification application is only available if OTB is compiled with Shark support"
+      "(CMake option OTB_USE_SHARK=ON)\n"
       "The steps of this composite application :\n"
         "1) ImageEnveloppe : create a shapefile (1 polygon),\n"
         "2) PolygonClassStatistics : compute the statistics,\n"
diff --git a/Modules/Applications/AppClassification/app/otbTrainRegression.cxx b/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
index 0140e5f..690d03d 100644
--- a/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainRegression.cxx
@@ -29,7 +29,6 @@
 // Statistic XML Reader
 #include "otbStatisticsXMLFileReader.h"
 
-#include "itkTimeProbe.h"
 #include "otbStandardFilterWatcher.h"
 
 // Normalize the samples
@@ -117,53 +116,74 @@ void DoInit() ITK_OVERRIDE
     "lists are built such that their size is inferior to maximum bounds given "
     "by the user, and the proportion corresponds to the balance parameter. "
     "Several classifier parameters can be set depending on the chosen "
-    "classifier. In the validation process, the mean square error is computed\n"
+    "classifier. In the validation process, the mean square error is computed "
+    "between the ground truth and the estimated model.\n"
     " This application is based on LibSVM and on OpenCV Machine Learning "
     "classifiers, and is compatible with OpenCV 2.3.1 and later.");
   SetDocLimitations("None");
   SetDocAuthors("OTB-Team");
-  SetDocSeeAlso("OpenCV documentation for machine learning http://docs.opencv.org/modules/ml/doc/ml.html ");
+  SetDocSeeAlso("OpenCV documentation for machine learning "
+    "http://docs.opencv.org/modules/ml/doc/ml.html ");
 
   //Group IO
-  AddParameter(ParameterType_Group, "io", "Input and output data");
-  SetParameterDescription("io", "This group of parameters allows setting input and output data.");
-  AddParameter(ParameterType_InputImageList, "io.il", "Input Image List");
-  SetParameterDescription("io.il", "A list of input images. First (n-1) bands should contain the predictor. The last band should contain the output value to predict.");
-  AddParameter(ParameterType_InputFilename, "io.csv", "Input CSV file");
-  SetParameterDescription("io.csv","Input CSV file containing the predictors, and the output values in last column. Only used when no input image is given");
-  MandatoryOff("io.csv");
-
-  AddParameter(ParameterType_InputFilename, "io.imstat", "Input XML image statistics file");
-  MandatoryOff("io.imstat");
-  SetParameterDescription("io.imstat",
-                          "Input XML file containing the mean and the standard deviation of the input images.");
-  AddParameter(ParameterType_OutputFilename, "io.out", "Output regression model");
-  SetParameterDescription("io.out", "Output file containing the model estimated (.txt format).");
-
-  AddParameter(ParameterType_Float,"io.mse","Mean Square Error");
-  SetParameterDescription("io.mse","Mean square error computed with the validation predictors");
-  SetParameterRole("io.mse",Role_Output);
-  DisableParameter("io.mse");
+  AddParameter( ParameterType_Group , "io" , "Input and output data" );
+  SetParameterDescription("io" , 
+    "This group of parameters allows setting input and output data." );
+  AddParameter( ParameterType_InputImageList , "io.il", "Input Image List" );
+  SetParameterDescription( "io.il" , 
+    "A list of input images. First (n-1) bands should contain the predictor. "
+    "The last band should contain the output value to predict." );
+  AddParameter( ParameterType_InputFilename , "io.csv" , "Input CSV file" );
+  SetParameterDescription( "io.csv" ,
+    "Input CSV file containing the predictors, and the output values in last "
+    "column. Only used when no input image is given" );
+  MandatoryOff( "io.csv" );
+
+  AddParameter( ParameterType_InputFilename , "io.imstat" , 
+    "Input XML image statistics file" );
+  MandatoryOff( "io.imstat" );
+  SetParameterDescription( "io.imstat",
+    "Input XML file containing the mean and the standard deviation of the "
+    "input images." );
+  AddParameter( ParameterType_OutputFilename , "io.out" ,
+    "Output regression model" );
+  SetParameterDescription( "io.out" , 
+    "Output file containing the model estimated (.txt format)." );
+
+  AddParameter( ParameterType_Float , "io.mse" , "Mean Square Error" );
+  SetParameterDescription( "io.mse" ,
+    "Mean square error computed with the validation predictors" );
+  SetParameterRole( "io.mse" , Role_Output );
+  DisableParameter( "io.mse" );
 
   //Group Sample list
-  AddParameter(ParameterType_Group, "sample", "Training and validation samples parameters");
-  SetParameterDescription("sample",
-                          "This group of parameters allows you to set training and validation sample lists parameters.");
-
-  AddParameter(ParameterType_Int, "sample.mt", "Maximum training predictors");
+  AddParameter( ParameterType_Group , "sample" , 
+    "Training and validation samples parameters" );
+  SetParameterDescription( "sample" ,
+    "This group of parameters allows you to set training and validation sample "
+    "lists parameters." );
+
+  AddParameter( ParameterType_Int , "sample.mt" , 
+    "Maximum training predictors");
   //MandatoryOff("mt");
-  SetDefaultParameterInt("sample.mt", 1000);
-  SetParameterDescription("sample.mt", "Maximum number of training predictors (default = 1000) (no limit = -1).");
+  SetDefaultParameterInt( "sample.mt" , 1000 );
+  SetParameterDescription( "sample.mt" , 
+    "Maximum number of training predictors (default = 1000) (no limit = -1).");
 
-  AddParameter(ParameterType_Int, "sample.mv", "Maximum validation predictors");
+  AddParameter( ParameterType_Int , "sample.mv" , 
+    "Maximum validation predictors");
   // MandatoryOff("mv");
-  SetDefaultParameterInt("sample.mv", 1000);
-  SetParameterDescription("sample.mv", "Maximum number of validation predictors (default = 1000) (no limit = -1).");
-
-  AddParameter(ParameterType_Float, "sample.vtr", "Training and validation sample ratio");
-  SetParameterDescription("sample.vtr",
-                          "Ratio between training and validation samples (0.0 = all training, 1.0 = all validation) (default = 0.5).");
-  SetParameterFloat("sample.vtr",0.5, false);
+  SetDefaultParameterInt( "sample.mv" , 1000 );
+  SetParameterDescription( "sample.mv" , 
+    "Maximum number of validation predictors (default = 1000) "
+    "(no limit = -1).");
+
+  AddParameter( ParameterType_Float , "sample.vtr" , 
+    "Training and validation sample ratio");
+  SetParameterDescription( "sample.vtr" ,
+    "Ratio between training and validation samples (0.0 = all training, "
+    "1.0 = all validation) (default = 0.5).");
+  SetParameterFloat( "sample.vtr" , 0.5 , false );
 
   Superclass::DoInit();
 
diff --git a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
index 1d1d387..f37eb30 100644
--- a/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
+++ b/Modules/Applications/AppClassification/app/otbTrainVectorClassifier.cxx
@@ -57,11 +57,13 @@ protected:
   void DoInit()
   {
     SetName( "TrainVectorClassifier" );
-    SetDescription( "Train a classifier based on labeled geometries and a list of features to consider." );
+    SetDescription( "Train a classifier based on labeled geometries and a "
+      "list of features to consider." );
 
     SetDocName( "Train Vector Classifier" );
     SetDocLongDescription( "This application trains a classifier based on "
-                                   "labeled geometries and a list of features to consider for classification." );
+      "labeled geometries and a list of features to consider for "
+      "classification." );
     SetDocLimitations( " " );
     SetDocAuthors( "OTB Team" );
     SetDocSeeAlso( " " );
diff --git a/Modules/Applications/AppDescriptors/app/CMakeLists.txt b/Modules/Applications/AppDescriptors/app/CMakeLists.txt
index 648fa7c..8942e2d 100644
--- a/Modules/Applications/AppDescriptors/app/CMakeLists.txt
+++ b/Modules/Applications/AppDescriptors/app/CMakeLists.txt
@@ -18,15 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppDescriptors_LINK_LIBS
-  ${OTBGdalAdapters_LIBRARIES}
-  ${OTBDescriptors_LIBRARIES}
-  ${OTBTransform_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBGDAL_LIBRARIES}
-)
-
 otb_create_application(
   NAME           HomologousPointsExtraction
   SOURCES        otbHomologousPointsExtraction.cxx
diff --git a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx
index f186df0..073e537 100644
--- a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx
+++ b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx
@@ -281,7 +281,7 @@ private:
           pprime1 = rsTransform->TransformPoint(point1);
           error = vcl_sqrt((point2[0]-pprime1[0])*(point2[0]-pprime1[0])+(point2[1]-pprime1[1])*(point2[1]-pprime1[1]));
 
-          if(error>GetParameterFloat("precision")*vcl_sqrt(vcl_abs(im2->GetSpacing()[0]*im2->GetSpacing()[1])))
+          if(error>GetParameterFloat("precision")*vcl_sqrt(vcl_abs(im2->GetSignedSpacing()[0]*im2->GetSignedSpacing()[1])))
             {
             filtered = true;
             }
diff --git a/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt b/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt
index fcde242..63c4a21 100644
--- a/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt
+++ b/Modules/Applications/AppDimensionalityReduction/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppDimensionalityReduction_LINK_LIBS
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBStatistics_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBDimensionalityReduction_LIBRARIES}
-)
-
 otb_create_application(
   NAME           DimensionalityReduction
   SOURCES        otbDimensionalityReduction.cxx
diff --git a/Modules/Applications/AppEdge/app/CMakeLists.txt b/Modules/Applications/AppEdge/app/CMakeLists.txt
index 31a9f46..e72b1e4 100644
--- a/Modules/Applications/AppEdge/app/CMakeLists.txt
+++ b/Modules/Applications/AppEdge/app/CMakeLists.txt
@@ -18,15 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppEdge_LINK_LIBS
-  ${OTBStatistics_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBEdge_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-)
-
 otb_create_application(
   NAME           LineSegmentDetection
   SOURCES        otbLineSegmentDetection.cxx
diff --git a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx
index b9eccc1..45bc66c 100644
--- a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx
+++ b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx
@@ -185,7 +185,7 @@ private:
       vproj->SetInput(vd);
       vproj->SetInputKeywordList(GetParameterImage("in")->GetImageKeywordlist());
       //vproj->SetInputOrigin(GetParameterImage("in")->GetOrigin());
-      //vproj->SetInputSpacing(GetParameterImage("in")->GetSpacing());
+      //vproj->SetInputSpacing(GetParameterImage("in")->GetSignedSpacing());
 
       // Setup the DEM Handler
       otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev");
diff --git a/Modules/Applications/AppFiltering/app/CMakeLists.txt b/Modules/Applications/AppFiltering/app/CMakeLists.txt
index d7f3dcd..fdd85cc 100644
--- a/Modules/Applications/AppFiltering/app/CMakeLists.txt
+++ b/Modules/Applications/AppFiltering/app/CMakeLists.txt
@@ -18,13 +18,12 @@
 # limitations under the License.
 #
 
-set(OTBAppFiltering_LINK_LIBS
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-)
-
 otb_create_application(
   NAME           Smoothing
   SOURCES        otbSmoothing.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
+otb_create_application(
+  NAME           ContrastEnhancement
+  SOURCES        otbContrastEnhancement.cxx
+  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
diff --git a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
new file mode 100644
index 0000000..3c55bf6
--- /dev/null
+++ b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
@@ -0,0 +1,995 @@
+/*
+ * 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 agreened 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 "otbWrapperApplication.h"
+#include "otbWrapperApplicationFactory.h"
+
+#include "otbVectorImageToImageListFilter.h"
+#include "otbImageListToVectorImageFilter.h"
+#include "otbStreamingStatisticsVectorImageFilter.h"
+#include "otbStreamingStatisticsImageFilter.h"
+#include "otbUnaryFunctorImageFilter.h"
+#include "itkStreamingImageFilter.h"
+#include "otbInPlacePassFilter.h"
+
+#include "otbComputeHistoFilter.h"
+#include "otbComputeGainLutFilter.h"
+#include "otbApplyGainFilter.h"
+#include "otbImageFileWriter.h"
+#include "itkImageRegionIterator.h"
+#include <string>
+#include "otbStreamingHistogramVectorImageFilter.h"
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+namespace Functor
+{
+
+class LuminanceOperator
+{
+typedef FloatVectorImageType::PixelType OutPixel;
+typedef FloatVectorImageType::PixelType InPixel;
+public:
+  LuminanceOperator() {}
+  unsigned int GetOutputSize()
+  {
+    return 1;
+  }
+  virtual ~LuminanceOperator() { }
+
+ OutPixel operator() (  InPixel  input )
+  { 
+  OutPixel out(1);  
+  out[0] = m_LumCoef[0] * input[m_Rgb[0]] + 
+           m_LumCoef[1] * input[m_Rgb[1]] + 
+           m_LumCoef[2] * input[m_Rgb[2]] ;
+  return out;
+  } // end operator ()
+
+
+  void SetRgb( std::vector<unsigned int> rgb)
+    {
+    m_Rgb = rgb;
+    }
+
+  void SetLumCoef(std::vector<float> lumCoef)
+    {
+    m_LumCoef = lumCoef;
+    }
+  std::vector<float> GetLumCoef()
+    {
+    return m_LumCoef;
+    }
+private:
+  std::vector<unsigned int> m_Rgb;
+  std::vector<float> m_LumCoef;
+}; // end of functor class  MultiplyOperator
+
+}  // end of functor 
+
+class ContrastEnhancement : public Application
+{
+public:
+  /** Standard class typedefs. */
+  typedef ContrastEnhancement	              Self;
+  typedef Application	                      Superclass;
+  typedef itk::SmartPointer < Self >	      Pointer;
+  typedef itk::SmartPointer < const Self >	ConstPointer;
+
+  typedef otb::VectorImage < unsigned int , 2 > HistogramType;
+  typedef otb::VectorImage < double , 2 > LutType;
+
+  typedef FloatImageType::PixelType ImagePixelType;
+
+  typedef otb::ComputeHistoFilter < FloatImageType , 
+                                    HistogramType > 
+          HistoFilterType;
+  typedef otb::ComputeGainLutFilter < HistogramType , 
+                                      LutType > 
+          GainLutFilterType;
+  typedef otb::ApplyGainFilter < FloatImageType , 
+                                 LutType , FloatImageType > 
+          ApplyFilterType;
+  typedef otb::ImageList < FloatImageType > ImageListType;
+
+  typedef otb::VectorImageToImageListFilter < FloatVectorImageType, 
+                                              ImageListType > 
+          VectorToImageListFilterType;
+
+  typedef otb::ImageListToVectorImageFilter < ImageListType, 
+                                              FloatVectorImageType > 
+          ImageListToVectorFilterType;
+
+  typedef otb::StreamingStatisticsVectorImageFilter < FloatVectorImageType >
+          VectorStatsFilterType;
+
+  typedef otb::StreamingStatisticsImageFilter < FloatImageType >
+          StatsFilterType;
+
+  typedef otb::UnaryFunctorImageFilter < FloatVectorImageType ,
+          FloatVectorImageType , Functor::LuminanceOperator > 
+          LuminanceFunctorType;
+
+  typedef itk::StreamingImageFilter < LutType , LutType > 
+          StreamingImageFilterType;
+
+  typedef otb::InPlacePassFilter < FloatImageType > BufferFilterType;
+
+  typedef otb::StreamingHistogramVectorImageFilter < FloatVectorImageType > 
+      HistoPersistentFilterType;
+
+  /** Standard macro */
+  itkNewMacro( Self );
+ 
+  itkTypeMacro( ContrastEnhancement , otb::Application );
+
+private:
+
+	void DoInit() override
+	{
+		SetName("ContrastEnhancement");
+    SetDescription("This application is the implementation of the histogram "
+      "equalization algorithm. It can be used to enhance contrast in an image "
+      "or to reduce the dynamic of the image without losing too much contrast. "
+      "It offers several options as a no data value, "
+      "a contrast limitation factor, a local version of the algorithm and "
+      "also a mode to equalized the luminance of the image.");
+
+    // Documentation
+    SetDocName("Contrast Enhancement");
+    SetDocLongDescription("This application is the implementation of the "
+      "histogram equalization algorithm. The idea of the algorithm is to use "
+      "the whole available dynamic. In order to do so it computes a histogram "
+      "over the image and then use the whole dynamic : meaning flattening the "
+      "histogram. That gives us gain for each bin that transform the original "
+      "histogram into the flat one. This gain is then apply on the original "
+      "image. Upon this coarse algorithm we added several option to allow "
+      "a finer result. First there is the limitation of the contrast. Many "
+      "ways can be used to do it, we choose to limit the contrast by modifying "
+      "the original histogram. To do so we clip the histogram at a given "
+      "height and redistribute equally among the bins the clipped population. "
+      "Then we add a local version of the algorithm. It is possible to apply "
+      "the algorithm on tiles of the image. That gives us gain depending on "
+      "the value of the pixel and its position in the image. In order to "
+      "smoothen the result we interpolate the gain between tiles.");
+    SetDocLimitations("None");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso(" ");
+
+    AddDocTag(Tags::Filter);
+
+    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
+    SetParameterDescription("in", "Input image.");
+    
+    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
+    SetParameterDescription("out", "Output image.");
+    
+    AddParameter(ParameterType_Int , "bins" , "Number of bin");
+    SetDefaultParameterInt("bins", 256);
+    SetParameterDescription("bins",
+      "Number of bin used to create the histogram");
+
+    AddParameter(ParameterType_Float , "hfact" , "Contrast Limitation");  
+    SetParameterDescription("hfact","This parameter will set the maximum "
+      "height accepted in a bin on the input image histogram. "
+      "The maximum height will be computed as hfact*eqHeight where eqHeight "
+      "is the height of the theoretical flat histogram. The higher hfact, the "
+      "higher the contrast.");
+    MandatoryOff("hfact");
+
+    AddParameter(ParameterType_Float , "nodata" , "Nodata Value");
+    SetParameterDescription("nodata","If there is a value in the "
+      "image that has no visualization meaning, it can be ignored by the "
+      "algorithm.");
+    MandatoryOff("nodata");
+
+    AddParameter(ParameterType_Choice , "spatial" , "Spatial parameters "
+      "for the histogram computation");
+    AddChoice( "spatial.local" , "Local" );
+    SetParameterDescription("spatial.local" , "The histograms will be "
+      "computed on the each thumbnail. Each of the histogram will be "
+      "equalized and the corresponding gain will be interpolated.");
+    AddChoice( "spatial.global" , "Global" );
+    SetParameterDescription("spatial.global" , "The histogram will be "
+      "computed on the whole image. The equalization will be done on "
+      "this single histogram.");
+
+ 
+    AddParameter(ParameterType_Int,"spatial.local.h" , 
+      "Thumbnail height in pixel");
+    AddParameter(ParameterType_Int,"spatial.local.w" , 
+      "Thumbnail width in pixel");
+
+    AddParameter(ParameterType_Choice , "minmax" , "Minimum and maximum "
+      "definition");
+    SetParameterDescription("minmax","Minimum and maximum value that will "
+      "bound the histogram.");
+    AddChoice( "minmax.auto" , "Automatic" );
+    SetParameterDescription("minmax.auto" , "Minimum and maximum value will "
+      "be computed on the image (nodata value won't be taken "
+      "into account) . Each band will have a minimum and a maximum.");
+    AddParameter(ParameterType_Empty, "minmax.auto.global", "Global");
+    SetParameterDescription("minmax.auto.global" , "Automatic"
+      "Min/max computation will result in the same minimum and maximum for "
+      "all the bands.");
+    AddChoice( "minmax.manuel" , "Manuel" );
+    SetParameterDescription("minmax.auto","Minimum and maximum value will be "
+      "set by the user");
+    AddParameter(ParameterType_Float , "minmax.manuel.min" , "Minimum");
+    AddParameter(ParameterType_Float , "minmax.manuel.max" , "Maximum");
+    MandatoryOff("minmax.manuel.min");
+    MandatoryOff("minmax.manuel.max");
+
+    AddParameter(ParameterType_Choice , "mode" , "What to equalized");
+    AddChoice( "mode.each" , "Channels" );
+    SetParameterDescription( "mode.each" ,
+      "Each channel is equalized independently" );
+    AddChoice( "mode.lum" , "Luminance" );
+    SetParameterDescription( "mode.lum" ,
+      "The luminance is equalized and then a gain is applied "
+      "on each channels. This gain for each channels will depend on"
+      "the weight (coef) of the channel in the luminance." );
+    AddParameter(ParameterType_Group , "mode.lum.red" , "Red Channel" );
+    AddParameter(ParameterType_Int , "mode.lum.red.ch" , "Red Channel" );
+    SetDefaultParameterInt("mode.lum.red.ch", 0 );
+    AddParameter(ParameterType_Float , "mode.lum.red.coef" ,
+      "Value for luminance computation" );
+    SetDefaultParameterFloat("mode.lum.red.coef", 0.21 );
+
+    AddParameter(ParameterType_Group , "mode.lum.green" , "Green Channel" );
+    AddParameter(ParameterType_Int , "mode.lum.green.ch" , "Greenen Channel" );
+    SetDefaultParameterInt("mode.lum.green.ch", 1 );
+    AddParameter(ParameterType_Float , "mode.lum.green.coef" ,
+      "Value for luminance computation" );
+    SetDefaultParameterFloat("mode.lum.green.coef", 0.71 );
+
+    AddParameter(ParameterType_Group , "mode.lum.blue" , "Blue Channel" );
+    AddParameter(ParameterType_Int , "mode.lum.blue.ch" , "Blue Channel" );
+    SetDefaultParameterInt("mode.lum.blue.ch", 2 );
+    AddParameter(ParameterType_Float , "mode.lum.blue.coef" ,
+      "Value for luminance computation" );
+    SetDefaultParameterFloat("mode.lum.blue.coef", 0.08 );
+
+    SetDefaultParameterInt( "spatial.local.w" , 256 );
+    SetDefaultParameterInt( "spatial.local.h" , 256 );
+
+    SetMinimumParameterIntValue("mode.lum.red.ch", 0);
+    SetMinimumParameterIntValue("mode.lum.green.ch", 0);
+    SetMinimumParameterIntValue("mode.lum.blue.ch", 0);
+    SetMinimumParameterIntValue("bins", 2);
+    SetMinimumParameterIntValue("spatial.local.h", 1);
+    SetMinimumParameterIntValue("spatial.local.w", 1);
+
+    SetExampleComment( "Local contrast enhancement by luminance" , 0 );
+    SetDocExampleParameterValue( "in" , "couleurs.tif" );
+    SetDocExampleParameterValue( "out" , "equalizedcouleurs.tif float" );
+    SetDocExampleParameterValue( "bins" , "256" );
+    SetDocExampleParameterValue( "spatial.local.w" , "500" );
+    SetDocExampleParameterValue( "spatial.local.h" , "500");
+    SetDocExampleParameterValue( "mode" , "lum" );
+
+    AddRAMParameter(); 
+  }
+
+  void DoUpdateParameters() override
+  {
+    if ( HasValue("in") )
+      {
+      FloatVectorImageType * inImage = GetParameterImage("in");
+      FloatVectorImageType::RegionType::SizeType size;
+      size = inImage->GetLargestPossibleRegion().GetSize() ;
+
+      // if ( !HasUserValue("spatial.local.w") )
+      //   SetParameterInt( "spatial.local.w" , size[0] );
+        
+      // if ( !HasUserValue("spatial.local.h") )
+      //   SetParameterInt( "spatial.local.h" , size[1] );
+      
+      if ( GetParameterString("spatial") == "local" &&
+           HasValue("spatial.local.h") && HasValue("spatial.local.w") &&
+           HasValue("bins") )
+        CheckValidity();
+      
+      
+      if ( !HasUserValue("nodata") && IsParameterEnabled("nodata"))
+        SetDefaultValue( inImage , "NODATA" );
+
+      if ( GetParameterString( "mode" ) == "lum" && 
+           !HasUserValue("mode.lum.red.ch") &&
+           !HasUserValue("mode.lum.green.ch") &&
+           !HasUserValue("mode.lum.blue.ch") )
+        SetDefaultValue( inImage , "RGB" );
+
+      // if ( HasUserValue("minmax.manuel.min") && 
+      //      HasUserValue("minmax.manuel.max") )
+      //   {
+      //   if ( GetParameterFloat( "minmax.manuel.min" ) > 
+      //        GetParameterFloat( "minmax.manuel.max" ) )
+      //     {
+      //     float temp = GetParameterFloat( "minmax.manuel.min" );
+      //     SetParameterFloat( "minmax.manuel.min" , 
+      //                        GetParameterFloat( "minmax.manuel.max" ));
+      //     SetParameterFloat( "minmax.manuel.max" , temp );
+      //     }
+      //   else if ( GetParameterFloat( "minmax.manuel.min" ) == 
+      //             GetParameterFloat( "minmax.manuel.max" ) )
+      //     {
+      //     std::ostringstream oss;
+      //     oss<<"Warning minimum and maximum are equal."<<std::endl;
+      //     otbAppLogINFO( << oss.str() );
+      //     }
+      //   }
+      }
+
+    if ( GetParameterString("minmax") == "manuel" )
+      {
+      MandatoryOn("minmax.manuel.min");
+      MandatoryOn("minmax.manuel.max");
+      }
+    else if ( GetParameterString("minmax") == "auto" )
+      {
+      MandatoryOff("minmax.manuel.min");
+      MandatoryOff("minmax.manuel.max");
+      }
+  }
+
+  void DoExecute() override
+  {
+    m_MinMaxMode = GetParameterString("minmax");
+    m_EqMode = GetParameterString("mode");
+    m_SpatialMode = GetParameterString("spatial");
+    FloatVectorImageType * inImage = GetParameterImage("in");
+    WarningGlobalOrNot( inImage );
+    WarningMinMax();
+    LogInfo();
+    ImageListType::Pointer outputImageList ( ImageListType::New() ); 
+    m_VectorToImageListFilter = VectorToImageListFilterType::New() ;
+    m_VectorToImageListFilter->SetInput( inImage );
+    m_VectorToImageListFilter->UpdateOutputInformation();
+    ImageListType::Pointer inputImageList = 
+                  m_VectorToImageListFilter->GetOutput();
+    unsigned int nbChannel = inImage->GetVectorLength ();
+
+    if ( m_EqMode == "each")
+      {
+      // Each channel will be equalized
+      m_GainLutFilter.resize(nbChannel);
+      m_ApplyFilter.resize(nbChannel);
+      m_BufferFilter.resize(nbChannel);
+      m_StreamingFilter.resize(nbChannel);
+      PerBandEqualization( inImage , inputImageList , 
+                           nbChannel , outputImageList );
+      }
+    else if ( m_EqMode == "lum")
+      {
+      std::vector< unsigned int > rgb( 3 , 0 );
+      rgb[0] = GetParameterInt("mode.lum.red.ch");
+      rgb[1] = GetParameterInt("mode.lum.green.ch");
+      rgb[2] = GetParameterInt("mode.lum.blue.ch");
+      if ( !( nbChannel > std::max( rgb[0] , std::max( rgb[1] , rgb[2] ) ) ) )
+        {
+        std::ostringstream oss;
+        oss<<"One of the selected channel needed for luminance computation "
+        "exceed the number of component of the image.";
+        otbAppLogFATAL( << oss.str() )
+        }
+      ComputeLuminance( inImage , rgb );
+      LuminanceEqualization( inputImageList , rgb , outputImageList );
+      }
+
+    m_ImageListToVectorFilterOut = ImageListToVectorFilterType::New() ;
+    m_ImageListToVectorFilterOut->SetInput(outputImageList);
+    SetParameterOutputImage( "out" , 
+        m_ImageListToVectorFilterOut->GetOutput() );
+  }
+
+  // Look for default values in the image metadata
+  void SetDefaultValue( const FloatVectorImageType * inImage ,
+                        std::string what)
+  {
+    typedef ImageMetadataInterfaceBase ImageMetadataInterfaceType;
+    ImageMetadataInterfaceType::Pointer metadataInterface = 
+          ImageMetadataInterfaceFactory
+                ::CreateIMI(inImage->GetMetaDataDictionary());
+    if ( what == "NODATA" )
+      {
+      std::vector<double> values;
+      std::vector<bool> flags;
+
+      bool ret = metadataInterface->GetNoDataFlags(flags,values);
+
+      if(ret && !values.empty() && !flags.empty() && flags[0])
+        {
+        SetParameterFloat( "nodata" , static_cast<float>( values[0] ) );
+        }
+      else
+        {
+        SetParameterFloat( "nodata" , 0 );
+        }
+      }
+    else if ( what == "RGB" )
+      {
+      std::vector<unsigned int> rgb = 
+                    metadataInterface->GetDefaultDisplay() ;
+      unsigned int m = inImage->GetVectorLength ();
+      SetParameterInt( "mode.lum.red.ch" , rgb[0] );
+      SetParameterInt( "mode.lum.green.ch" , rgb[1] );
+      SetParameterInt( "mode.lum.blue.ch" , rgb[2] );
+      if( m < rgb[ 0 ] )
+        {
+        SetParameterFloat ("mode.lum.red.coef" , 0.0 );
+        SetParameterInt( "mode.lum.red.ch" , 0 );
+        }
+      if( m < rgb[ 1 ] )
+        {
+        SetParameterFloat ("mode.lum.green.coef" , 0.0 );
+        SetParameterInt( "mode.lum.gre.ch" , 0 );
+        }
+      if( m < rgb[ 2 ] )
+        {
+        SetParameterFloat ("mode.lum.blue.coef" , 0.0 );
+        SetParameterInt( "mode.lum.blue.ch" , 0 );
+        }
+      }
+  }
+
+  // Log info for the user
+  void LogInfo()
+  {
+    std::ostringstream oss;
+    oss << "The application has been launched with the following parameters :"
+    <<std::endl;
+    oss << "- number of bins : " << GetParameterInt("bins") << std::endl;
+    if ( HasValue("hfact") )
+      {
+      oss << "- contrast limtaition factor : "
+      << GetParameterFloat("hfact") << std::endl;
+      }
+    else
+      {
+      oss << "- no contrast limitation factor" << std::endl;
+      }
+    oss << "- spatial parameters : " << m_SpatialMode ;
+    if ( m_SpatialMode == "local" )
+      {
+      oss<< " with a thumbnail of " << m_ThumbSize[0] <<" X "<< m_ThumbSize[1] ;
+      }
+    oss << std::endl << "- equalisation of ";
+    if ( m_EqMode == "each" )
+      {
+      oss << "each channel";
+      }
+    else
+      {
+      oss << "the luminance";
+      }
+    oss << std::endl << "- Min/Max parameters : ";
+    if ( m_MinMaxMode == "auto" )
+      {
+      oss << "automatic";
+      if ( IsParameterEnabled( "minmax.auto.global" ) )
+        { 
+        oss << " and global";
+        }
+      }
+    else 
+      {
+      oss << GetParameterFloat("minmax.manuel.min") << "/" << 
+        GetParameterFloat("minmax.manuel.max");
+      }
+
+    otbAppLogINFO( << oss.str() );
+  }
+
+  // Force global computation if the thumbsize is equal to the largest region
+  void WarningGlobalOrNot( FloatVectorImageType * input)
+  {
+    auto size = input->GetLargestPossibleRegion().GetSize();
+    if ( m_SpatialMode == "global" )
+      {
+      m_ThumbSize[0] = size[0];
+      m_ThumbSize[1] = size[1];
+      }  
+    else 
+      {
+      m_ThumbSize[0] = GetParameterInt("spatial.local.w");
+      m_ThumbSize[1] = GetParameterInt("spatial.local.h");
+      if ( size[0] == m_ThumbSize[0] && size[1] == m_ThumbSize[1] )
+        {
+        std::ostringstream oss;
+        oss<<"Warning you choose to compute the histogram with a local "
+        "method whereas you have selected the whole image for the thumbnail "
+        "size. In order to use less memory consider using the global option for "
+        "histogram computation.";
+        otbAppLogWARNING( << oss.str() );
+        }
+      }
+  }
+
+  // Check for min max validity 
+  void WarningMinMax()
+  {
+    if ( m_MinMaxMode == "manuel" &&  
+         GetParameterFloat( "minmax.manuel.min" ) > 
+         GetParameterFloat( "minmax.manuel.max" ) )
+      {
+      std::ostringstream oss;
+      oss<<"The minimum (" << GetParameterFloat( "minmax.manuel.min" ) <<
+      ") is superior to the maximum (" 
+      << GetParameterFloat( "minmax.manuel.max" )
+      << ") please correct this error or allow the application to compute "
+      "those parameters";
+      otbAppLogFATAL( << oss.str() )
+      }
+  }
+
+  // Check if the image size is a multiple of the thumbnail size
+  void CheckValidity()
+  {
+    std::ostringstream oss;
+    long nbPixel = GetParameterInt("spatial.local.w") * 
+                   GetParameterInt("spatial.local.h");
+    if ( nbPixel < 10 * GetParameterInt("bins"))
+      {   
+      oss<<"Warning in parameters selection the thumbnail size is small "
+      "in comparison with the number of bin. Histogram may not have much sens. "
+      "For better result enlarge thumbnail size or reduce number of bin.";
+      otbAppLogINFO( << oss.str() );
+      }
+  }
+
+  // Compute min max from a vector image
+  void ComputeVectorMinMax( const FloatVectorImageType::Pointer inImage ,
+                            FloatVectorImageType::PixelType & max ,
+                            FloatVectorImageType::PixelType & min )
+  {
+    if ( m_MinMaxMode == "manuel" )
+      {
+      min.Fill( GetParameterFloat("minmax.manuel.min") );
+      max.Fill( GetParameterFloat("minmax.manuel.max") );
+      }
+    else
+      {
+      VectorStatsFilterType::Pointer 
+                statFilter ( VectorStatsFilterType::New() );
+      statFilter->SetIgnoreInfiniteValues(true);
+      if( IsParameterEnabled("nodata") )
+        {
+        statFilter->SetIgnoreUserDefinedValue(true);
+        statFilter->SetUserIgnoredValue( GetParameterFloat("nodata") );
+        }
+      statFilter->SetInput( inImage );
+      AddProcess(statFilter->GetStreamer(), "Computing statistics");
+      statFilter->Update();
+      min = statFilter->GetMinimum();
+      max = statFilter->GetMaximum();
+      if ( IsParameterEnabled("minmax.auto.global") )
+        {
+        float temp(min[0]);
+        for ( unsigned int i = 1 ; i < min.GetSize() ; i++ )
+          {
+          temp = std::min(temp , min[i]);
+          }
+        min.Fill(temp);
+        temp = max[0];
+        for ( unsigned int i = 1 ; i < max.GetSize() ; i++ )
+          {
+          temp = std::max(temp , max[i]);
+          }
+        max.Fill(temp);
+        }
+      }
+    std::ostringstream oss;
+    oss<<"Minimum and maximum are for each channel : ";
+    if ( IsParameterEnabled("minmax.auto.global") || 
+          m_MinMaxMode == "manuel" )
+      {
+      oss<<std::endl<<min[0]<<" and "<<max[0];
+      }
+    else 
+      {
+      for ( unsigned int i = 0 ; i < min.GetSize() ; i++ )
+        {
+          oss<<std::endl<<min[i]<<" and "<<max[i];
+        }
+      }
+    otbAppLogINFO( << oss.str() );
+  }
+
+  // Prepare the first half of the pipe that is common to every methode of 
+  // equalization
+  void SetUpPipeline( unsigned int channel ,
+                      const FloatImageType::Pointer input )
+  {
+    m_GainLutFilter[channel] = GainLutFilterType::New();
+    m_ApplyFilter[channel] = ApplyFilterType::New();
+    m_StreamingFilter[channel] = StreamingImageFilterType::New();
+    m_BufferFilter[channel] = BufferFilterType::New();
+    m_BufferFilter[channel]->SetInput( input );
+    m_GainLutFilter[channel]->SetInput ( m_Histogram[channel] );
+    m_StreamingFilter[channel]->SetInput( 
+      m_GainLutFilter[channel]->GetOutput() );
+    m_ApplyFilter[channel]->SetInputImage ( 
+      m_BufferFilter[channel]->GetOutput() );
+    m_ApplyFilter[channel]->SetInputLut( 
+      m_StreamingFilter[channel]->GetOutput() );
+  }
+
+  // Function corresponding to the "each" mode
+  void PerBandEqualization( const FloatVectorImageType::Pointer inImage ,
+                            const ImageListType::Pointer inputImageList ,
+                            const unsigned int nbChannel,
+                            ImageListType::Pointer outputImageList )
+  {
+    FloatVectorImageType::PixelType min(nbChannel) , max(nbChannel);
+    min.Fill(0);
+    max.Fill(0);
+    ComputeVectorMinMax( inImage , max , min );
+
+    if ( m_SpatialMode == "global" )
+      PersistentComputation( inImage , nbChannel , max , min );
+    else
+      {
+      float thresh (-1);
+      if ( HasValue("hfact") )
+        {
+        thresh = GetParameterInt("hfact");
+        }
+
+      m_HistoFilter.resize(nbChannel);
+      m_Histogram.resize(nbChannel);
+      for (unsigned int channel = 0 ; channel < nbChannel ; channel++)
+        {
+        m_HistoFilter[channel] = HistoFilterType::New();
+        m_HistoFilter[channel]->SetInput( 
+            inputImageList->GetNthElement(channel) );
+        SetHistoFilterParameter( m_HistoFilter[channel] ,
+                                 min[channel] ,
+                                 max[channel] ,
+                                 GetParameterInt("bins") ,
+                                 thresh );
+        m_Histogram[channel] = m_HistoFilter[channel]->GetHistoOutput();
+        }
+      }
+
+    for ( unsigned int channel = 0 ; channel < nbChannel ; channel++ ) 
+      {
+      SetUpPipeline( channel , inputImageList->GetNthElement(channel) );
+
+      if ( min[channel] == max[channel] )
+        {
+          std::ostringstream oss;
+          oss<< "Channel " <<channel << " is constant : " << "min = " <<
+          min[channel] << " and max = " << max[channel] ;
+          otbAppLogINFO( << oss.str() );
+          m_BufferFilter[channel]->SetInput( 
+                inputImageList->GetNthElement(channel) );
+          outputImageList->PushBack( m_BufferFilter[channel]->GetOutput() );
+          continue;
+        }
+
+      SetGainLutFilterParameter( m_GainLutFilter[channel] ,
+                                 min[channel] ,
+                                 max[channel]);
+      SetApplyFilterParameter( m_ApplyFilter[channel] ,
+                               min[channel] ,
+                               max[channel]);
+
+      outputImageList->PushBack( m_ApplyFilter[channel]->GetOutput() );
+      }
+  }
+
+  // Compute the luminance with user parameters
+  void ComputeLuminance( const FloatVectorImageType::Pointer inImage ,
+                         std::vector < unsigned int > rgb )
+  {
+    // Retrieve coeffs for each channel
+    std::vector < float > lumCoef( 3 , 0.0 );
+    lumCoef[0] = GetParameterFloat("mode.lum.red.coef");
+    lumCoef[1] = GetParameterFloat("mode.lum.green.coef");
+    lumCoef[2] = GetParameterFloat("mode.lum.blue.coef");
+    // Normalize those coeffs
+    float sum = std::accumulate( lumCoef.begin() , lumCoef.end() , 0.0 );
+    assert(sum>0);
+    for (int i = 0 ; i<3 ; i++ )
+      {
+      lumCoef[i] /= sum;
+      }
+    m_LuminanceFunctor =  LuminanceFunctorType::New() ;
+    m_LuminanceFunctor->GetFunctor().SetRgb( rgb );
+    m_LuminanceFunctor->GetFunctor().SetLumCoef( lumCoef );
+    m_LuminanceFunctor->SetInput( inImage );
+    m_LuminanceFunctor->UpdateOutputInformation();
+  }
+
+  // Equalize the luminance and apply the corresponding gain on each channel
+  // used to compute this luminance
+  void LuminanceEqualization( const ImageListType::Pointer inputImageList ,
+                              const std::vector < unsigned int > rgb ,
+                              ImageListType::Pointer outputImageList )
+  {
+    m_GainLutFilter.resize( 1 , GainLutFilterType::New() );
+    m_HistoFilter.resize( 1 , HistoFilterType::New() );
+    m_StreamingFilter.resize( 1 , StreamingImageFilterType::New() );
+    m_ApplyFilter.resize(3);
+    m_BufferFilter.resize(3);
+    FloatVectorImageType::PixelType min(1) , max(1);
+    ComputeVectorMinMax( m_LuminanceFunctor->GetOutput() , max , min );
+
+    if ( m_SpatialMode == "global" )
+      PersistentComputation( m_LuminanceFunctor->GetOutput() , 1 , max , min );
+    else
+      {
+        float thresh (-1);
+        if ( HasValue("hfact") )
+          {
+          thresh = GetParameterInt("hfact");
+          }
+        m_Histogram.resize(1);
+        m_HistoFilter[0] = HistoFilterType::New();
+        m_LuminanceToImageListFilter = VectorToImageListFilterType::New();
+        m_LuminanceToImageListFilter->SetInput( 
+          m_LuminanceFunctor->GetOutput() );
+        SetHistoFilterParameter( m_HistoFilter[0] ,
+                                 min[0] ,
+                                 max[0] ,
+                                 GetParameterInt("bins") ,
+                                 thresh ); 
+        m_LuminanceToImageListFilter->UpdateOutputInformation();
+        m_HistoFilter[0]->SetInput( 
+          m_LuminanceToImageListFilter->GetOutput()->GetNthElement(0) ) ;
+        m_Histogram[0] = m_HistoFilter[0]->GetHistoOutput();
+      }
+
+    m_GainLutFilter[0]->SetInput ( m_Histogram[0] );
+    m_StreamingFilter[0]->SetInput( m_GainLutFilter[0]->GetOutput() );
+
+    SetGainLutFilterParameter( m_GainLutFilter[0] ,
+                               min[0] ,
+                               max[0] );
+
+    for ( int channel = 0 ; channel < 3 ; channel++ ) 
+      {
+
+      m_BufferFilter[channel] = BufferFilterType::New();
+      m_ApplyFilter[channel] = ApplyFilterType::New();
+      SetApplyFilterParameter( m_ApplyFilter[channel] ,
+                               min[0] ,
+                               max[0] );
+
+      m_BufferFilter[channel]->SetInput( 
+          inputImageList->GetNthElement( rgb[channel] ) );
+      m_ApplyFilter[channel]->SetInputImage ( 
+          m_BufferFilter[channel]->GetOutput() );
+      m_ApplyFilter[channel]->SetInputLut( 
+          m_StreamingFilter[0]->GetOutput() );
+      
+
+      outputImageList->PushBack( m_ApplyFilter[channel]->GetOutput() );
+    }
+  }
+
+  // Function that compute histograms with HistoPersistentFilterType
+  void PersistentComputation( const FloatVectorImageType::Pointer inImage ,
+                              const unsigned int nbChannel ,
+                              const FloatVectorImageType::PixelType & max ,
+                              const FloatVectorImageType::PixelType & min)
+  { 
+
+    HistoPersistentFilterType::Pointer histoPersistent (
+        HistoPersistentFilterType::New());
+    unsigned int nbBin ( GetParameterInt( "bins" ) );
+    histoPersistent->SetInput( inImage );
+    FloatVectorImageType::PixelType pixel( nbChannel ) , step( nbChannel );
+    pixel.Fill( nbBin );
+    histoPersistent->GetFilter()->SetNumberOfBins( pixel );
+    if ( IsParameterEnabled("nodata") )
+      {
+      histoPersistent->GetFilter()->NoDataFlagOn();
+      histoPersistent->GetFilter()->SetNoDataValue( 
+                GetParameterFloat( "nodata" ) );
+      }
+    step = ( max - min ) / nbBin;
+    pixel = min - 0.5 * step;
+    histoPersistent->GetFilter()->SetHistogramMin(pixel);
+    pixel = max + 0.5 * step;
+    histoPersistent->GetFilter()->SetHistogramMax(pixel);
+    AddProcess(histoPersistent->GetStreamer(), "Computing histogram");
+    histoPersistent->Update();
+    HistoPersistentFilterType::HistogramListType * histoList = 
+            histoPersistent->GetHistogramList();
+
+    Transfer( histoList );
+
+    if ( HasValue("hfact") )
+      {
+      Threshold( histoList , nbBin );
+      }
+  }
+
+  // Threshold function that is normally done in ComputeHistoFilter  and here is
+  // used on the output of HistoPersistentFilterType.
+  void Threshold( HistoPersistentFilterType::HistogramListType * histoList ,
+                  unsigned int nbBin )
+  {
+    for ( unsigned int j = 0 ; j < histoList->Size() ; j++ )
+      {
+      unsigned int rest(0) , height ( static_cast<unsigned int>( 
+          GetParameterFloat( "hfact" ) * 
+          ( histoList->GetNthElement(j)->GetTotalFrequency() / nbBin ) ) );
+
+      HistogramType::IndexType zero;
+      HistogramType::Pointer & histoToThresh = m_Histogram[j];
+      zero.Fill(0);
+      for ( unsigned int i = 0 ; i < nbBin ; i++ )
+        {
+        if ( histoToThresh->GetPixel(zero)[i] > height )
+          {
+          rest += histoToThresh->GetPixel(zero)[i] - height ;
+          histoToThresh->GetPixel(zero)[i] = height ;
+          }
+        }
+      height = rest / nbBin;
+      rest = rest % nbBin;
+      for ( unsigned int i = 0 ; i < nbBin ; i++ )
+        {
+        histoToThresh->GetPixel(zero)[i] += height ;
+        if ( i > (nbBin - rest)/2 && i <= (nbBin - rest)/2 + rest )
+          {
+          ++histoToThresh->GetPixel(zero)[i];
+          }
+        }
+      }
+  }
+
+  // Transfer the output of the HistoPersistentFilterType to the input type
+  // of ComputeGainLutFilter
+  void Transfer( HistoPersistentFilterType::HistogramListType * histoList )
+  {
+    unsigned int nbBin( GetParameterInt( "bins" ) );
+
+    HistoPersistentFilterType::HistogramType::Pointer histo;
+    FloatImageType::SpacingType inputSpacing ( 
+      GetParameterImage("in")->GetSignedSpacing() );
+    FloatImageType::PointType inputOrigin ( 
+      GetParameterImage("in")->GetOrigin() );
+
+    HistogramType::SpacingType histoSpacing ;
+    histoSpacing[0] = inputSpacing[0] * m_ThumbSize[0] ;
+    histoSpacing[1] = inputSpacing[1] * m_ThumbSize[1] ;
+    HistogramType::PointType histoOrigin ;
+    histoOrigin[0] = histoSpacing[0] / 2 + 
+      inputOrigin[0] - inputSpacing[0] / 2 ;
+    histoOrigin[1] = histoSpacing[1] / 2 + 
+      inputOrigin[1] - inputSpacing[1] / 2 ;
+
+    for ( unsigned int i = 0 ; i < histoList->Size() ; i++ )
+      {
+      HistogramType::Pointer histoVectorImage =
+        CreateHistogramFrom( histoList->GetNthElement( i ) ,
+                             nbBin ,
+                             histoSpacing ,
+                             histoOrigin );
+     
+      m_Histogram.push_back( histoVectorImage );
+      }
+  }
+
+  // Creating a histogram (VectorImage) from an itkHistogram
+  HistogramType::Pointer CreateHistogramFrom( 
+      HistoPersistentFilterType::HistogramType::Pointer histo ,
+      unsigned int nbBin ,
+      HistogramType::SpacingType histoSpacing ,
+      HistogramType::PointType histoOrigin )
+  {
+    HistogramType::SizeType sizeOne;
+    sizeOne.Fill( 1 );
+    HistogramType::IndexType index;
+    index.Fill(0);
+
+    HistogramType::PixelType histoPixel( nbBin );
+
+    HistogramType::Pointer histoVectorImage ( 
+            HistogramType::New() );
+
+    histoVectorImage->SetVectorLength( nbBin );
+    histoVectorImage->SetBufferedRegion( sizeOne );
+    histoVectorImage->SetRequestedRegion( sizeOne );
+    histoVectorImage->SetLargestPossibleRegion( sizeOne );
+    histoVectorImage->SetSignedSpacing( histoSpacing ) ;
+    histoVectorImage->SetOrigin( histoOrigin );
+    histoVectorImage->Allocate();
+    for (unsigned int j = 0 ; j < nbBin ; j++ )
+      {
+      histoPixel[j] = histo->GetFrequency( j );
+      }
+    histoVectorImage->SetPixel( index , histoPixel );
+    return histoVectorImage;
+  }
+
+  // Set correct parameters for the ComputeHistoFilter
+  void SetHistoFilterParameter( HistoFilterType::Pointer histoFilter ,
+                                float min ,
+                                float max ,
+                                unsigned int nbBin ,
+                                float thresh = -1 )
+  {
+    histoFilter->SetMin( min );
+    histoFilter->SetMax( max );
+    histoFilter->SetNbBin( nbBin );
+    histoFilter->SetThumbSize( m_ThumbSize );
+    histoFilter->SetThreshold( thresh );
+    if ( IsParameterEnabled("nodata") )
+      {
+      histoFilter->SetNoData( GetParameterFloat( "nodata" ) );
+      histoFilter->SetNoDataFlag( true );
+      }
+  }
+
+  // Set correct parameters for the ComputeGainLutFilter
+  void SetGainLutFilterParameter( GainLutFilterType::Pointer gainLutFilter ,
+                                  ImagePixelType min ,
+                                  ImagePixelType max )
+  {
+    gainLutFilter->SetMin( min );
+    gainLutFilter->SetMax( max );
+    gainLutFilter->SetNbPixel( m_ThumbSize[0]*m_ThumbSize[1] );
+  }
+
+  // Set correct parameters for the ApplyGainFilter
+  void SetApplyFilterParameter( ApplyFilterType::Pointer applyFilter ,
+                                ImagePixelType min ,
+                                ImagePixelType max )
+  {
+    applyFilter->SetMin( min );
+    applyFilter->SetMax( max );
+    applyFilter->SetThumbSize( m_ThumbSize );
+    if ( IsParameterEnabled("nodata") )
+      {
+      applyFilter->SetNoData( GetParameterFloat( "nodata" ) );
+      applyFilter->SetNoDataFlag( true );
+      }
+  }
+
+  std::string m_SpatialMode , m_MinMaxMode , m_EqMode ;
+  FloatImageType::SizeType m_ThumbSize;
+  ImageListToVectorFilterType::Pointer m_ImageListToVectorFilterOut;
+  LuminanceFunctorType::Pointer m_LuminanceFunctor;
+  VectorToImageListFilterType::Pointer m_LuminanceToImageListFilter;
+  VectorToImageListFilterType::Pointer m_VectorToImageListFilter;
+  std::vector < GainLutFilterType::Pointer > m_GainLutFilter;
+  std::vector < HistoFilterType::Pointer > m_HistoFilter;
+  std::vector < HistogramType::Pointer > m_Histogram;
+  std::vector < ApplyFilterType::Pointer > m_ApplyFilter;
+  std::vector < StreamingImageFilterType::Pointer > m_StreamingFilter;
+  std::vector < BufferFilterType::Pointer > m_BufferFilter;
+
+};
+
+
+
+} //End namespace Wrapper
+} //End namespace otb
+
+OTB_APPLICATION_EXPORT(otb::Wrapper::ContrastEnhancement)
diff --git a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
index e80df1e..a31dc93 100644
--- a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
+++ b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
@@ -57,70 +57,81 @@ public:
 private:
   void DoInit() ITK_OVERRIDE
   {
-    SetName("Smoothing");
-    SetDescription("Apply a smoothing filter to an image");
-
-    SetDocName("Smoothing");
-    SetDocLongDescription("This application applies smoothing filter to an image."
-      " Either gaussian, mean, or anisotropic diffusion are available.");
-    SetDocLimitations("None");
-    SetDocAuthors("OTB-Team");
+    SetName( "Smoothing" );
+    SetDescription( "Apply a smoothing filter to an image" );
+
+    SetDocName( "Smoothing" );
+    SetDocLongDescription( "This application applies a smoothing filter to an "
+      "image. Three methodes can be used : a gaussian filter , a mean filter "
+      ", or an anisotropic diffusion using the Perona-Malik algorithm." );
+    SetDocLimitations( "None") ;
+    SetDocAuthors( "OTB-Team" );
     SetDocSeeAlso(" ");
 
     AddDocTag(Tags::Filter);
 
-    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
-    SetParameterDescription("in", "Input image to smooth.");
-    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
-    SetParameterDescription("out", "Output smoothed image.");
+    AddParameter( ParameterType_InputImage ,  "in" , "Input Image" );
+    SetParameterDescription( "in", "Input image to smooth." );
+    AddParameter( ParameterType_OutputImage , "out" , "Output Image" );
+    SetParameterDescription( "out" , "Output smoothed image." );
 
     AddRAMParameter();
 
-    AddParameter(ParameterType_Choice,      "type", "Smoothing Type");
-    SetParameterDescription("type", "Smoothing kernel to apply");
+    AddParameter( ParameterType_Choice, "type" , "Smoothing Type" );
+    SetParameterDescription( "type", "Smoothing kernel to apply" );
 
-    AddChoice("type.mean",     "Mean");
+    AddChoice( "type.mean" , "Mean" );
 
-    AddParameter(ParameterType_Radius, "type.mean.radius", "Radius");
-    SetParameterDescription("type.mean.radius", "Mean radius (in pixels)");
-    SetDefaultParameterInt("type.mean.radius", 2);
+    AddParameter( ParameterType_Radius , "type.mean.radius" , "Radius" );
+    SetParameterDescription( "type.mean.radius" , 
+      "Kernel's radius (in pixels)" );
+    SetDefaultParameterInt( "type.mean.radius" , 2 );
 
-    AddChoice("type.gaussian", "Gaussian");
+    AddChoice( "type.gaussian" , "Gaussian" );
 
-    AddParameter(ParameterType_Float, "type.gaussian.radius", "Radius");
-    SetParameterDescription("type.gaussian.radius", "Gaussian radius (in pixels)");
-    SetDefaultParameterFloat("type.gaussian.radius", 2.0);
+    AddParameter( ParameterType_Float, "type.gaussian.radius" , "Radius" );
+    SetParameterDescription( "type.gaussian.radius", 
+      "Standard deviation of the gaussian kernel used to filter the image");
+    SetDefaultParameterFloat( "type.gaussian.radius" , 2.0 );
+    // TODO rename this parameter
 
-    AddChoice("type.anidif",   "Anisotropic Diffusion");
+    AddChoice( "type.anidif" , "Anisotropic Diffusion" );
 
-    AddParameter(ParameterType_Float,  "type.anidif.timestep", "Time Step");
-    SetParameterDescription("type.anidif.timestep", "Diffusion equation time step");
 
-    AddParameter(ParameterType_Int,  "type.anidif.nbiter", "Nb Iterations");
-    SetParameterDescription("type.anidif.nbiter", "Number of iterations");
+    AddParameter( ParameterType_Float , "type.anidif.timestep",  "Time Step" );
+    SetParameterDescription( "type.anidif.timestep" , 
+      "Time step that will be used to discretize the diffusion equation" );
 
-    AddParameter(ParameterType_Float,  "type.anidif.conductance", "Conductance");
-    SetParameterDescription("type.anidif.nbiter", "Controls the sensitivity of the conductance term");
+    AddParameter( ParameterType_Int , "type.anidif.nbiter" , "Nb Iterations" );
+    SetParameterDescription( "type.anidif.nbiter" , 
+      "Number of iterations needed to get the result" );
 
-    SetDefaultParameterFloat("type.anidif.timestep",   0.125);
-    SetDefaultParameterInt("type.anidif.nbiter",     10);
-    SetDefaultParameterInt("type.anidif.conductance",     1.);
+    AddParameter( ParameterType_Float , "type.anidif.conductance" , 
+      "Conductance" );
+    SetParameterDescription( "type.anidif.conductance" , 
+      "Controls the sensitivity of the conductance term in the diffusion "
+      "equation. The lower it is the stronger the features will be preserved" );
 
-    SetParameterString("type", "anidif", false);
+    SetDefaultParameterFloat( "type.anidif.timestep" , 0.125 );
+    SetDefaultParameterInt( "type.anidif.nbiter" , 10 );
+    SetDefaultParameterInt( "type.anidif.conductance" , 1. );
+
+    SetParameterString( "type" , "anidif" , false );
 
     // Doc example parameter settings
-    SetExampleComment("Image smoothing using a mean filter.", 0);
-    SetDocExampleParameterValue("in", "Romania_Extract.tif");
-    SetDocExampleParameterValue("out", "smoothedImage_mean.png uchar");
-    SetDocExampleParameterValue("type", "mean");
-
-    unsigned int exId = AddExample( "Image smoothing using an anisotropic diffusion filter." );
-    SetDocExampleParameterValue("in", "Romania_Extract.tif", exId);
-    SetDocExampleParameterValue("out", "smoothedImage_ani.png float", exId);
-    SetDocExampleParameterValue("type", "anidif", exId);
-    SetDocExampleParameterValue("type.anidif.timestep", "0.1", exId);
-    SetDocExampleParameterValue("type.anidif.nbiter", "5", exId);
-    SetDocExampleParameterValue("type.anidif.conductance", "1.5", exId);
+    SetExampleComment( "Image smoothing using a mean filter." , 0 );
+    SetDocExampleParameterValue( "in" , "Romania_Extract.tif" );
+    SetDocExampleParameterValue( "out" , "smoothedImage_mean.png uchar" );
+    SetDocExampleParameterValue( "type" , "mean");
+
+    unsigned int exId = AddExample( "Image smoothing using an anisotropic "
+      "diffusion filter." );
+    SetDocExampleParameterValue( "in" , "Romania_Extract.tif" , exId );
+    SetDocExampleParameterValue( "out" , "smoothedImage_ani.png float" , exId );
+    SetDocExampleParameterValue( "type" , "anidif" , exId );
+    SetDocExampleParameterValue( "type.anidif.timestep" , "0.1" , exId );
+    SetDocExampleParameterValue( "type.anidif.nbiter" , "5" , exId );
+    SetDocExampleParameterValue( "type.anidif.conductance" , "1.5" , exId );
 
     SetOfficialDocLink();
   }
diff --git a/Modules/Applications/AppFiltering/otb-module.cmake b/Modules/Applications/AppFiltering/otb-module.cmake
index 5e8fc45..e5c8187 100644
--- a/Modules/Applications/AppFiltering/otb-module.cmake
+++ b/Modules/Applications/AppFiltering/otb-module.cmake
@@ -26,6 +26,9 @@ otb_module(OTBAppFiltering
     OTBITK
     OTBApplicationEngine
     OTBImageBase
+    OTBContrast
+    OTBStatistics
+    OTBStreaming
 
   TEST_DEPENDS
     OTBTestKernel
diff --git a/Modules/Applications/AppFiltering/test/CMakeLists.txt b/Modules/Applications/AppFiltering/test/CMakeLists.txt
index 9c4a802..f8195d2 100644
--- a/Modules/Applications/AppFiltering/test/CMakeLists.txt
+++ b/Modules/Applications/AppFiltering/test/CMakeLists.txt
@@ -48,6 +48,61 @@ otb_test_application(NAME  apTvUtSmoothingTest_OutXML
                      VALID   --compare-image ${NOTOL}
                              ${BASELINE}/apTvUtSmoothingTest.tif
                              ${TEMP}/apTvUtSmoothingTest_OutXML.tif)
+
+#----------- Contrast TESTS ----------------
+
+otb_test_application(NAME  apTvUtContrastTest_base
+                     APP  ContrastEnhancement
+                     OPTIONS -in ${INPUTDATA}/QB_Suburb.png
+                             -out ${TEMP}/apTvUtContrastTest_base.tif int16
+                             -bins 256
+                             -spatial.local.h 51
+                             -spatial.local.w 67
+                     VALID   --compare-image ${NOTOL}
+                             ${BASELINE}/apTvUtContrastTest_base.tif
+                             ${TEMP}/apTvUtContrastTest_base.tif)
+
+otb_test_application(NAME  apTvUtContrastTest_base_glob
+                     APP  ContrastEnhancement
+                     OPTIONS -in ${INPUTDATA}/QB_Suburb.png
+                             -out ${TEMP}/apTvUtContrastTest_base_glob.tif int16
+                             -bins 256
+                             -spatial global
+                             -minmax manuel
+                             -minmax.manuel.min 0 
+                             -minmax.manuel.max 255
+                     VALID   --compare-image ${NOTOL}
+                             ${BASELINE}/apTvUtContrastTest_base_glob.tif
+                             ${TEMP}/apTvUtContrastTest_base_glob.tif)
+
+otb_test_application(NAME  apTvUtContrastTest_lum_glob
+                     APP  ContrastEnhancement
+                     OPTIONS -in ${INPUTDATA}/anaglyphInput1.tif
+                             -out ${TEMP}/apTvUtContrastTest_lum_glob.tif int16
+                             -bins 256
+                             -spatial global
+                             -hfact 2.7
+                             -nodata 0
+                             -mode lum
+                     VALID   --compare-image ${NOTOL}
+                             ${BASELINE}/apTvUtContrastTest_lum_glob.tif
+                             ${TEMP}/apTvUtContrastTest_lum_glob.tif)
+
+otb_test_application(NAME  apTvUtContrastTest_lum
+                     APP  ContrastEnhancement
+                     OPTIONS -in ${INPUTDATA}/anaglyphInput1.tif
+                             -out ${TEMP}/apTvUtContrastTest_lum.tif int16
+                             -bins 256
+                             -spatial.local.h 33
+                             -spatial.local.w 47
+                             -hfact 2.1
+                             -nodata 0
+                             -mode lum
+                     VALID   --compare-image ${NOTOL}
+                             ${BASELINE}/apTvUtContrastTest_lum.tif
+                             ${TEMP}/apTvUtContrastTest_lum.tif)
+
+
                              
                              
 
diff --git a/Modules/Applications/AppFusion/app/CMakeLists.txt b/Modules/Applications/AppFusion/app/CMakeLists.txt
index 1e7a0eb..62a40fa 100644
--- a/Modules/Applications/AppFusion/app/CMakeLists.txt
+++ b/Modules/Applications/AppFusion/app/CMakeLists.txt
@@ -18,14 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppFusion_LINK_LIBS
-  ${OTBImageBase_LIBRARIES}
-  ${OTBInterpolation_LIBRARIES}
-  ${OTBPanSharpening_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-)
-
 otb_create_application(
   NAME           BundleToPerfectSensor
   SOURCES        otbBundleToPerfectSensor.cxx
diff --git a/Modules/Applications/AppHyperspectral/app/CMakeLists.txt b/Modules/Applications/AppHyperspectral/app/CMakeLists.txt
index 6256b8b..a8e5d48 100644
--- a/Modules/Applications/AppHyperspectral/app/CMakeLists.txt
+++ b/Modules/Applications/AppHyperspectral/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppHyperspectral_LINK_LIBS
-  ${OTBStatistics_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBEndmembersExtraction_LIBRARIES}
-  ${OTBUnmixing_LIBRARIES}
-)
-
 otb_create_application(
   NAME           HyperspectralUnmixing
   SOURCES        otbHyperspectralUnmixing.cxx
diff --git a/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx b/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx
index 4fe8762..c3b04df 100644
--- a/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx
+++ b/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx
@@ -50,16 +50,28 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("VertexComponentAnalysis");
-    SetDescription("Find endmembers in hyperspectral images with Vertex Component Analysis");
+    SetDescription("Given a set of mixed spectral vectors, estimate"
+    "reference substances also known as endmembers using the Vertex"
+    "Component Analysis algorithm.");
 
     // Documentation
     SetDocName("Vertex Component Analysis");
-    SetDocLongDescription("Applies the Vertex Component Analysis to an hyperspectral image to extract endmembers");
+    SetDocLongDescription("Apply the Vertex Component Analysis [1] to"
+    "an hyperspectral image to extract endmembers. Given a set of mixed"
+    "spectral vectors (multispectral or hyperspectral), the application"
+    "estimates the spectral signature of reference substances also known"
+    "as endmembers.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
-
-	AddDocTag("Miscellaneous");
+    SetDocSeeAlso("[1] J. M. P. Nascimento and J. M. B. Dias, Vertex"
+    "component analysis: a fast algorithm to unmix hyperspectral data,"
+    "in IEEE Transactions on Geoscience and Remote Sensing, vol. 43,"
+    "no. 4, pp. 898-910, April 2005.J. M. P. Nascimento and"
+    "J. M. B. Dias, Vertex component analysis: a fast algorithm to"
+    "unmix hyperspectral data, in IEEE Transactions on Geoscience and"
+    "Remote Sensing, vol. 43, no. 4, pp. 898-910, April 2005.");
+
+    AddDocTag("Miscellaneous");
     AddDocTag(Tags::Hyperspectral);
     AddDocTag(Tags::DimensionReduction);
 
@@ -67,12 +79,15 @@ private:
     SetParameterDescription("in","Input hyperspectral data cube");
 
     AddParameter(ParameterType_Int, "ne", "Number of endmembers");
-    SetParameterDescription("ne","The number of endmembers to extract from the data cube");
+    SetParameterDescription("ne","The number of endmembers to extract from the hyperspectral image.");
     SetParameterInt("ne",1, false);
     MandatoryOn("ne");
 
     AddParameter(ParameterType_OutputImage, "outendm", "Output Endmembers");
-    SetParameterDescription("outendm","The endmebers, stored in a one-line multi-spectral image, each pixel representing an endmember");
+    SetParameterDescription("outendm","Endmembers, stored in a"
+    "one-line multi-spectral image.Each pixel corresponds to one"
+    "endmembers and each band values corresponds to the spectral"
+    "signature of the corresponding endmember.");
     MandatoryOn("outendm");
 
     AddRANDParameter();
diff --git a/Modules/Applications/AppImageUtils/app/CMakeLists.txt b/Modules/Applications/AppImageUtils/app/CMakeLists.txt
index 369b82f..1a85812 100644
--- a/Modules/Applications/AppImageUtils/app/CMakeLists.txt
+++ b/Modules/Applications/AppImageUtils/app/CMakeLists.txt
@@ -18,24 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppImageUtils_LINK_LIBS
-  ${OTBStatistics_LIBRARIES}
-  ${OTBColorMap_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBTransform_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBStreaming_LIBRARIES}
-  ${OTBCarto_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBCurlAdapters_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBMathParser_LIBRARIES}
-  ${OTBCommon_LIBRARIES}
-  ${OTBInterpolation_LIBRARIES}
-  ${OTBOSSIMAdapters_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-)
-
 otb_create_application(
   NAME           DownloadSRTMTiles
   SOURCES        otbDownloadSRTMTiles.cxx
@@ -112,3 +94,8 @@ otb_create_application(
   NAME           ManageNoData
   SOURCES        otbManageNoData.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
+
+otb_create_application(
+  NAME           DynamicConvert
+  SOURCES        otbDynamicConvert.cxx
+  LINK_LIBRARIES ${${otb-module}_LIBRARIES})
diff --git a/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx b/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
index 5ebe69d..185872b 100644
--- a/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbConcatenateImages.cxx
@@ -61,10 +61,12 @@ private:
 
     // Documentation
     SetDocName("Images Concatenation");
-    SetDocLongDescription("This application performs images channels concatenation. It will walk the input image list (single or multi-channel) and generates a single multi-channel image. The channel order is the one of the list.");
+    SetDocLongDescription("This application performs images channels concatenation. "
+      "It reads the input image list (single or multi-channel) "
+      "and generates a single multi-channel image. The channel order is the same as the list.");
     SetDocLimitations("All input images must have the same size.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("Rescale application, Convert");
+    SetDocSeeAlso("Rescale application, Convert, SplitImage");
 
     AddDocTag(Tags::Manip);
     AddDocTag("Concatenation");
@@ -75,10 +77,10 @@ private:
     m_ImageList = ImageListType::New();
 
     AddParameter(ParameterType_InputImageList,  "il",   "Input images list");
-    SetParameterDescription("il", "The list of images to concatenate");
+    SetParameterDescription("il", "The list of images to concatenate, must have the same size.");
 
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
-    SetParameterDescription("out", "The concatenated output image");
+    SetParameterDescription("out", "The concatenated output image.");
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppImageUtils/app/otbConvert.cxx b/Modules/Applications/AppImageUtils/app/otbConvert.cxx
index 51ce7f3..621d48a 100644
--- a/Modules/Applications/AppImageUtils/app/otbConvert.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbConvert.cxx
@@ -18,6 +18,8 @@
  * limitations under the License.
  */
 
+#include <numeric>
+
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
@@ -105,6 +107,7 @@ private:
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("Rescale");
 
+    AddDocTag(Tags::Deprecated);
     AddDocTag(Tags::Manip);
     AddDocTag("Conversion");
     AddDocTag("Image Dynamic");
@@ -195,7 +198,7 @@ private:
     if ( HasValue("in") )
       {
       typedef otb::ImageMetadataInterfaceBase ImageMetadataInterfaceType;
-      ImageMetadataInterfaceType::Pointer metadataInterface = 
+      ImageMetadataInterfaceType::Pointer metadataInterface =
       ImageMetadataInterfaceFactory::CreateIMI(GetParameterImage("in")->GetMetaDataDictionary());
 
       int nbBand = GetParameterImage("in")->GetNumberOfComponentsPerPixel();
@@ -215,7 +218,7 @@ private:
         SetDefaultParameterInt("channels.rgb.blue", bandBlue);
         }
       }
-    
+
 
   }
 
diff --git a/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx b/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx
index 813fa5c..fa696a0 100644
--- a/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx
@@ -33,7 +33,7 @@ enum
   Mode_List
 };
 
-const std::string SRTMServerPath = "http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/";
+const std::string SRTMServerPath = "https://dds.cr.usgs.gov/srtm/version2_1/SRTM3/";
 
 const std::string HGTZIPExtension = ".hgt.zip";
 const std::string HGTExtension = ".hgt";
diff --git a/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
new file mode 100644
index 0000000..fa8b76c
--- /dev/null
+++ b/Modules/Applications/AppImageUtils/app/otbDynamicConvert.cxx
@@ -0,0 +1,534 @@
+/*
+ * 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 "otbWrapperApplication.h"
+#include "otbWrapperApplicationFactory.h"
+
+#include "otbVectorRescaleIntensityImageFilter.h"
+#include "otbUnaryImageFunctorWithVectorImageFilter.h"
+#include "otbStreamingShrinkImageFilter.h"
+#include "itkListSample.h"
+#include "otbListSampleToHistogramListGenerator.h"
+#include "itkImageRegionConstIterator.h"
+
+#include "otbImageListToVectorImageFilter.h"
+#include "otbMultiToMonoChannelExtractROI.h"
+#include "otbImageList.h"
+
+#include <numeric>
+
+namespace otb
+{
+namespace Wrapper
+{
+
+namespace Functor
+{
+  template< class TScalar >
+class ITK_EXPORT LogFunctor
+{
+public:
+  TScalar operator() (const TScalar& v) const
+  {
+    return std::log(v);
+  }
+};
+} // end namespace Functor
+
+
+
+class DynamicConvert : public Application
+{
+public:
+  /** Standard class typedefs. */
+  typedef DynamicConvert                Self;
+  typedef Application                   Superclass;
+  typedef itk::SmartPointer<Self>       Pointer;
+  typedef itk::SmartPointer<const Self> ConstPointer;
+
+  /** Standard macro */
+  itkNewMacro(Self);
+
+  itkTypeMacro(DynamicConvert, otb::Application);
+
+  /** Filters typedef */
+  typedef itk::Statistics::ListSample<FloatVectorImageType::PixelType> ListSampleType;
+  typedef itk::Statistics::DenseFrequencyContainer2 DFContainerType;
+  typedef ListSampleToHistogramListGenerator<ListSampleType,
+    FloatVectorImageType::InternalPixelType,
+    DFContainerType> HistogramsGeneratorType;
+    
+  typedef StreamingShrinkImageFilter<FloatVectorImageType,
+    FloatVectorImageType> ShrinkFilterType;
+
+  typedef Functor::LogFunctor<FloatVectorImageType::InternalPixelType> TransferLogFunctor;
+  typedef UnaryImageFunctorWithVectorImageFilter<FloatVectorImageType,
+    FloatVectorImageType,
+    TransferLogFunctor> TransferLogType;
+
+private:
+
+  void DoInit() ITK_OVERRIDE
+  {
+    SetName("DynamicConvert");
+    SetDescription("Change the pixel type and rescale the image's dynamic");
+
+    // Documentation
+    SetDocName("Dynamic Conversion");
+    // TODO
+    SetDocLongDescription("This application performs an image pixel type "
+      "conversion (short, ushort, uchar, int, uint, float and double types are "
+      "handled). The output image is written in the specified format (ie. "
+      "that corresponds to the given extension).\n The conversion can include "
+      "a rescale of the data range, by default it's set between the 2nd to "
+      "the 98th percentile. The rescale can be linear or log2. \n The choice "
+      "of the output channels can be done with the extended filename, but "
+      "less easy to handle. To do this, a 'channels' parameter allows you to "
+      "select the desired bands at the output. There are 3 modes, the "
+      "available choices are: \n * grayscale :  to display mono image as "
+      "standard color image \n * rgb : select 3 bands in the input image "
+      "(multi-bands) \n * all : keep all bands.");
+    SetDocLimitations("None");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso("Convert, Rescale");
+
+    AddDocTag(Tags::Manip);
+    AddDocTag("Conversion");
+    AddDocTag("Image Dynamic");
+
+    AddParameter(ParameterType_InputImage, "in", "Input image");
+    SetParameterDescription("in", "Input image");
+
+    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
+    SetParameterDescription("out", "Output image");
+    SetDefaultOutputPixelType("out",ImagePixelType_uint8);
+
+    AddParameter(ParameterType_Choice, "type", "Rescale type");
+    SetParameterDescription("type", "Transfer function for the rescaling");
+    AddChoice("type.linear", "Linear");
+    AddChoice("type.log2", "Log2");
+    SetParameterString("type", "linear", false);
+
+    AddParameter(ParameterType_Float,"type.linear.gamma",
+      "Gamma correction factor");
+    SetParameterDescription("type.linear.gamma",
+      "Gamma correction factor");
+    SetDefaultParameterFloat("type.linear.gamma",1.0);
+    MandatoryOff("type.linear.gamma");
+
+    AddParameter(ParameterType_InputImage,  "mask",   "Input mask");
+    SetParameterDescription("mask",
+      "The masked pixels won't be used to adapt the dynamic "
+      "(the mask must have the same dimensions as the input image)");
+    MandatoryOff("mask");
+    DisableParameter("mask");
+
+    AddParameter(ParameterType_Group,"quantile","Histogram quantile cutting");
+    SetParameterDescription("quantile",
+      "Cut the histogram edges before rescaling");
+
+    AddParameter(ParameterType_Float, "quantile.high", "High cut quantile");
+    SetParameterDescription("quantile.high", 
+      "Quantiles to cut from histogram high values "
+      "before computing min/max rescaling (in percent, 2 by default)");
+    MandatoryOff("quantile.high");
+    SetDefaultParameterFloat("quantile.high", 2.0);
+    DisableParameter("quantile.high");
+
+    AddParameter(ParameterType_Float, "quantile.low", "Low cut quantile");
+    SetParameterDescription("quantile.low", 
+      "Quantiles to cut from histogram low values "
+      "before computing min/max rescaling (in percent, 2 by default)");
+    MandatoryOff("quantile.low");
+    SetDefaultParameterFloat("quantile.low", 2.0);
+    DisableParameter("quantile.low");
+
+    AddParameter(ParameterType_Choice, "channels", "Channels selection");
+    SetParameterDescription("channels", "It's possible to select the channels "
+      "of the output image. There are 3 modes, the available choices are:");
+
+    AddChoice("channels.all", "Default mode");
+    SetParameterDescription("channels.all", 
+      "Select all bands in the input image, (1,...,n).");
+
+    AddChoice("channels.grayscale", "Grayscale mode");
+    SetParameterDescription("channels.grayscale", 
+      "Display single channel as standard color image.");
+    AddParameter(ParameterType_Int, "channels.grayscale.channel", 
+      "Grayscale channel");
+    SetDefaultParameterInt("channels.grayscale.channel", 1);
+    SetMinimumParameterIntValue("channels.grayscale.channel", 1);
+
+    AddChoice("channels.rgb", "RGB composition");
+    SetParameterDescription("channels.rgb", "Select 3 bands in the input image "
+      "(multi-bands), by default (1,2,3).");
+
+    AddParameter(ParameterType_Int, "channels.rgb.red", "Red Channel");
+    SetParameterDescription("channels.rgb.red", "Red channel index.");
+    SetMinimumParameterIntValue("channels.rgb.red", 1);
+    AddParameter(ParameterType_Int, "channels.rgb.green", "Green Channel");
+    SetParameterDescription("channels.rgb.green", "Green channel index.");
+    SetMinimumParameterIntValue("channels.rgb.green", 1);
+    AddParameter(ParameterType_Int, "channels.rgb.blue", "Blue Channel");
+    SetParameterDescription("channels.rgb.blue", "Blue channel index.");
+    SetMinimumParameterIntValue("channels.rgb.blue", 1);
+
+    AddParameter(ParameterType_Float, "outmin", "Output min value");
+    SetDefaultParameterFloat("outmin", 0.0);
+    SetParameterDescription( "outmin", "Minimum value of the output image." );
+    AddParameter(ParameterType_Float, "outmax", "Output max value");
+    SetDefaultParameterFloat("outmax", 255.0);
+    SetParameterDescription( "outmax", "Maximum value of the output image." );
+    MandatoryOff("outmin");
+    MandatoryOff("outmax");
+
+    AddRAMParameter();
+
+    // Doc example parameter settings
+    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
+    SetDocExampleParameterValue("out", "otbConvertWithScalingOutput.png");
+    SetDocExampleParameterValue("type", "linear");
+    SetDocExampleParameterValue("channels", "rgb");
+    SetDocExampleParameterValue("outmin", "0");
+    SetDocExampleParameterValue("outmax", "255");
+
+    SetOfficialDocLink();
+  }
+
+  void DoUpdateParameters() ITK_OVERRIDE
+  {
+    // Read information
+    if ( HasValue("in") )
+    {
+      typedef otb::ImageMetadataInterfaceBase ImageMetadataInterfaceType;
+      ImageMetadataInterfaceType::Pointer metadataInterface =
+        ImageMetadataInterfaceFactory::CreateIMI(
+          GetParameterImage("in")->GetMetaDataDictionary());
+
+      int nbBand = GetParameterImage("in")->GetNumberOfComponentsPerPixel();
+      SetMaximumParameterIntValue("channels.grayscale.channel", nbBand);
+      SetMaximumParameterIntValue("channels.rgb.red", nbBand);
+      SetMaximumParameterIntValue("channels.rgb.green", nbBand);
+      SetMaximumParameterIntValue("channels.rgb.blue", nbBand);
+
+      if (nbBand > 1)
+      {
+        // get band index : Red/Green/Blue, in depending on the sensor
+        auto const& display = metadataInterface->GetDefaultDisplay();
+        SetDefaultParameterInt("channels.rgb.red", display[0] + 1);
+        SetDefaultParameterInt("channels.rgb.green", display[1] + 1);
+        SetDefaultParameterInt("channels.rgb.blue", display[2] + 1);
+      }
+    }
+  }
+
+  template<class TImageType>
+  void GenericDoExecute()
+  {
+    // Clear previously registered filters
+    m_Filters.clear();
+
+    std::string rescaleType = this->GetParameterString("type");
+    typedef otb::VectorRescaleIntensityImageFilter<FloatVectorImageType, TImageType> RescalerType;
+    typename RescalerType::Pointer rescaler = RescalerType::New();
+
+    // selected channel
+    auto tempImage = GetSelectedChannels<FloatVectorImageType>();
+
+    const unsigned int nbComp(tempImage->GetNumberOfComponentsPerPixel());
+
+    // We need to subsample the input image in order to estimate its histogram
+    // Shrink factor is computed so as to load a quicklook of 1000
+    // pixels square at most
+    auto imageSize = tempImage->GetLargestPossibleRegion().GetSize();
+    unsigned int shrinkFactor = std::max({int(imageSize[0])/1000, 
+      int(imageSize[1])/1000, 1});
+    otbAppLogDEBUG( << "Shrink factor used to compute Min/Max: "<<shrinkFactor );
+
+    otbAppLogDEBUG( << "Shrink starts..." );
+    typename ShrinkFilterType::Pointer shrinkFilter = ShrinkFilterType::New();
+    shrinkFilter->SetShrinkFactor(shrinkFactor);
+    shrinkFilter->GetStreamer()->
+      SetAutomaticAdaptativeStreaming(GetParameterInt("ram"));
+    AddProcess(shrinkFilter->GetStreamer(), 
+      "Computing shrink Image for min/max estimation...");
+
+    if ( rescaleType == "log2")
+    {
+      //define the transfer log
+      m_TransferLog = TransferLogType::New();
+      m_TransferLog->SetInput(tempImage);
+      m_TransferLog->UpdateOutputInformation();
+
+      shrinkFilter->SetInput(m_TransferLog->GetOutput());
+      rescaler->SetInput(m_TransferLog->GetOutput());
+      shrinkFilter->Update();
+    }
+    else
+    {
+      shrinkFilter->SetInput(tempImage);
+      rescaler->SetInput(tempImage);
+      shrinkFilter->Update();
+    }
+
+    otbAppLogDEBUG( << "Evaluating input Min/Max..." );
+    itk::ImageRegionConstIterator<FloatVectorImageType>
+      it(shrinkFilter->GetOutput(), 
+        shrinkFilter->GetOutput()->GetLargestPossibleRegion());
+
+    typename ListSampleType::Pointer listSample = ListSampleType::New();
+    listSample->SetMeasurementVectorSize( 
+      tempImage->GetNumberOfComponentsPerPixel());
+
+    // Now we generate the list of samples
+    if (IsParameterEnabled("mask"))
+    {
+      FloatVectorImageType::Pointer mask = this->GetParameterImage("mask");
+      ShrinkFilterType::Pointer maskShrinkFilter = ShrinkFilterType::New();
+      maskShrinkFilter->SetShrinkFactor(shrinkFactor);
+      maskShrinkFilter->SetInput(mask);
+      maskShrinkFilter->GetStreamer()->
+        SetAutomaticAdaptativeStreaming(GetParameterInt("ram"));
+      maskShrinkFilter->Update();
+
+      auto itMask = itk::ImageRegionConstIterator<FloatVectorImageType>(
+        maskShrinkFilter->GetOutput(),
+        maskShrinkFilter->GetOutput()->GetLargestPossibleRegion());
+
+      // Remove masked pixels
+      it.GoToBegin();
+      itMask.GoToBegin();
+      for(; !it.IsAtEnd(); ++it, ++itMask)
+      {
+        // float values, so the threshold is set to 0.5
+        if (itMask.Get()[0] > 0.5)
+        {
+          listSample->PushBack(it.Get());
+        }
+      }
+      // if listSample is empty
+      if (listSample->Size() == 0)
+      {
+        otbAppLogINFO( << "All pixels were masked, the application assume "
+          "a wrong mask and include all the image");
+      }
+    }
+
+    // get all pixels : if mask is disable or all pixels were masked
+    if ((!IsParameterEnabled("mask")) || (listSample->Size() == 0))
+    {
+      for(it.GoToBegin(); !it.IsAtEnd(); ++it)
+      {
+        listSample->PushBack(it.Get());
+      }
+    }
+
+    // And then the histogram
+    typename HistogramsGeneratorType::Pointer histogramsGenerator = 
+      HistogramsGeneratorType::New();
+    histogramsGenerator->SetListSample(listSample);
+    histogramsGenerator->SetNumberOfBins(255);
+    // Samples with nodata values are ignored
+    histogramsGenerator->NoDataFlagOn();
+    histogramsGenerator->Update();
+    auto histOutput = histogramsGenerator->GetOutput();
+    assert(histOutput);
+
+    // And extract the lower and upper quantile
+    typename FloatVectorImageType::PixelType inputMin(nbComp), inputMax(nbComp);
+    for(unsigned int i = 0; i < nbComp; ++i)
+    {
+      auto && elm = histOutput->GetNthElement(i);
+      assert(elm);
+      inputMin[i] = elm->Quantile(0, 
+        0.01 * GetParameterFloat("quantile.low"));
+      inputMax[i] = elm->Quantile(0, 
+        1.0 - 0.01 * GetParameterFloat("quantile.high"));
+    }
+
+    otbAppLogDEBUG( << std::setprecision(5) 
+                    << "Min/Max computation done : min=" 
+                    << inputMin
+                    << " max=" << inputMax );
+
+    rescaler->AutomaticInputMinMaxComputationOff();
+    rescaler->SetInputMinimum(inputMin);
+    rescaler->SetInputMaximum(inputMax);
+
+    if ( rescaleType == "linear")
+    {
+      rescaler->SetGamma(GetParameterFloat("type.linear.gamma"));
+    }
+
+    typename TImageType::PixelType minimum(nbComp);
+    typename TImageType::PixelType maximum(nbComp);
+
+    /*
+    float outminvalue = std::numeric_limits<typename TImageType::InternalPixelType>::min();
+    float outmaxvalue = std::numeric_limits<typename TImageType::InternalPixelType>::max();
+    // TODO test outmin/outmax values
+    if (outminvalue > GetParameterFloat("outmin"))
+      itkExceptionMacro("The outmin value at " << GetParameterFloat("outmin") << 
+                        " is too low, select a value in "<< outminvalue <<" min.");
+    if ( outmaxvalue < GetParameterFloat("outmax") )
+      itkExceptionMacro("The outmax value at " << GetParameterFloat("outmax") << 
+                        " is too high, select a value in "<< outmaxvalue <<" max.");
+    */
+
+    maximum.Fill( GetParameterFloat("outmax") );
+    minimum.Fill( GetParameterFloat("outmin") );
+
+    rescaler->SetOutputMinimum(minimum);
+    rescaler->SetOutputMaximum(maximum);
+
+    m_Filters.push_back(rescaler.GetPointer());
+    SetParameterOutputImage<TImageType>("out", rescaler->GetOutput());
+  }
+
+  // Get the bands order
+  std::vector<int> const GetChannels()
+  {
+    std::vector<int> channels;
+
+    int nbChan = GetParameterImage("in")->GetNumberOfComponentsPerPixel();
+    std::string channelMode = GetParameterString("channels");
+
+    if(channelMode == "grayscale")
+    {
+      if (GetParameterInt("channels.grayscale.channel") <= nbChan)
+      {
+        channels = {GetParameterInt("channels.grayscale.channel"),
+        GetParameterInt("channels.grayscale.channel"),
+        GetParameterInt("channels.grayscale.channel")};
+      }
+      else
+      {
+        itkExceptionMacro(<< "The channel has an invalid index");
+      }
+    }
+    else if (channelMode == "rgb")
+    {
+      if ((GetParameterInt("channels.rgb.red") <= nbChan)
+        && ( GetParameterInt("channels.rgb.green") <= nbChan)
+        && ( GetParameterInt("channels.rgb.blue")   <= nbChan))
+      {
+        channels = {GetParameterInt("channels.rgb.red"),
+        GetParameterInt("channels.rgb.green"),
+        GetParameterInt("channels.rgb.blue")};
+      }
+      else
+      {
+        itkExceptionMacro(<< "At least one needed channel has an invalid "
+          "index");
+      }
+    }
+    else if (channelMode == "all")
+    {
+      // take all bands
+      channels.resize(nbChan);
+      std::iota(channels.begin(), channels.end(), 1);
+    }
+    return channels;
+  }
+
+  // return an image with the bands order modified of the input image
+  template<class TImageType>
+  typename TImageType::Pointer GetSelectedChannels()
+  {
+    typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,
+      typename TImageType::InternalPixelType> ExtractROIFilterType;
+    typedef otb::ImageList<otb::Image<typename TImageType::InternalPixelType> > ImageListType;
+    typedef ImageListToVectorImageFilter<ImageListType,
+                                         TImageType > ListConcatenerFilterType;
+
+    typename ImageListType::Pointer imageList  = ImageListType::New();
+    typename ListConcatenerFilterType::Pointer concatener = 
+      ListConcatenerFilterType::New();
+
+    //m_Filters.push_back(imageList.GetPointer());
+    m_Filters.push_back(concatener.GetPointer());
+
+    const bool monoChannel = IsParameterEnabled("channels.grayscale");
+
+    // get band order
+    const std::vector<int> channels = GetChannels();
+
+    for (auto && channel : channels)
+    {
+      typename ExtractROIFilterType::Pointer extractROIFilter = 
+        ExtractROIFilterType::New();
+      m_Filters.push_back(extractROIFilter.GetPointer());
+      extractROIFilter->SetInput(GetParameterImage("in"));
+      if (!monoChannel) 
+        extractROIFilter->SetChannel(channel);
+
+      extractROIFilter->UpdateOutputInformation();
+      imageList->PushBack(extractROIFilter->GetOutput());
+    }
+
+    concatener->SetInput(imageList);
+    concatener->UpdateOutputInformation();
+
+    return concatener->GetOutput();
+  }
+
+
+  void DoExecute() override
+  {
+    switch ( this->GetParameterOutputImagePixelType("out") )
+    {
+      case ImagePixelType_uint8:
+        GenericDoExecute<UInt8VectorImageType>();
+        break;
+      case ImagePixelType_int16:
+        GenericDoExecute<Int16VectorImageType>();
+        break;
+      case ImagePixelType_uint16:
+        GenericDoExecute<UInt16VectorImageType>();
+        break;
+      case ImagePixelType_int32:
+        GenericDoExecute<Int32VectorImageType>();
+        break;
+      case ImagePixelType_uint32:
+        GenericDoExecute<UInt32VectorImageType>();
+        break;
+      case ImagePixelType_float:
+        GenericDoExecute<FloatVectorImageType>();
+        break;
+      case ImagePixelType_double:
+        GenericDoExecute<DoubleVectorImageType>();
+        break;
+      default:
+        itkExceptionMacro("Unknown pixel type "
+          <<this->GetParameterOutputImagePixelType("out")<<".");
+        break;
+    }
+  }
+
+  itk::ProcessObject::Pointer m_TmpFilter;
+  TransferLogType::Pointer m_TransferLog;
+  std::vector<itk::LightObject::Pointer> m_Filters;
+};
+
+}
+}
+
+OTB_APPLICATION_EXPORT(otb::Wrapper::DynamicConvert)
+
diff --git a/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx b/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx
index 62857ab..74bb9c4 100644
--- a/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbReadImageInfo.cxx
@@ -316,8 +316,8 @@ private:
     ossOutput << "\tOrigin :  [" << GetParameterFloat("originx") << "," << GetParameterFloat("originy") << "]" << std::endl;
 
     //Get image spacing
-    SetParameterFloat("spacingx",inImage->GetSpacing()[0], false);
-    SetParameterFloat("spacingy",inImage->GetSpacing()[1], false);
+    SetParameterFloat("spacingx",inImage->GetSignedSpacing()[0], false);
+    SetParameterFloat("spacingy",inImage->GetSignedSpacing()[1], false);
     ossOutput << "\tSpacing :  [" << GetParameterFloat("spacingx") << "," << GetParameterFloat("spacingy") << "]" << std::endl;
 
     //Estimate ground spacing
diff --git a/Modules/Applications/AppImageUtils/app/otbRescale.cxx b/Modules/Applications/AppImageUtils/app/otbRescale.cxx
index 54cb606..f5c08c8 100644
--- a/Modules/Applications/AppImageUtils/app/otbRescale.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbRescale.cxx
@@ -62,8 +62,8 @@ private:
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
 
+    AddDocTag(Tags::Deprecated);
     AddDocTag(Tags::Manip);
-
     AddParameter(ParameterType_InputImage,  "in",   "Input Image");
     SetParameterDescription( "in", "The image to scale." );
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
diff --git a/Modules/Applications/AppImageUtils/app/otbSplitImage.cxx b/Modules/Applications/AppImageUtils/app/otbSplitImage.cxx
index ece8b81..e23eaa5 100644
--- a/Modules/Applications/AppImageUtils/app/otbSplitImage.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbSplitImage.cxx
@@ -52,13 +52,16 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("SplitImage");
-    SetDescription("Split a N multiband image into N images");
+    SetDescription("Split a N multiband image into N images.");
 
     SetDocName("Split Image");
-    SetDocLongDescription("This application splits a N-bands image into N mono-band images. The output images filename will be generated from the output parameter. Thus if the input image has 2 channels, and the user has set an output outimage.tif, the generated images will be outimage_0.tif and outimage_1.tif");
+    SetDocLongDescription("This application splits a N-bands image into N mono-band images. "
+      "The output images filename will be generated from the output parameter. "
+      "Thus, if the input image has 2 channels, and the user has set as output parameter, outimage.tif, "
+      "the generated images will be outimage_0.tif and outimage_1.tif.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+    SetDocSeeAlso("ConcatenateImages");
 
     AddDocTag(Tags::Manip);
 
@@ -66,8 +69,10 @@ private:
     SetParameterDescription("in","Input multiband image filename.");
 
     AddParameter(ParameterType_OutputImage, "out", "Output Image");
-    SetParameterDescription("out",
-                            "Output filename that will be used to get the prefix and the extension of the output images to write");
+    SetParameterDescription("out", "The output filename will be used to get the prefix "
+    "an the extension of the output written's image. For example with outimage.tif as output filename, "
+    "the generated images will had an indice (corresponding at each bands) "
+    "between the prefix and the extension, such as: outimage_0.tif  and outimage_1.tif (if 2 bands).");
 
     AddRAMParameter();
 
diff --git a/Modules/Applications/AppImageUtils/app/otbTileFusion.cxx b/Modules/Applications/AppImageUtils/app/otbTileFusion.cxx
index a3f6a68..5dd80bc 100644
--- a/Modules/Applications/AppImageUtils/app/otbTileFusion.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbTileFusion.cxx
@@ -52,7 +52,7 @@ private:
 
     // Documentation
     SetDocName("Image Tile Fusion");
-    SetDocLongDescription("Concatenate several tile files into a single image file.");
+    SetDocLongDescription("Automatically mosaic a set of non overlapping tile files into a single image. Images must have a matching number of bands and they must be listed in lexicographic order.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
@@ -60,7 +60,7 @@ private:
     AddDocTag(Tags::Manip);
 
     AddParameter(ParameterType_InputImageList,  "il",   "Input Tile Images");
-    SetParameterDescription("il", "Input tiles to concatenate (in lexicographic order : (0,0) (1,0) (0,1) (1,1)).");
+    SetParameterDescription("il", "Input images to concatenate (in lexicographic order, for instance : (0,0) (1,0) (0,1) (1,1)).");
 
     AddParameter(ParameterType_Int, "cols", "Number of tile columns");
     SetParameterDescription("cols", "Number of columns in the tile array");
diff --git a/Modules/Applications/AppImageUtils/test/CMakeLists.txt b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
index 7c33a6b..d2852f4 100644
--- a/Modules/Applications/AppImageUtils/test/CMakeLists.txt
+++ b/Modules/Applications/AppImageUtils/test/CMakeLists.txt
@@ -36,7 +36,7 @@ otb_test_application(NAME apTvUtConvertBasic
                      OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
                              -out ${TEMP}/apTvUtConvertBasicOutput.tif float
                      VALID   --compare-image ${NOTOL}
-                             ${INPUTDATA}/apTvUtConvertBasicOutput.tif
+                             ${OTBAPP_BASELINE}/apTvUtConvertBasicOutput.tif
                 	     ${TEMP}/apTvUtConvertBasicOutput.tif
 )
 
@@ -52,8 +52,8 @@ otb_test_application(NAME apTvUtConvertWithScaling
                              -out ${TEMP}/apTvUtConvertWithScalingOutput.tif
                              -type linear
                      VALID   --compare-image ${NOTOL}
-                             ${INPUTDATA}/apTvUtConvertWithScalingOutput.tif
-                	     ${TEMP}/apTvUtConvertWithScalingOutput.tif
+                             ${OTBAPP_BASELINE}/apTvUtConvertWithScalingOutput.tif
+                             ${TEMP}/apTvUtConvertWithScalingOutput.tif
 )
 
 otb_test_application(NAME apTvUtConvertExtendedFilename_readerGEOM
@@ -74,7 +74,7 @@ otb_test_application(NAME apTvUtConvertSelectChannels
                              -channels.rgb.blue 1
                              -type linear
                      VALID   --compare-image ${NOTOL}
-                             ${INPUTDATA}/apTvUtConvertSelectChannelsRgbOutput.tif
+                             ${OTBAPP_BASELINE}/apTvUtConvertSelectChannelsRgbOutput.tif
                              ${TEMP}/apTvUtConvertSelectChannelsRgbOutput.tif)
 
 otb_test_application(NAME apTvUtConvertMonoChannel
@@ -84,9 +84,46 @@ otb_test_application(NAME apTvUtConvertMonoChannel
                              -channels grayscale
                              -type linear
                      VALID   --compare-image ${NOTOL}
-                             ${INPUTDATA}/apTvUtConvertMonoChannelOutput.tif
+                             ${OTBAPP_BASELINE}/apTvUtConvertMonoChannelOutput.tif
                              ${TEMP}/apTvUtConvertMonoChannelOutput.tif)
 
+#----------- DynamicConvert TESTS ------------
+otb_test_application(NAME apTvUtDynamicConvertBasic
+                     APP DynamicConvert
+                     OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
+                             -out ${TEMP}/apTvUtDynamicConvertOutput.tif
+                             -type linear
+                             -channels rgb
+                             -channels.rgb.red 2
+                             -channels.rgb.green 3
+                             -channels.rgb.blue 1
+                     VALID   --compare-image ${NOTOL}
+                             ${OTBAPP_BASELINE}/apTvUtConvertSelectChannelsRgbOutput.tif
+                             ${TEMP}/apTvUtDynamicConvertOutput.tif)
+
+otb_test_application(NAME apTvUtDynamicConvertLog2
+                     APP DynamicConvert
+                     OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_XS.tif
+                             -out ${TEMP}/apTvUtDynamicConvertLog2Output.tif
+                             -type log2
+                     VALID   --compare-image ${NOTOL}
+                             ${OTBAPP_BASELINE}/apTvUtDynamicConvertLog2Output.tif
+                             ${TEMP}/apTvUtDynamicConvertLog2Output.tif)
+
+otb_test_application(NAME apTvUtDynamicConvertFloat
+                     APP DynamicConvert
+                     OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
+                             -out ${TEMP}/apTvUtDynamicConvertFloatOutput.tif float
+                             -type linear
+                             -type.linear.gamma 2.2
+                             -outmin 0.0
+                             -outmax 1.0
+                             -quantile.low 0
+                             -quantile.high 4
+                     VALID   --compare-image ${NOTOL}
+                             ${OTBAPP_BASELINE}/apTvUtDynamicConvertFloatOutput.tif
+                             ${TEMP}/apTvUtDynamicConvertFloatOutput.tif)
+
 #----------- PixelInfo TESTS ----------------
 
 #----------- ExtractROI TESTS ----------------
diff --git a/Modules/Applications/AppIndices/app/CMakeLists.txt b/Modules/Applications/AppIndices/app/CMakeLists.txt
index 188bcf7..e17b73e 100644
--- a/Modules/Applications/AppIndices/app/CMakeLists.txt
+++ b/Modules/Applications/AppIndices/app/CMakeLists.txt
@@ -18,12 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppIndices_LINK_LIBS
-  ${OTBIndices_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-)
-
 otb_create_application(
   NAME           RadiometricIndices
   SOURCES        otbRadiometricIndices.cxx
diff --git a/Modules/Applications/AppKMZ/app/CMakeLists.txt b/Modules/Applications/AppKMZ/app/CMakeLists.txt
index 2ac1d7b..40a4c3f 100644
--- a/Modules/Applications/AppKMZ/app/CMakeLists.txt
+++ b/Modules/Applications/AppKMZ/app/CMakeLists.txt
@@ -18,10 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppImageUtils_LINK_LIBS
-  ${OTBKMZWriter_LIBRARIES}
-)
-
 otb_create_application(
   NAME           KmzExport
   SOURCES        otbKmzExport.cxx
diff --git a/Modules/Applications/AppMathParser/app/CMakeLists.txt b/Modules/Applications/AppMathParser/app/CMakeLists.txt
index de42c60..5169067 100644
--- a/Modules/Applications/AppMathParser/app/CMakeLists.txt
+++ b/Modules/Applications/AppMathParser/app/CMakeLists.txt
@@ -18,14 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppMathParser_LINK_LIBS
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBMathParser_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-  )
-
-
 otb_create_application(
   NAME           BandMath
   SOURCES        otbBandMath.cxx
diff --git a/Modules/Applications/AppMathParser/app/otbBandMath.cxx b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
index f8ecc1b..37a9054 100644
--- a/Modules/Applications/AppMathParser/app/otbBandMath.cxx
+++ b/Modules/Applications/AppMathParser/app/otbBandMath.cxx
@@ -66,22 +66,34 @@ private:
 
     SetDocLongDescription(
       "This application performs a mathematical operation on several multi-band "
-      "images and outputs the result into a monoband image. Evaluation of the "
+      "images and outputs the result into a monoband image. The given expression"
+      " is computed at each pixel position. Evaluation of the "
       "mathematical formula is done by the muParser libraries.\n\n"
 
-      "muParser version superior to 2.0, provides the '&&' and '||' logical "
-      "operators, and a ternary operator 'boolean_expression ? if_true : "
-      "if_false'.\n\n"
-
-      "Older versions of muParser (prior to v-2.0) provides only the 'and' and "
-      "'or' logical operators, and a ternary operator 'if(; ; )'.\n\n"
-
-      "The list of features and operators is available on the muParser website [1]."
+      "The formula can be written using:\n\n"
+      "  * numerical values ( 2.3, -5, 3.1e4, ...)\n"
+      "  * variables containing pixel values (e.g. : 'im2b3' is the pixel value"
+      " in 2nd image, 3rd band)\n"
+      "  * binary operators:\n\n"
+      "    * '+' addition, '-' subtraction, '*' multiplication, '/' division\n"
+      "    * '^' raise x to the power of y\n"
+      "    * '<' less than, '>' greater than, '<=' less or equal, '>=' greater or equal\n"
+      "    * '==' equal, '!=' not equal\n"
+#ifdef OTB_MUPARSER_HAS_CXX_LOGICAL_OPERATORS
+      "    * '||' logical or, '&&' logical and\n"
+      "  * if-then-else operator: '(condition ? value_true : value_false)'\n"
+#else
+      "    * 'or' logical or, 'and' logical and\n"
+      "  * if-then-else operator: 'if(condition;value_true;value_false)'\n"
+#endif
+      "  * functions : exp(), log(), sin(), cos(), min(), max(), ...\n\n"
+
+      "The full list of features and operators is available on the muParser website [1]."
       );
 
     SetDocLimitations( "None" );
     SetDocAuthors( "OTB-Team" );
-    SetDocSeeAlso("[1] http://muparser.sourceforge.net/");
+    SetDocSeeAlso("[1] http://beltoforion.de/article.php?a=muparser");
     AddDocTag( "Miscellaneous" );
 
     AddParameter( ParameterType_InputImageList, "il", "Input image-list" );
@@ -101,12 +113,7 @@ private:
     AddParameter( ParameterType_String, "exp", "Expression");
     SetParameterDescription(
       "exp",
-      "The muParser mathematical expression to apply on input images.\n"
-      "Use im1b1 as first band of first image, im1b2 for the second band of "
-      "first image.\n"
-      "Use im2b1 as first band of second image, im2b2 for the second band of "
-      "second image.\n"
-      "etc."
+      "The muParser mathematical expression to apply on input images."
     );
 
     // Doc example parameter settings
diff --git a/Modules/Applications/AppMathParserX/app/CMakeLists.txt b/Modules/Applications/AppMathParserX/app/CMakeLists.txt
index fef444d..e36ba79 100644
--- a/Modules/Applications/AppMathParserX/app/CMakeLists.txt
+++ b/Modules/Applications/AppMathParserX/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppMathParserX_LINK_LIBS
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBMathParserX_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-  )
-
-
 otb_create_application(
   NAME           BandMathX
   SOURCES        otbBandMathX.cxx
diff --git a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
index 7c56aa8..90a7f24 100644
--- a/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
+++ b/Modules/Applications/AppMathParserX/app/otbBandMathX.cxx
@@ -82,44 +82,30 @@ private:
       "Fundamentals\n"
       "------------\n\n"
 
-      "The i-th input image is identified by the 'im<i+1>' (e.g. 'im1') prefix "
-      "(please, note the indexing from 1 to N, for N inputs).\n\n"
-
-      "The following list summarizes the available variables of input #0:\n\n"
-
-      "im1\n"
-      "  a pixel from 1st input, made of n components (n bands).\n\n"
-
-      "im1b2\n"
-      "  the 2nd component of a pixel from 1st input (band index is 1-based).\n\n"
-
-      "im1b2N3x4\n"
-      "  a 3x4 pixels 'N'eighbourhood of a pixel the 2nd component of a pixel "
-      "from the 1st input.\n\n"
-
-      "im1PhyX\n"
-      "  horizontal (X-axis) spacing of the 1st input.\n\n"
-
-      "im1PhyY\n"
-      "  vertical spacing of the 1st input input.\n\n"
-
-      "im1b2Mean\n"
-      "  mean of the 2nd component of the 1st input (global statistics)\n\n"
-
-      "im1b2Mini\n"
-      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
-
-      "im1b2Maxi\n"
-      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
-
-      "im1b2Sum\n"
-      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
-
-      "im1b2Var\n"
-      "  minimum of the 2nd component of the 1st input (global statistics)\n\n"
-
-      "idxX, idxY\n"
-      "  indices of the current pixel (generic variables)\n\n"
+      "The formula can be written using:\n\n"
+      "  * numerical values ( 2.3, -5, 3.1e4, ...)\n"
+      "  * variables containing pixel values (please, note the indexing of "
+      "inputs from 1 to N). Examples for the first input image:\n\n"
+      "    * 'im1' a pixel from 1st input, made of n components (n bands)\n"
+      "    * 'im1b2' the 2nd component of a pixel from 1st input (band index is 1-based)\n"
+      "    * 'im1b2N3x4' a 3x4 pixels 'N'eighbourhood of a pixel the 2nd "
+      "component of a pixel from the 1st input\n"
+      "    * 'im1PhyX' horizontal (X-axis) spacing of the 1st input.\n"
+      "    * 'im1PhyY' vertical spacing of the 1st input input.\n"
+      "    * 'im1b2Mean' mean of the 2nd component of the 1st input (global statistics)\n"
+      "    * 'im1b2Mini' minimum of the 2nd component of the 1st input (global statistics)\n"
+      "    * 'im1b2Maxi' maximum of the 2nd component of the 1st input (global statistics)\n"
+      "    * 'im1b2Sum' sum of the 2nd component of the 1st input (global statistics)\n"
+      "    * 'im1b2Var' variance of the 2nd component of the 1st input (global statistics)\n"
+      "    * 'idxX' and 'idxY' are the indices of the current pixel (generic variables)\n"
+      "  * binary operators:\n\n"
+      "    * '+' addition, '-' subtraction, '*' multiplication, '/' division\n"
+      "    * '^' raise x to the power of y\n"
+      "    * '<' less than, '>' greater than, '<=' less or equal, '>=' greater or equal\n"
+      "    * '==' equal, '!=' not equal\n"
+      "    * logical operators: 'or', 'and', 'xor'\n"
+      "  * if-then-else operator: '(condition ? value_true : value_false)'\n"
+      "  * functions : abs(), exp(), log(), sin(), cos(), min(), max(), ...\n\n"
 
       "Always keep in mind that this application only addresses mathematically "
       "well-defined formulas. For instance, it is not possible to add vectors of"
@@ -130,16 +116,16 @@ private:
       "represented as a row vector.\n\n"
 
       "Example:\n"
-      "  im1 + im2 (1)\n"
+      "  im1 + im2\n"
       "  represents the addition of pixels from the 1st and 2nd inputs. This "
       "expression is consistent only if both inputs have the same number of "
       "bands.\n\n"
 
       "Please, note that it is also possible to use the following expressions"
-      " to obtain the same result:\n"
-      "  im1b1 + im2b1\n"
-      "  im1b2 + im2b2 (2)\n"
-      "  ...\n\n"
+      " to obtain the same result:\n\n"
+      "  * im1b1 + im2b1\n"
+      "  * im1b2 + im2b2\n"
+      "  * ...\n\n"
 
       "Nevertheless, the first expression is by far much pleaseant. We call "
       "this new functionality the 'batch mode' (performing the same operation "
@@ -150,41 +136,41 @@ private:
 
       "Another new feature is the possibility to perform operations that "
       "involve neighborhoods of pixels. Variables related to such neighborhoods "
-      "are always defined following the imIbJNKxP pattern, where:\n"
-      "- I is an number identifying the image input (remember, input #0 = im1, "
+      "are always defined following the imIbJNKxP pattern, where:\n\n"
+      "  - I is an number identifying the image input (remember, input #0 = im1, "
       "and so on)\n"
-      "- J is an number identifying the band (remember, first band is indexed by"
+      "  - J is an number identifying the band (remember, first band is indexed by"
       "1)\n"
-      "- KxP are two numbers that represent the size of the neighborhood (first "
+      "  - KxP are two numbers that represent the size of the neighborhood (first "
       "one is related to the horizontal direction)\n\n"
 
       "NB: All neighborhood are centered, thus K and P must be odd numbers.\n\n"
 
-      "Many operators come with this new functionality:\n"
-      "- dotpr\n"
-      "- mean\n"
-      "- var\n"
-      "- median\n"
-      "- min\n"
-      "- max\n"
-      "- etc.\n\n"
-
-      "For instance, if im1 represents the pixel of 3 bands image:\n"
-      "  im1 - mean( im1b1N5x5, im1b2N5x5, im1b3N5x5 ) (3)\n\n"
+      "Many operators come with this new functionality:\n\n"
+      "  - dotpr\n"
+      "  - mean\n"
+      "  - var\n"
+      "  - median\n"
+      "  - min\n"
+      "  - max\n"
+      "  - etc.\n\n"
+
+      "For instance, if im1 represents the pixel of 3 bands image::\n\n"
+      "  im1 - mean( im1b1N5x5, im1b2N5x5, im1b3N5x5 )\n\n"
       "could represent a high pass filter (note that by implying three "
       "neighborhoods, the operator mean returns a row vector of three components"
       ". It is a typical behaviour for many operators of this application).\n\n"
 
-      "In addition to the previous operators, other operators are available:\n"
-      "- existing operators/functions from muParserX, that were not originally "
+      "In addition to the previous operators, other operators are available:\n\n"
+      "  - existing operators/functions from muParserX, that were not originally "
       "defined for vectors and matrices (e.g. cos, sin). These new "
       "operators/functions keep the original names to which we added the prefix "
       "'v' for vector (vcos, vsin, etc.)\n"
-      "- mult, div and pow operators, that perform element-wise multiplication, "
+      "  - mult, div and pow operators, that perform element-wise multiplication, "
       "division or exponentiation of vector/matrices (e.g. im1 div im2).\n"
-      "- mlt, dv and pw operators, that perform multiplication, division or "
+      "  - mlt, dv and pw operators, that perform multiplication, division or "
       "exponentiation of vector/matrices by a scalar (e.g. im1 dv 2.0).\n"
-      "- bands, which is a very useful operator. It allows selecting specific "
+      "  - bands, which is a very useful operator. It allows selecting specific "
       "bands from an image, and/or to rearrange them in a new vector (e.g."
       "bands( im1, { 1, 2, 1, 1 } ) produces a vector of 4 components made of "
       "band 1, band 2, band 1 and band 1 values from the first input.\n\n"
@@ -194,30 +180,19 @@ private:
       "The application itself\n"
       "----------------------\n\n"
 
-      "The application takes the following parameters:\n"
-      "-il          Sets the list of inputs\n"
-      "-ext         Sets the mathematical expression (see also limitations "
-      "section below).\n"
-      "-incontext   Sets the text filename containing constants values (syntax: "
-      "'#type name value')\n\n"
-
-      "An example of such a file is given below:\n"
+      "The application can use an expression supplied with the 'exp' parameter."
+      " It can also use an input context file, that defines variables and "
+      "expressions. An example of context file is given below::\n\n"
       "  #F expo 1.1\n"
       "  #M kernel1 { 0.1 , 0.2 , 0.3; 0.4 , 0.5 , 0.6; 0.7 , 0.8 , 0.9; 1 , 1.1"
-      ", 1.2; 1.3 , 1.4 , 1.5 }\n\n"
+      ", 1.2; 1.3 , 1.4 , 1.5 }\n"
+      "  #E $dotpr( kernel1, im1b1N3x5 ); im2b1^expo$\n\n"
 
       "As we can see, #I/#F allows the definition of an integer/float constant, "
       "whereas #M allows the definition of a vector/matrix. In the latter case, "
       "elements of a row must be separated by commas, and rows must be separated"
-      " by semicolons.\n\n"
-
-      "It is also possible to define expressions within the same txt file, with "
-      "#E <expr> (see limitations, below). For instance:\n"
-      "  #E $dotpr( kernel1, im1b1N3x5 ); im2b1^expo$\n\n"
-
-      "-outcontext  Output usesr's constants and expressions (context).\n"
-      "-out         Sets output image (multi-outputs is not implemented yet).\n"
-      "\n"
+      " by semicolons. It is also possible to define expressions within the same"
+      " txt file, with #E <expr> (see limitations, below).\n"
 
       "Finally, we strongly recommend to read the OTB Cookbook which can be "
       "found at: http://www.orfeo-toolbox.org/packages/OTBCookBook.pdf"
diff --git a/Modules/Applications/AppMoments/app/CMakeLists.txt b/Modules/Applications/AppMoments/app/CMakeLists.txt
index 8a59214..197588d 100644
--- a/Modules/Applications/AppMoments/app/CMakeLists.txt
+++ b/Modules/Applications/AppMoments/app/CMakeLists.txt
@@ -18,12 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppMoments_LINK_LIBS
-  ${OTBMoments_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-)
-
 otb_create_application(
   NAME           LocalStatisticExtraction
   SOURCES        otbLocalStatisticExtraction.cxx
diff --git a/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx b/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx
index c743fa2..f04bb70 100644
--- a/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx
+++ b/Modules/Applications/AppMoments/app/otbLocalStatisticExtraction.cxx
@@ -26,8 +26,6 @@
 
 #include "otbMultiToMonoChannelExtractROI.h"
 
-#include "itkTimeProbe.h"
-
 namespace otb
 {
 namespace Wrapper
diff --git a/Modules/Applications/AppMorphology/app/CMakeLists.txt b/Modules/Applications/AppMorphology/app/CMakeLists.txt
index dd1d8c9..dbb2b77 100644
--- a/Modules/Applications/AppMorphology/app/CMakeLists.txt
+++ b/Modules/Applications/AppMorphology/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppMorphology_LINK_LIBS
-  ${OTBImageBase_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-  ${OTBMorphologicalProfiles_LIBRARIES}
-)
-
 otb_create_application(
   NAME           BinaryMorphologicalOperation
   SOURCES        otbBinaryMorphologicalOperation.cxx
diff --git a/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx b/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx
index 486dd17..c4a5961 100644
--- a/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx
+++ b/Modules/Applications/AppMorphology/app/otbBinaryMorphologicalOperation.cxx
@@ -34,8 +34,6 @@
 #include "otbImageList.h"
 #include "otbImageListToVectorImageFilter.h"
 
-#include "itkTimeProbe.h"
-
 namespace otb
 {
 namespace Wrapper
@@ -78,77 +76,101 @@ private:
 
 void DoInit() ITK_OVERRIDE
 {
-SetName("BinaryMorphologicalOperation");
-SetDescription("Performs morphological operations on an input image channel");
+SetName( "BinaryMorphologicalOperation" );
+SetDescription( "Performs morphological operations on an input image channel" );
 
 // Documentation
-SetDocName("Binary Morphological Operation");
-SetDocLongDescription("This application performs binary morphological operations on a mono band image");
-SetDocLimitations("None");
-SetDocAuthors("OTB-Team");
-SetDocSeeAlso("itkBinaryDilateImageFilter, itkBinaryErodeImageFilter, itkBinaryMorphologicalOpeningImageFilter and itkBinaryMorphologicalClosingImageFilter classes");
+SetDocName( "Binary Morphological Operation" );
+SetDocLongDescription( "This application performs binary morphological "
+  "operations on a mono band image or a channel of the input." );
+SetDocLimitations( "None" );
+SetDocAuthors( "OTB-Team" );
+SetDocSeeAlso( "itkBinaryDilateImageFilter, itkBinaryErodeImageFilter, "
+  "itkBinaryMorphologicalOpeningImageFilter and "
+  "itkBinaryMorphologicalClosingImageFilter classes." );
 
 AddDocTag(Tags::FeatureExtraction);
 AddDocTag("Morphology");
 
-AddParameter(ParameterType_InputImage, "in",  "Input Image");
-SetParameterDescription("in", "The input image to be filtered.");
+AddParameter( ParameterType_InputImage , "in" ,  "Input Image" );
+SetParameterDescription( "in" , "The input image to be filtered." );
 
-AddParameter(ParameterType_OutputImage, "out", "Feature Output Image");
-SetParameterDescription("out", "Output image containing the filtered output image.");
+AddParameter( ParameterType_OutputImage , "out" , "Output Image" );
+SetParameterDescription( "out" , "Output image" );
 
-AddParameter(ParameterType_Int,  "channel",  "Selected Channel");
-SetParameterDescription("channel", "The selected channel index");
-SetDefaultParameterInt("channel", 1);
-SetMinimumParameterIntValue("channel", 1);
+AddParameter( ParameterType_Int ,  "channel" ,  "Selected Channel" );
+SetParameterDescription( "channel" , "The selected channel index" );
+SetDefaultParameterInt( "channel" , 1 );
+SetMinimumParameterIntValue( "channel" , 1 );
 
 AddRAMParameter();
 
-AddParameter(ParameterType_Choice, "structype", "Structuring Element Type");
-SetParameterDescription("structype", "Choice of the structuring element type");
+AddParameter( ParameterType_Choice , "structype" ,
+ "Type of structuring element" );
+SetParameterDescription( "structype" , 
+  "Choice of the structuring element type");
 //Ball
-AddChoice("structype.ball", "Ball");
-AddParameter(ParameterType_Int, "structype.ball.xradius", "The Structuring Element X Radius");
-SetParameterDescription("structype.ball.xradius", "The Structuring Element X Radius");
-SetDefaultParameterInt("structype.ball.xradius", 5);
-AddParameter(ParameterType_Int, "structype.ball.yradius", "The Structuring Element Y Radius");
-SetParameterDescription("structype.ball.yradius", "The Structuring Element Y Radius");
-SetDefaultParameterInt("structype.ball.yradius", 5);
+AddChoice( "structype.ball" , "Ball" );
+AddParameter( ParameterType_Int , "structype.ball.xradius" ,
+ "Structuring element X radius" );
+SetParameterDescription( "structype.ball.xradius" , 
+  "The structuring element radius along the X axis." );
+SetDefaultParameterInt( "structype.ball.xradius" , 5 );
+AddParameter( ParameterType_Int , "structype.ball.yradius" ,
+ "Structuring element Y radiuss" );
+SetParameterDescription( "structype.ball.yradius" , 
+  "The structuring element radius along the y axis." );
+SetDefaultParameterInt( "structype.ball.yradius" , 5 );
 //Cross
-AddChoice("structype.cross", "Cross");
+AddChoice( "structype.cross" , "Cross" );
 
 AddParameter(ParameterType_Choice, "filter", "Morphological Operation");
 SetParameterDescription("filter", "Choice of the morphological operation");
 //Dilate
-AddChoice("filter.dilate", "Dilate");
-AddParameter(ParameterType_Float, "filter.dilate.foreval", "Foreground Value");
-SetParameterDescription("filter.dilate.foreval", "The Foreground Value");
-SetDefaultParameterFloat("filter.dilate.foreval", 1.0);
-AddParameter(ParameterType_Float, "filter.dilate.backval", "Background Value");
-SetParameterDescription("filter.dilate.backval", "The Background Value");
-SetDefaultParameterFloat("filter.dilate.backval", 0.0);
+AddChoice( "filter.dilate" , "Dilate" );
+AddParameter( ParameterType_Float , "filter.dilate.foreval" ,
+ "Foreground value" );
+SetParameterDescription( "filter.dilate.foreval" , 
+  "Set the foreground value, default is 1.0." );
+SetDefaultParameterFloat( "filter.dilate.foreval" , 1.0 );
+AddParameter( ParameterType_Float , "filter.dilate.backval" ,
+ "Background value" );
+SetParameterDescription( "filter.dilate.backval" , 
+  "Set the background value, default is 0.0." );
+SetDefaultParameterFloat( "filter.dilate.backval" , 0.0 );
 
 //Erode
-AddChoice("filter.erode", "Erode");
-AddParameter(ParameterType_Float, "filter.erode.foreval", "Foreground Value");
-SetParameterDescription("filter.erode.foreval", "The Foreground Value");
-SetDefaultParameterFloat("filter.erode.foreval", 1.0);
-AddParameter(ParameterType_Float, "filter.erode.backval", "Background Value");
-SetParameterDescription("filter.erode.backval", "The Background Value");
+AddChoice( "filter.erode" , "Erode" );
+AddParameter( ParameterType_Float , "filter.erode.foreval" , 
+  "Foreground value" );
+SetParameterDescription( "filter.erode.foreval" , 
+  "Set the foreground value, default is 1.0." );
+SetDefaultParameterFloat( "filter.erode.foreval" , 1.0 );
+AddParameter( ParameterType_Float , "filter.erode.backval" , 
+   "Background value" );
+SetParameterDescription("filter.erode.backval", 
+  "Set the background value, default is 0.0." );
 SetDefaultParameterFloat("filter.erode.backval", 0.0);
+
 //Opening
-AddChoice("filter.opening", "Opening");
-AddParameter(ParameterType_Float, "filter.opening.foreval", "Foreground Value");
-SetParameterDescription("filter.opening.foreval", "The Foreground Value");
+AddChoice( "filter.opening" , "Opening" );
+AddParameter( ParameterType_Float , "filter.opening.foreval" ,
+  "Foreground value" );
+SetParameterDescription( "filter.opening.foreval" , 
+  "Set the foreground value, default is 1.0." );
 SetDefaultParameterFloat("filter.opening.foreval", 1.0);
-AddParameter(ParameterType_Float, "filter.opening.backval", "Background Value");
-SetParameterDescription("filter.opening.backval", "The Background Value");
-SetDefaultParameterFloat("filter.opening.backval", 0.0);
+AddParameter( ParameterType_Float , "filter.opening.backval" ,
+  "Background value" );
+SetParameterDescription( "filter.opening.backval" , 
+  "Set the background value, default is 0.0." );
+SetDefaultParameterFloat( "filter.opening.backval" , 0.0 );
 //Closing
-AddChoice("filter.closing", "Closing");
-AddParameter(ParameterType_Float, "filter.closing.foreval", "Foreground Value");
-SetParameterDescription("filter.closing.foreval", "The Foreground Value");
-SetDefaultParameterFloat("filter.closing.foreval", 1.0);
+AddChoice( "filter.closing" , "Closing" );
+AddParameter( ParameterType_Float , "filter.closing.foreval" ,
+  "Foreground value" );
+SetParameterDescription( "filter.closing.foreval" , 
+  "Set the foreground value, default is 1.0." );
+SetDefaultParameterFloat( "filter.closing.foreval" , 1.0 );
 
 // Doc example parameter settings
 SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
diff --git a/Modules/Applications/AppMorphology/app/otbGrayScaleMorphologicalOperation.cxx b/Modules/Applications/AppMorphology/app/otbGrayScaleMorphologicalOperation.cxx
index b9d26d0..e35aad5 100644
--- a/Modules/Applications/AppMorphology/app/otbGrayScaleMorphologicalOperation.cxx
+++ b/Modules/Applications/AppMorphology/app/otbGrayScaleMorphologicalOperation.cxx
@@ -34,8 +34,6 @@
 #include "otbImageList.h"
 #include "otbImageListToVectorImageFilter.h"
 
-#include "itkTimeProbe.h"
-
 namespace otb
 {
 namespace Wrapper
diff --git a/Modules/Applications/AppMorphology/app/otbMorphologicalClassification.cxx b/Modules/Applications/AppMorphology/app/otbMorphologicalClassification.cxx
index 3e6d338..a117a2f 100644
--- a/Modules/Applications/AppMorphology/app/otbMorphologicalClassification.cxx
+++ b/Modules/Applications/AppMorphology/app/otbMorphologicalClassification.cxx
@@ -35,7 +35,6 @@
 #include "otbImageList.h"
 #include "otbImageListToVectorImageFilter.h"
 
-#include "itkTimeProbe.h"
 #include "otbConvexOrConcaveClassificationFilter.h"
 #include "otbMorphologicalProfilesSegmentationFilter.h"
 
@@ -74,64 +73,75 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName( "MorphologicalClassification" );
-    SetDescription( "Performs morphological convex, concave and flat classification on an input image channel" );
+    SetDescription( "Performs morphological convex, concave and flat "
+      "classification on an input image channel" );
 
     // Documentation
     SetDocName( "Morphological Classification" );
-    SetDocLongDescription( "This algorithm is based on the following publication:\n"
-                                   "\n"
-                                   "Martino Pesaresi and Jon Alti Benediktsson, Member, IEEE: A new approach\n"
-                                   "for the morphological segmentation of high resolution satellite imagery.\n"
-                                   "IEEE Transactions on geoscience and remote sensing, vol. 39, NO. 2,\n"
-                                   "February 2001, p. 309-320.\n"
-                                   "\n"
-                                   "This application perform the following decision rule to classify a pixel\n"
-                                   "between the three classes Convex, Concave and Flat. Let :math:`f` denote\n"
-                                   "the input image and :math:`\\psi_{N}(f)` the geodesic leveling of\n"
-                                   ":math:`f` with a structuring element of size :math:`N`. One can derive\n"
-                                   "the following decision rule to classify :math:`f` into Convex (label\n"
-                                   ":math:`\\stackrel{\\smile}{k}`), Concave (label\n"
-                                   ":math:`\\stackrel{\\frown}{k}`) and Flat (label :math:`\\bar{k}`): \n"
-                                   "\n"
-                                   ":math:`f(n) = \\begin{cases} \\stackrel{\\smile}{k} & : f-\\psi_{N}(f)>\\sigma \\\\ \\stackrel{\\frown}{k} & : \\psi_{N}(f)-f>\\sigma \\\\ \\bar{k} & : \\mid f - \\psi_{N}(f) \\mid \\leq \\sigma \\end{cases}`"
-                                   "\n\n"
-                                   "This output is a labeled image (0 : Flat, 1 : Convex, 2 : Concave)" );
-    SetDocLimitations( "Generation of the morphological classification is not streamable, pay attention to this fact when setting the radius size of the structuring element." );
+    SetDocLongDescription( 
+    "This algorithm is based on the following publication:\n"
+    "Martino Pesaresi and Jon Alti Benediktsson, Member, IEEE: A new approach "
+    "for the morphological segmentation of high resolution satellite imagery.\n"
+    "IEEE Transactions on geoscience and remote sensing, vol. 39, NO. 2, "
+    "February 2001, p. 309-320.\n"
+    "\n"
+    "This application perform the following decision rule to classify a pixel "
+    "between the three classes Convex, Concave and Flat. Let :math:`f` denote "
+    "the input image and :math:`\\psi_{N}(f)` the geodesic leveling of "
+    ":math:`f` with a structuring element of size :math:`N`. One can derive "
+    "the following decision rule to classify :math:`f` into Convex (label "
+    ":math:`\\stackrel{\\smile}{k}`), Concave (label "
+    ":math:`\\stackrel{\\frown}{k}`) and Flat (label :math:`\\bar{k}`):  "
+    "\n"
+    ":math:`f(n) = \\begin{cases} \\stackrel{\\smile}{k} & : f-\\psi_{N}(f)>\\sigma \\\\ \\stackrel{\\frown}{k} & : \\psi_{N}(f)-f>\\sigma \\\\ \\bar{k} & : \\mid f - \\psi_{N}(f) \\mid \\leq \\sigma \\end{cases}`"
+    "\n\n"
+    "The output is a labeled image (0 : Flat, 1 : Convex, 2 : Concave)" );
+    SetDocLimitations( 
+      "Generation of the morphological classification is not streamable, "
+      "pay attention to this fact when setting the radius size of the "
+      "structuring element." );
     SetDocAuthors( "OTB-Team" );
     SetDocSeeAlso( "otbConvexOrConcaveClassificationFilter class" );
 
-    AddDocTag(Tags::FeatureExtraction);
-    AddDocTag("Morphology");
+    AddDocTag( Tags::FeatureExtraction );
+    AddDocTag( "Morphology" );
 
-    AddParameter( ParameterType_InputImage, "in", "Input Image" );
-    SetParameterDescription( "in", "The input image to be classified." );
+    AddParameter( ParameterType_InputImage , "in" , "Input Image" );
+    SetParameterDescription( "in" , "The input image to be classified." );
 
-    AddParameter( ParameterType_OutputImage, "out", "Output Image" );
+    AddParameter( ParameterType_OutputImage , "out" , "Output Image" );
     SetParameterDescription( "out",
-                             "The output classified image with 3 different values (0 : Flat, 1 : Convex, 2 : Concave)" );
+      "The output classified image with 3 different values (0 : Flat, "
+      "1 : Convex, 2 : Concave)" );
 
-    AddParameter( ParameterType_Int, "channel", "Selected Channel" );
-    SetParameterDescription( "channel", "The selected channel index for input image" );
-    SetDefaultParameterInt( "channel", 1 );
-    SetMinimumParameterIntValue( "channel", 1 );
+    AddParameter( ParameterType_Int , "channel" , "Selected Channel" );
+    SetParameterDescription( "channel" , 
+      "The selected channel index for input image" );
+    SetDefaultParameterInt( "channel" , 1 );
+    SetMinimumParameterIntValue( "channel" , 1 );
 
     AddRAMParameter();
 
     // Structuring Element (Ball | Cross)
-    AddParameter( ParameterType_Choice, "structype", "Structuring Element Type" );
-    SetParameterDescription( "structype", "Choice of the structuring element type" );
-    AddChoice( "structype.ball", "Ball" );
-    AddChoice( "structype.cross", "Cross" );
-
-    AddParameter( ParameterType_Int, "radius", "Radius" );
-    SetParameterDescription( "radius", "Radius of the structuring element (in pixels)" );
-    SetDefaultParameterInt( "radius", 5 );
-    SetMinimumParameterIntValue( "radius", 1 );
-
-    AddParameter( ParameterType_Float, "sigma", "Sigma value for leveling tolerance" );
-    SetParameterDescription( "sigma", "Sigma value for leveling tolerance" );
-    SetDefaultParameterFloat( "sigma", 0.5 );
-    SetMinimumParameterFloatValue( "sigma", 0 );
+    AddParameter( ParameterType_Choice , "structype" ,
+     "Structuring Element Type" );
+    SetParameterDescription( "structype" , 
+      "Choice of the structuring element type" );
+    AddChoice( "structype.ball" , "Ball" );
+    AddChoice( "structype.cross" , "Cross" );
+
+    AddParameter( ParameterType_Int , "radius" , "Radius" );
+    SetParameterDescription( "radius" ,
+      "Radius of the structuring element (in pixels), default value is 5." );
+    SetDefaultParameterInt( "radius" , 5 );
+    SetMinimumParameterIntValue( "radius" , 1 );
+
+    AddParameter( ParameterType_Float , "sigma" , 
+      "Sigma value for leveling tolerance" );
+    SetParameterDescription( "sigma" , 
+      "Sigma value for leveling tolerance, default value is 0.5." );
+    SetDefaultParameterFloat( "sigma" , 0.5 );
+    SetMinimumParameterFloatValue( "sigma" , 0 );
 
     SetDocExampleParameterValue( "in", "ROI_IKO_PAN_LesHalles.tif" );
     SetDocExampleParameterValue( "channel", "1" );
diff --git a/Modules/Applications/AppMorphology/app/otbMorphologicalMultiScaleDecomposition.cxx b/Modules/Applications/AppMorphology/app/otbMorphologicalMultiScaleDecomposition.cxx
index 3cb2b13..fc27fd8 100644
--- a/Modules/Applications/AppMorphology/app/otbMorphologicalMultiScaleDecomposition.cxx
+++ b/Modules/Applications/AppMorphology/app/otbMorphologicalMultiScaleDecomposition.cxx
@@ -35,7 +35,6 @@
 #include "otbImageList.h"
 #include "otbImageListToVectorImageFilter.h"
 
-#include "itkTimeProbe.h"
 #include "otbConvexOrConcaveClassificationFilter.h"
 #include "otbMorphologicalProfilesSegmentationFilter.h"
 #include "otbGeodesicMorphologyIterativeDecompositionImageFilter.h"
diff --git a/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx b/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx
index 79d9464..c314b8d 100644
--- a/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx
+++ b/Modules/Applications/AppMorphology/app/otbMorphologicalProfilesAnalysis.cxx
@@ -36,7 +36,6 @@
 #include "otbImageList.h"
 #include "otbImageListToVectorImageFilter.h"
 
-#include "itkTimeProbe.h"
 #include "otbConvexOrConcaveClassificationFilter.h"
 #include "otbMorphologicalProfilesSegmentationFilter.h"
 #include "otbGeodesicMorphologyIterativeDecompositionImageFilter.h"
diff --git a/Modules/Applications/AppOpticalCalibration/app/CMakeLists.txt b/Modules/Applications/AppOpticalCalibration/app/CMakeLists.txt
index 083697c..736e1fb 100644
--- a/Modules/Applications/AppOpticalCalibration/app/CMakeLists.txt
+++ b/Modules/Applications/AppOpticalCalibration/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppOpticalCalibration_LINK_LIBS
-  ${OTBOpticalCalibration_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-)
-
 otb_create_application(
   NAME           OpticalCalibration
   SOURCES        otbOpticalCalibration.cxx
diff --git a/Modules/Applications/AppProjection/app/CMakeLists.txt b/Modules/Applications/AppProjection/app/CMakeLists.txt
index e072604..059348c 100644
--- a/Modules/Applications/AppProjection/app/CMakeLists.txt
+++ b/Modules/Applications/AppProjection/app/CMakeLists.txt
@@ -18,21 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppProjection_LINK_LIBS
-  ${OTBGdalAdapters_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBTransform_LIBRARIES}
-  ${OTBOSSIMAdapters_LIBRARIES}
-  ${OTBCarto_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBMathParser_LIBRARIES}
-  ${OTBCommon_LIBRARIES}
-  ${OTBGDAL_LIBRARIES}
-  ${OTBInterpolation_LIBRARIES}
-)
-
 otb_create_application(
   NAME           OrthoRectification
   SOURCES        otbOrthoRectification.cxx
diff --git a/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx b/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx
index 1d9642a..dfecb74 100644
--- a/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx
+++ b/Modules/Applications/AppProjection/app/otbConvertCartoToGeoPoint.cxx
@@ -53,11 +53,11 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("ConvertCartoToGeoPoint");
-    SetDescription("Convert cartographic coordinates to geographic one.");
+    SetDescription("Convert cartographic coordinates to geographic ones.");
 
     // Documentation
     SetDocName("Cartographic to geographic coordinates conversion");
-    SetDocLongDescription("This application computes the geographic coordinates from a cartographic one. User has to give the X and Y coordinate and the cartographic projection (UTM/LAMBERT/LAMBERT2/LAMBERT93/SINUS/ECKERT4/TRANSMERCATOR/MOLLWEID/SVY21).");
+    SetDocLongDescription("This application computes the geographic coordinates from cartographic ones. User has to give the X and Y coordinate and the cartographic projection (see mapproj parameter for details).");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
@@ -67,20 +67,20 @@ private:
 
     AddParameter(ParameterType_Group, "carto", "Input cartographic coordinates");
     AddParameter(ParameterType_Float, "carto.x", "X cartographic coordinates");
-    SetParameterDescription("carto.x", "X cartographic coordinates in the specified projection.");
+    SetParameterDescription("carto.x", "X cartographic coordinates in the projection defined by mapproj parameter");
 
     AddParameter(ParameterType_Float, "carto.y", "Y cartographic coordinates");
-    SetParameterDescription("carto.y", "Y cartographic coordinates in the specified projection.");
+    SetParameterDescription("carto.y", "Y cartographic coordinates in the projection defined by mapproj parameter");
 
     // Add the MapProjectionParameters
     MapProjectionParametersHandler::AddMapProjectionParameters(this, "mapproj");
 
     AddParameter(ParameterType_Float, "long", "Output long");
-    SetParameterDescription("long", "Point longitude coordinates.");
+    SetParameterDescription("long", "Point longitude coordinates in decimal degrees.");
     SetParameterRole("long", Role_Output);
 
     AddParameter(ParameterType_Float, "lat", "Output lat");
-    SetParameterDescription("lat", "Point latitude coordinates.");
+    SetParameterDescription("lat", "Point latitude coordinates in decimal degrees.");
     SetParameterRole("lat", Role_Output);
 
     // Doc example parameter settings
diff --git a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
index 2dc6a61..4d3c9cb 100644
--- a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
+++ b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
@@ -91,17 +91,18 @@ private:
   {
     SetName("OrthoRectification");
     std::ostringstream oss;
-    oss << "This application allows ortho-rectification of optical and radar images from supported sensors." << std::endl;
+    oss << "This application allows to ortho-rectify optical and radar images from supported sensors." << std::endl;
     SetDescription(oss.str());
     // Documentation
     SetDocName("Ortho-rectification");
     oss.str("");
-    oss<<"An inverse sensor model is built from the input image metadata to convert geographical to raw geometry coordinates. ";
-    oss<<"This inverse sensor model is then combined with the chosen map projection to build a global coordinate mapping grid. Last, this grid is used to resample using the chosen interpolation algorithm. ";
-    oss<<"A Digital Elevation Model can be specified to account for terrain deformations. "<<std::endl;
+    oss<<"This application uses inverse sensor modelling combined with a choice of interpolation functions to resample a sensor geometry image into a ground geometry regular grid. ";
+    oss<<"The ground geometry regular grid is defined with respect to a map projection (see map parameter). The application offers several modes to estimate the output grid parameters (origin and ground sampling distance), including automatic estimation of image size, ground sampling distance, or both, from image metadata, user-defined ROI corners, or another ortho-image.";
+    oss<<"A digital Elevation Model along with a geoid file can be specified to account for terrain deformations.";
     oss<<"In case of SPOT5 images, the sensor model can be approximated by an RPC model in order to speed-up computation.";
+    
     SetDocLongDescription(oss.str());
-    SetDocLimitations("Supported sensors (both optical and radar) are: GeoEye, Ikonos, Pleiades, Quickbird, RadarSat, Sentinel-1, SPOT5 (TIF format), SPOT6/7, TerraSAR-X, Worldview 1/2/3.");
+    SetDocLimitations("Supported sensors (both optical and radar) are: GeoEye, Ikonos, Pleiades, Quickbird, RadarSat, Sentinel-1, SPOT5 (TIF format), SPOT6/7, TerraSAR-X, Worldview 1/2/3, and any TIF image with embedded RPC tags.\n Also note that the opt.gridspacing default value may not be suitable for all sensors. In particular, if this value is lower than the target ground sampling distance, the processing time may increase a lot. A warning is issued in this case. Typical values shoul [...]
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("Ortho-rectification chapter from the OTB Software Guide");
 
@@ -533,7 +534,7 @@ private:
             FloatVectorImageType::Pointer inOrtho = GetParameterImage("outputs.ortho");
 
             ResampleFilterType::OriginType orig = inOrtho->GetOrigin();
-            ResampleFilterType::SpacingType spacing = inOrtho->GetSpacing();
+            ResampleFilterType::SpacingType spacing = inOrtho->GetSignedSpacing();
             ResampleFilterType::SizeType size = inOrtho->GetLargestPossibleRegion().GetSize();
 
             SetParameterInt("outputs.sizex",size[0]);
diff --git a/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx b/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx
index f1941b5..7b6da7d 100644
--- a/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx
+++ b/Modules/Applications/AppProjection/app/otbRigidTransformResample.cxx
@@ -234,7 +234,7 @@ private:
       scale[1] = 1.0 / GetParameterFloat("transform.type.id.scaley");
 
       // Evaluate spacing
-      FloatVectorImageType::SpacingType spacing = inputImage->GetSpacing();
+      FloatVectorImageType::SpacingType spacing = inputImage->GetSignedSpacing();
       FloatVectorImageType::SpacingType OutputSpacing;
       OutputSpacing[0] = spacing[0] * scale[0];
       OutputSpacing[1] = spacing[1] * scale[1];
@@ -279,7 +279,7 @@ private:
       scale[1] = 1.0 / GetParameterFloat("transform.type.translation.scaley");
 
       // Evaluate spacing
-      FloatVectorImageType::SpacingType spacing = inputImage->GetSpacing();
+      FloatVectorImageType::SpacingType spacing = inputImage->GetSignedSpacing();
       FloatVectorImageType::SpacingType OutputSpacing;
       OutputSpacing[0] = spacing[0] * scale[0];
       OutputSpacing[1] = spacing[1] * scale[1];
@@ -312,7 +312,7 @@ private:
       ScalableTransformType::Pointer transform = ScalableTransformType::New();
 
       FloatVectorImageType::SizeType inSize = inputImage->GetLargestPossibleRegion().GetSize();
-      FloatVectorImageType::SpacingType spacing = inputImage->GetSpacing();
+      FloatVectorImageType::SpacingType spacing = inputImage->GetSignedSpacing();
 
       itk::ContinuousIndex<double,2> ULindex(inputImage->GetLargestPossibleRegion().GetIndex());
       ULindex[0] += -0.5;
diff --git a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx
index 95ed2a5..1d1018e 100644
--- a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx
+++ b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx
@@ -214,7 +214,7 @@ private:
     otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev");
 
     // Set up output image information
-    FloatVectorImageType::SpacingType spacing = refImage->GetSpacing();
+    FloatVectorImageType::SpacingType spacing = refImage->GetSignedSpacing();
     FloatVectorImageType::IndexType   start   = refImage->GetLargestPossibleRegion().GetIndex();
     FloatVectorImageType::SizeType    size    = refImage->GetLargestPossibleRegion().GetSize();
     FloatVectorImageType::PointType   origin  = refImage->GetOrigin();
@@ -278,7 +278,7 @@ private:
       
       m_BasicResampler->SetOutputOrigin(origin);
 
-      FloatVectorImageType::SpacingType xsSpacing = GetParameterImage("inm")->GetSpacing();
+      FloatVectorImageType::SpacingType xsSpacing = GetParameterImage("inm")->GetSignedSpacing();
       xsSpacing*=0.25;
       
       m_BasicResampler->SetOutputSpacing(xsSpacing);
diff --git a/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx b/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx
index 82efac5..fe9e070 100644
--- a/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx
+++ b/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx
@@ -144,7 +144,7 @@ private:
       {
       FloatVectorImageType::Pointer inImage = GetParameterFloatVectorImage("in.kwl");
       m_GeometriesProjFilter->SetInputOrigin(inImage->GetOrigin()); // nec qd capteur
-      m_GeometriesProjFilter->SetInputSpacing(inImage->GetSpacing()); // nec qd capteur
+      m_GeometriesProjFilter->SetInputSpacing(inImage->GetSignedSpacing()); // nec qd capteur
       m_GeometriesProjFilter->SetInputKeywordList(inImage->GetImageKeywordlist());
       //otbAppLogINFO(<<"kwl."<<std::endl);
       }
@@ -156,7 +156,7 @@ private:
       if (outImage)
         {
         m_GeometriesProjFilter->SetOutputOrigin(outImage->GetOrigin()); // nec qd capteur
-        m_GeometriesProjFilter->SetOutputSpacing(outImage->GetSpacing()); // nec qd capteur
+        m_GeometriesProjFilter->SetOutputSpacing(outImage->GetSignedSpacing()); // nec qd capteur
         m_OutputProjectionRef = outImage->GetProjectionRef(); // ~ wkt
         if (m_OutputProjectionRef.empty())
           {
diff --git a/Modules/Applications/AppSARCalibration/app/CMakeLists.txt b/Modules/Applications/AppSARCalibration/app/CMakeLists.txt
index ee25f98..4360104 100644
--- a/Modules/Applications/AppSARCalibration/app/CMakeLists.txt
+++ b/Modules/Applications/AppSARCalibration/app/CMakeLists.txt
@@ -18,11 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppSARCalibration_LINK_LIBS
-  ${OTBSARCalibration_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-)
-
 otb_create_application(
   NAME           SARCalibration
   SOURCES        otbSARCalibration.cxx
diff --git a/Modules/Applications/AppSARDecompositions/app/CMakeLists.txt b/Modules/Applications/AppSARDecompositions/app/CMakeLists.txt
index 10c7ea3..4c34d61 100644
--- a/Modules/Applications/AppSARDecompositions/app/CMakeLists.txt
+++ b/Modules/Applications/AppSARDecompositions/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppFiltering_LINK_LIBS
-  ${OTBPolarimetry_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-)
-
 otb_create_application(
   NAME           SARDecompositions
   SOURCES        otbSARDecompositions.cxx
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/CMakeLists.txt b/Modules/Applications/AppSARPolarMatrixConvert/app/CMakeLists.txt
index dd8715a..e3fd251 100644
--- a/Modules/Applications/AppSARPolarMatrixConvert/app/CMakeLists.txt
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppFiltering_LINK_LIBS
-  ${OTBPolarimetry_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-)
-
 otb_create_application(
   NAME           SARPolarMatrixConvert
   SOURCES        otbSARPolarMatrixConvert.cxx
diff --git a/Modules/Applications/AppSARPolarSynth/app/CMakeLists.txt b/Modules/Applications/AppSARPolarSynth/app/CMakeLists.txt
index 5390d9a..ce4c55e 100644
--- a/Modules/Applications/AppSARPolarSynth/app/CMakeLists.txt
+++ b/Modules/Applications/AppSARPolarSynth/app/CMakeLists.txt
@@ -18,13 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppFiltering_LINK_LIBS
-  ${OTBPolarimetry_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-)
-
 otb_create_application(
   NAME           SARPolarSynth
   SOURCES        otbSARPolarSynth.cxx
diff --git a/Modules/Applications/AppSARUtils/app/CMakeLists.txt b/Modules/Applications/AppSARUtils/app/CMakeLists.txt
index 6f0e019..2c43cc4 100644
--- a/Modules/Applications/AppSARUtils/app/CMakeLists.txt
+++ b/Modules/Applications/AppSARUtils/app/CMakeLists.txt
@@ -1,10 +1,22 @@
-set(OTBAppSARUtils_LINK_LIBS
-  ${OTBSARUtils_LIBRARIES}
-  {OTBImageNoise_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBITK_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-)
+#
+# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+#     https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 
 otb_create_application(
   NAME           ComputeModulusAndPhase
diff --git a/Modules/Applications/AppSegmentation/app/CMakeLists.txt b/Modules/Applications/AppSegmentation/app/CMakeLists.txt
index f55ae3d..b6003d6 100644
--- a/Modules/Applications/AppSegmentation/app/CMakeLists.txt
+++ b/Modules/Applications/AppSegmentation/app/CMakeLists.txt
@@ -18,29 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppSegmentation_LINK_LIBS
-  ${OTBVectorDataBase_LIBRARIES}
-  ${OTBLabelMap_LIBRARIES}
-  ${OTBConversion_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBImageIO_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBWatersheds_LIBRARIES}
-  ${OTBGdalAdapters_LIBRARIES}
-  ${OTBSmoothing_LIBRARIES}
-  ${OTBMetrics_LIBRARIES}
-  ${OTBOGRProcessing_LIBRARIES}
-  ${OTBStatistics_LIBRARIES}
-  ${OTBMeanShift_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBCCOBIA_LIBRARIES}
-  ${OTBMathParser_LIBRARIES}
-  ${OTBMorphologicalProfiles_LIBRARIES}
-  ${OTBTransform_LIBRARIES}
-  ${OTBCommon_LIBRARIES}
-)
-
 otb_create_application(
   NAME           Segmentation
   SOURCES        otbSegmentation.cxx
diff --git a/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx
index c141e8c..b9bc876 100644
--- a/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx
@@ -173,7 +173,7 @@ private:
       m_Vproj->SetInput(m_Connected->GetFilter()->GetOutputVectorData());
       m_Vproj->SetInputKeywordList(inputImage->GetImageKeywordlist());
       //m_Vproj->SetInputOrigin(inputImage->GetOrigin());
-      //m_Vproj->SetInputSpacing(inputImage->GetSpacing());
+      //m_Vproj->SetInputSpacing(inputImage->GetSignedSpacing());
 
       // Setup the DEM Handler
       otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev");
diff --git a/Modules/Applications/AppStereo/app/CMakeLists.txt b/Modules/Applications/AppStereo/app/CMakeLists.txt
index 3bcccff..8fc636a 100644
--- a/Modules/Applications/AppStereo/app/CMakeLists.txt
+++ b/Modules/Applications/AppStereo/app/CMakeLists.txt
@@ -18,21 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppStereo_LINK_LIBS
-  ${OTBStereo_LIBRARIES}
-  ${OTBStatistics_LIBRARIES}
-  ${OTBImageIO_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBInterpolation_LIBRARIES}
-  ${OTBTransform_LIBRARIES}
-  ${OTBDisplacementField_LIBRARIES}
-  ${OTBDisparityMap_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-  ${OTBMathParser_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-)
-
 otb_create_application(
   NAME           StereoFramework
   SOURCES        otbStereoFramework.cxx
diff --git a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
index 312cff6..279c09a 100644
--- a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
+++ b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx
@@ -313,47 +313,66 @@ private:
 
   void DoInit() ITK_OVERRIDE
   {
+    // TODO : implement this application as a CompositeApplication...
     SetName("StereoFramework");
     SetDescription("Compute the ground elevation based on one or multiple stereo pair(s)");
 
     SetDocName("Stereo Framework");
-    SetDocLongDescription("Compute the ground elevation with a stereo block matching algorithm "
-                          "between one or multiple stereo pair in sensor geometry. The output is projected in "
-                          "desired geographic or cartographic map projection (UTM by default). The pipeline is made of the following steps:\n"
-                          "for each sensor pair :\n\n"
-                          "\t- compute the epipolar displacement grids from the stereo pair (direct and inverse)\n"
-                          "\t- resample the stereo pair into epipolar geometry using BCO interpolation\n"
-                          "\t- create masks for each epipolar image : remove black borders and resample"
-                          " input masks\n"
-                          "\t- compute horizontal disparities with a block matching algorithm\n"
-                          "\t- refine disparities to sub-pixel precision with a dichotomy algorithm\n"
-                          "\t- apply an optional median filter\n"
-                          "\t- filter disparities based on the correlation score  and exploration bounds\n"
-                          "\t- translate disparities in sensor geometry\n"
-                          "\t  convert disparity to 3D Map.\n\n"
-                          "Then fuse all 3D maps to produce DSM.");
+    SetDocLongDescription(
+      "Compute the ground elevation with a stereo block matching algorithm "
+      "between one or multiple stereo pair in sensor geometry. The output is "
+      "projected in desired geographic or cartographic map projection (WGS84 by"
+      " default).\n\n"
+      "This application is chaining different processing steps. Some of them "
+      "are also performed by other applications in the stereo-reconstruction "
+      "framework:\n"
+      "  * StereoRectificationGridGenerator [1] : for the generation of deformation grids\n"
+      "  * GridBasedImageResampling [2] : resampling into epipolar geometry\n"
+      "  * BlockMatching [3] : estimation of dense disparity maps\n\n"
+      "The pipeline executes the following steps on each stereo pair:\n"
+      "  - compute the epipolar displacement grids from the stereo pair (direct and inverse)\n"
+      "  - resample the stereo pair into epipolar geometry using BCO interpolation\n"
+      "  - create masks for each epipolar image : remove black borders and resample"
+      " input masks\n"
+      "  - compute horizontal disparities with a block matching algorithm\n"
+      "  - refine disparities to sub-pixel precision with a dichotomy algorithm\n"
+      "  - apply an optional median filter\n"
+      "  - filter disparities based on the correlation score and exploration bounds\n"
+      "  - translate disparities in sensor geometry\n"
+      "  - convert disparity to 3D Map.\n\n"
+      "Then all 3D maps are fused to produce DSM. The fusion method in each "
+      "DEM cell can be chosen between maximum, minimum and average.");
     SetDocLimitations(" ");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+    SetDocSeeAlso("[1] StereoRectificationGridGenerator\n"
+      "[2] GridBasedImageResampling\n"
+      "[3] BlockMatching");
 
     AddDocTag(Tags::Stereo);
 
     // Add the output parameters in a group
     AddParameter(ParameterType_Group, "input", "Input parameters");
-    SetParameterDescription("input","This group of parameters allows one to parametrize input data.");
+    SetParameterDescription("input","This group of parameters allows one to set input data.");
 
-    AddParameter(ParameterType_InputImageList,  "input.il",   "Input images list");
-    SetParameterDescription("input.il", "The list of images.");
+    AddParameter(ParameterType_InputImageList, "input.il", "Input images list");
+    SetParameterDescription("input.il", "List of images corresponding to "
+      "multiple views on a single scene, in sensor geometry.");
 
     AddParameter(ParameterType_String, "input.co", "Couples list");
-    SetParameterDescription("input.co","List of index of couples im image list. Couples must be separated by a comma. (index start at 0). for example : 0 1,1 2 will process a first couple composed of the first and the second image in image list, then the first and the third image\n. note that images are handled by pairs."
-        " if left empty couples are created from input index i.e. a first couple will be composed of the first and second image, a second couple with third and fourth image etc. (in this case image list must be even).");
+    SetParameterDescription("input.co","List of index of couples im image list."
+      " Couples must be separated by a comma (index start at 0). For example :"
+      " 0 1,1 2 will process a first couple composed of the first and the"
+      " second image in image list, then the second and the third image\n. "
+      "Note that images are handled by pairs. If left empty, couples are "
+      "created from input index i.e. a first couple will be composed of the "
+      "first and second image, a second couple with third and fourth image etc."
+      " (in this case image list must be even).");
     MandatoryOff("input.co");
     SetParameterString("input.co","", false);
     DisableParameter("input.co");
 
-    AddParameter(ParameterType_Int,  "input.channel",   "Image channel used for the block matching");
-    SetParameterDescription("input.channel", "Used channel for block matching (used for all images)");
+    AddParameter(ParameterType_Int, "input.channel", "Input Image channel");
+    SetParameterDescription("input.channel", "Channel used for block matching (the same for all images)");
     SetDefaultParameterInt("input.channel", 1);
     SetMinimumParameterIntValue("input.channel", 1);
 
@@ -380,10 +399,18 @@ private:
     // UserDefined values
     AddParameter(ParameterType_Choice, "output.fusionmethod", "Method to fuse measures in each DSM cell");
     SetParameterDescription("output.fusionmethod","This parameter allows one to choose the method used to fuse elevation measurements in each output DSM cell");
-    AddChoice("output.fusionmethod.max", "The cell is filled with the maximum measured elevation values");
-    AddChoice("output.fusionmethod.min", "The cell is filled with the minimum measured elevation values");
-    AddChoice("output.fusionmethod.mean","The cell is filled with the mean of measured elevation values");
-    AddChoice("output.fusionmethod.acc", "accumulator mode. The cell is filled with the the number of values (for debugging purposes).");
+    AddChoice("output.fusionmethod.max", "Maximum");
+    SetParameterDescription("output.fusionmethod.max","The cell is filled with"
+      " the maximum measured elevation values");
+    AddChoice("output.fusionmethod.min", "Minimum");
+    SetParameterDescription("output.fusionmethod.min", "The cell is filled with"
+      " the minimum measured elevation values");
+    AddChoice("output.fusionmethod.mean","Mean");
+    SetParameterDescription("output.fusionmethod.mean","The cell is filled with"
+      " the mean of measured elevation values");
+    AddChoice("output.fusionmethod.acc", "Accumulator");
+    SetParameterDescription("output.fusionmethod.acc", "Accumulator mode. The"
+      " cell is filled with the the number of values (for debugging purposes).");
 
     AddParameter(ParameterType_OutputImage,"output.out","Output DSM");
     SetParameterDescription("output.out","Output elevation image");
@@ -396,55 +423,76 @@ private:
     SetParameterDescription("output.mode.user","This mode allows you to fully modify default values.");
     // Upper left point coordinates
     AddParameter(ParameterType_Float, "output.mode.user.ulx", "Upper Left X ");
-    SetParameterDescription("output.mode.user.ulx","Cartographic X coordinate of upper-left corner (meters for cartographic projections, degrees for geographic ones)");
+    SetParameterDescription("output.mode.user.ulx","Cartographic X coordinate "
+      "of upper-left corner (meters for cartographic projections, degrees for"
+      " geographic ones)");
 
     AddParameter(ParameterType_Float, "output.mode.user.uly", "Upper Left Y ");
-    SetParameterDescription("output.mode.user.uly","Cartographic Y coordinate of the upper-left corner (meters for cartographic projections, degrees for geographic ones)");
+    SetParameterDescription("output.mode.user.uly","Cartographic Y coordinate "
+      "of the upper-left corner (meters for cartographic projections, degrees "
+      "for geographic ones)");
 
     // Size of the output image
     AddParameter(ParameterType_Int, "output.mode.user.sizex", "Size X ");
-    SetParameterDescription("output.mode.user.sizex","Size of projected image along X (in pixels)");
+    SetParameterDescription("output.mode.user.sizex","Size of projected image"
+      " along X (in pixels)");
 
     AddParameter(ParameterType_Int, "output.mode.user.sizey", "Size Y ");
-    SetParameterDescription("output.mode.user.sizey","Size of projected image along Y (in pixels)");
+    SetParameterDescription("output.mode.user.sizey","Size of projected image"
+      " along Y (in pixels)");
 
     // Spacing of the output image
     AddParameter(ParameterType_Float, "output.mode.user.spacingx", "Pixel Size X ");
-    SetParameterDescription("output.mode.user.spacingx","Size of each pixel along X axis (meters for cartographic projections, degrees for geographic ones)");
+    SetParameterDescription("output.mode.user.spacingx","Size of each pixel "
+      "along X axis (meters for cartographic projections, degrees for geographic ones)");
 
 
     AddParameter(ParameterType_Float, "output.mode.user.spacingy", "Pixel Size Y ");
-    SetParameterDescription("output.mode.user.spacingy","Size of each pixel along Y axis (meters for cartographic projections, degrees for geographic ones)");
+    SetParameterDescription("output.mode.user.spacingy","Size of each pixel "
+      "along Y axis (meters for cartographic projections, degrees for geographic ones)");
 
     // Add the output parameters in a group
     AddParameter(ParameterType_Group, "stereorect", "Stereorectification Grid parameters");
-    SetParameterDescription("stereorect","This group of parameters allows one to choose direct and inverse grid subsampling. These parameters are very useful to tune time and memory consumption.");
+    SetParameterDescription("stereorect","This group of parameters allows one "
+      "to choose direct and inverse grid subsampling. These parameters are very"
+      " useful to tune time and memory consumption.");
 
     AddParameter(ParameterType_Int,"stereorect.fwdgridstep","Step of the displacement grid (in pixels)");
-    SetParameterDescription("stereorect.fwdgridstep","Stereo-rectification displacement grid only varies slowly. Therefore, it is recommended to use a coarser grid (higher step value) in case of large images");
+    SetParameterDescription("stereorect.fwdgridstep","Stereo-rectification "
+      "displacement grid only varies slowly. Therefore, it is recommended to "
+      "use a coarser grid (higher step value) in case of large images");
     SetDefaultParameterInt("stereorect.fwdgridstep",16);
     MandatoryOff("stereorect.fwdgridstep");
 
     AddParameter(ParameterType_Int, "stereorect.invgridssrate", "Sub-sampling rate for epipolar grid inversion");
-    SetParameterDescription("stereorect.invgridssrate","Grid inversion is an heavy process that implies spline regression on control points. To avoid eating to much memory, this parameter allows one to first sub-sample the field to invert.");
+    SetParameterDescription("stereorect.invgridssrate","Grid inversion is an "
+      "heavy process that implies spline regression on control points. To avoid"
+      " eating to much memory, this parameter allows one to first sub-sample "
+      "the field to invert.");
     SetDefaultParameterInt("stereorect.invgridssrate",10);
     SetMinimumParameterIntValue("stereorect.invgridssrate",1);
     MandatoryOff("stereorect.invgridssrate");
 
     AddParameter(ParameterType_Group,"bm","Block matching parameters");
-    SetParameterDescription("bm","This group of parameters allow tuning the block-matching behavior");
+    SetParameterDescription("bm","This group of parameters allow tuning the "
+      "block-matching behavior");
 
     AddParameter(ParameterType_Choice,   "bm.metric", "Block-matching metric");
+    SetParameterDescription("bm.metric", "Metric used to compute matching score");
     //SetDefaultParameterInt("bm.metric",3);
 
     AddChoice("bm.metric.ssdmean","Sum of Squared Distances divided by mean of block");
-    SetParameterDescription("bm.metric.ssdmean","derived version of Sum of Squared Distances between pixels value in the metric window (SSD divided by mean over window)");
+    SetParameterDescription("bm.metric.ssdmean","derived version of Sum of "
+      "Squared Distances between pixels value in the metric window (SSD divided"
+      " by mean over window)");
 
     AddChoice("bm.metric.ssd","Sum of Squared Distances");
-    SetParameterDescription("bm.metric.ssd","Sum of squared distances between pixels value in the metric window");
+    SetParameterDescription("bm.metric.ssd","Sum of squared distances between "
+      "pixels value in the metric window");
 
     AddChoice("bm.metric.ncc","Normalized Cross-Correlation");
-    SetParameterDescription("bm.metric.ncc","Normalized Cross-Correlation between the left and right windows");
+    SetParameterDescription("bm.metric.ncc","Normalized Cross-Correlation "
+      "between the left and right windows");
 
     AddChoice("bm.metric.lp","Lp pseudo-norm");
     SetParameterDescription("bm.metric.lp","Lp pseudo-norm between the left and right windows");
@@ -454,20 +502,22 @@ private:
     SetDefaultParameterFloat("bm.metric.lp.p", 1.0);
     SetMinimumParameterFloatValue("bm.metric.lp.p", 0.0);
 
-    AddParameter(ParameterType_Int,"bm.radius","Radius of blocks for matching filter (in pixels)");
+    AddParameter(ParameterType_Int,"bm.radius","Correlation window radius (in pixels)");
     SetParameterDescription("bm.radius","The radius of blocks in Block-Matching (in pixels)");
     SetDefaultParameterInt("bm.radius",2);
     SetMinimumParameterIntValue("bm.radius",1);
     MandatoryOff("bm.radius");
 
     AddParameter(ParameterType_Float,"bm.minhoffset","Minimum altitude offset (in meters)");
-    SetParameterDescription("bm.minhoffset","Minimum altitude below the selected elevation source (in meters)");
+    SetParameterDescription("bm.minhoffset","Minimum altitude below the "
+      "selected elevation source (in meters)");
     //MandatoryOff("bm.minhoffset");
     SetDefaultParameterFloat("bm.minhoffset",-20.0);
     DisableParameter("bm.minhoffset");
 
     AddParameter(ParameterType_Float,"bm.maxhoffset","Maximum altitude offset (in meters)");
-    SetParameterDescription("bm.maxhoffset","Maximum altitude above the selected elevation source (in meters)");
+    SetParameterDescription("bm.maxhoffset","Maximum altitude above the "
+      "selected elevation source (in meters)");
     //MandatoryOff("bm.maxhoffset");
     SetDefaultParameterFloat("bm.maxhoffset",20.0);
     DisableParameter("bm.maxhoffset");
@@ -475,19 +525,25 @@ private:
     AddParameter(ParameterType_Group,"postproc","Postprocessing parameters");
     SetParameterDescription("postproc","This group of parameters allow use optional filters.");
 
-    AddParameter(ParameterType_Empty,"postproc.bij","Use bijection consistency in block matching strategy");
-    SetParameterDescription("postproc.bij","use bijection consistency. Right to Left correlation is computed to validate Left to Right disparities. If bijection is not found pixel is rejected.");
+    AddParameter(ParameterType_Empty,"postproc.bij","Use bijection consistency"
+      " in block matching strategy");
+    SetParameterDescription("postproc.bij","Use bijection consistency. "
+      "Right to Left correlation is computed to validate Left to Right "
+      "disparities. If bijection is not found, the disparity is rejected.");
     MandatoryOff("postproc.bij");
     EnableParameter("postproc.bij");
 
     AddParameter(ParameterType_Empty,"postproc.med","Use median disparities filtering");
-    SetParameterDescription("postproc.med","disparities output can be filtered using median post filtering (disabled by default).");
+    SetParameterDescription("postproc.med","Disparity map can be filtered using"
+      " median post filtering (disabled by default).");
     MandatoryOff("postproc.med");
     DisableParameter("postproc.med");
 
 
     AddParameter(ParameterType_Float,"postproc.metrict","Correlation metric threshold");
-    SetParameterDescription("postproc.metrict","Use block matching metric output to discard pixels with low correlation value (disabled by default, float value)");
+    SetParameterDescription("postproc.metrict","Use block matching metric "
+      "output to discard pixels with low correlation value (disabled by "
+      "default, float value)");
     MandatoryOff("postproc.metrict");
     SetDefaultParameterFloat("postproc.metrict",0.6);
     DisableParameter("postproc.metrict");
@@ -495,24 +551,28 @@ private:
     AddParameter(ParameterType_Group,"mask","Masks");
 
     AddParameter(ParameterType_InputImage, "mask.left","Input left mask");
-    SetParameterDescription("mask.left","Mask for left input image");
+    SetParameterDescription("mask.left","Mask for left input image. Pixel with"
+      " a null mask value are discarded.");
     MandatoryOff("mask.left");
     DisableParameter("mask.left");
 
     AddParameter(ParameterType_InputImage, "mask.right","Input right mask");
-    SetParameterDescription("mask.right","Mask for right input image");
+    SetParameterDescription("mask.right","Mask for right input image. Pixel "
+      "with a null mask value are discarded.");
     MandatoryOff("mask.right");
     DisableParameter("mask.right");
 
-    AddParameter(ParameterType_Float,"mask.variancet","Discard pixels with low local variance");
-    SetParameterDescription("mask.variancet","This parameter allows one to discard pixels whose local variance is too small (the size of the neighborhood is given by the radius parameter)");
+    AddParameter(ParameterType_Float,"mask.variancet","Discard pixels with low"
+      " local variance");
+    SetParameterDescription("mask.variancet","This parameter allows one to "
+      "discard pixels whose local variance is too small (the size of the "
+      "neighborhood is given by the correlation window radius)");
     MandatoryOff("mask.variancet");
     SetDefaultParameterFloat("mask.variancet",50.);
     //DisableParameter("mask.variancet");
 
     AddRAMParameter();
 
-
     SetDocExampleParameterValue("input.il","sensor_stereo_left.tif sensor_stereo_right.tif");
     SetDocExampleParameterValue("elev.default","200");
     SetDocExampleParameterValue("stereorect.fwdgridstep", "8");
@@ -688,8 +748,8 @@ private:
       epipolarGridSource->Update();
 
       FloatImageType::SpacingType epiSpacing;
-      epiSpacing[0] = 0.5 * (vcl_abs(inleft->GetSpacing()[0]) + vcl_abs(inleft->GetSpacing()[1]));
-      epiSpacing[1] = 0.5 * (vcl_abs(inleft->GetSpacing()[0]) + vcl_abs(inleft->GetSpacing()[1]));
+      epiSpacing[0] = 0.5 * (vcl_abs(inleft->GetSignedSpacing()[0]) + vcl_abs(inleft->GetSignedSpacing()[1]));
+      epiSpacing[1] = 0.5 * (vcl_abs(inleft->GetSignedSpacing()[0]) + vcl_abs(inleft->GetSignedSpacing()[1]));
 
       FloatImageType::SizeType epiSize;
       epiSize = epipolarGridSource->GetRectifiedImageSize();
@@ -721,7 +781,7 @@ private:
       leftInverseDisplacementFieldFilter->SetInput(leftDisplacement);
 
       FloatVectorImageType::PointType lorigin = inleft->GetOrigin();
-      FloatVectorImageType::SpacingType lspacing = inleft->GetSpacing();
+      FloatVectorImageType::SpacingType lspacing = inleft->GetSignedSpacing();
       FloatVectorImageType::SizeType lsize = inleft->GetLargestPossibleRegion().GetSize();
       double gridStep = epipolarGridSource->GetGridStep();
       lspacing[0] *= gridStep;
diff --git a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
index ed0d0fd..616594a 100644
--- a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
+++ b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
@@ -102,11 +102,28 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("StereoRectificationGridGenerator");
-    SetDescription("Generates two deformation fields to stereo-rectify (i.e. resample in epipolar geometry) a pair of stereo images up to the sensor model precision");
+    SetDescription("Generates two deformation fields to resample in epipolar "
+      "geometry, a pair of stereo images up to the sensor model precision");
 
     SetDocName("Stereo-rectification deformation grid generator");
-    SetDocLongDescription("This application generates a pair of deformation grid to stereo-rectify a pair of stereo images according to sensor modelling and a mean elevation hypothesis. The deformation grids can be passed to the GridBasedImageResampling application for actual resampling in epipolar geometry.");
-    SetDocLimitations("Generation of the deformation grid is not streamable, pay attention to this fact when setting the grid step.");
+    SetDocLongDescription("This application generates a pair of deformation "
+      "grid to stereo-rectify a pair of stereo images according to sensor "
+      "modelling and a mean elevation hypothesis.\n\n"
+      "This application is the first part of the stereo reconstruction "
+      "framework. The output deformation grids can be passed to the "
+      "GridBasedImageResampling application for actual resampling into epipolar"
+      " geometry.\n\n"
+      "There are several ways to set the elevation source:\n"
+      "  * An arbitrary constant elevation\n"
+      "  * A DEM directory\n"
+      "  * Compute an average elevation from a DEM\n\n"
+      "If needed, the application can compute inverse resampling grids (from "
+      "epipolar to original sensor geometry). Don't forget to check the other "
+      "outputs from the application. For instance, the application gives the "
+      "X and Y size of the rectified images, along with an estimated baseline "
+      "ratio.");
+    SetDocLimitations("Generation of the deformation grid is not streamable, "
+      "pay attention to this fact when setting the grid step.");
     SetDocAuthors("OTB-Team");
 
     AddDocTag(Tags::Stereo);
@@ -116,16 +133,20 @@ private:
     AddParameter(ParameterType_Group,"io","Input and output data");
     SetParameterDescription("io","This group of parameters allows setting the input and output images.");
     AddParameter(ParameterType_InputImage,"io.inleft","Left input image");
-    SetParameterDescription("io.inleft","The left input image to resample");
+    SetParameterDescription("io.inleft","The left image from the stereo pair,"
+      " in sensor geometry.");
 
     AddParameter(ParameterType_InputImage,"io.inright","Right input image");
-    SetParameterDescription("io.inright","The right input image to resample");
+    SetParameterDescription("io.inright","The right image from the stereo pair,"
+      " in sensor geometry.");
 
     AddParameter(ParameterType_OutputImage, "io.outleft", "Left output deformation grid");
-    SetParameterDescription("io.outleft","The output deformation grid to be used to resample the left input image");
+    SetParameterDescription("io.outleft","The deformation grid to resample the"
+      " left image from sensor geometry to epipolar geometry.");
 
     AddParameter(ParameterType_OutputImage, "io.outright", "Right output deformation grid");
-    SetParameterDescription("io.outright","The output deformation grid to be used to resample the right input image");
+    SetParameterDescription("io.outright","The deformation grid to resample the"
+      " right image from sensor geometry to epipolar geometry.");
 
     AddParameter(ParameterType_Group,"epi","Epipolar  geometry and grid parameters");
     SetParameterDescription("epi","Parameters of the epipolar geometry and output grids");
@@ -148,48 +169,73 @@ private:
     DisableParameter("epi.elevation.avgdem.value");
 
     AddParameter(ParameterType_Float,"epi.elevation.avgdem.mindisp","Minimum disparity from DEM");
-    SetParameterDescription("epi.elevation.avgdem.mindisp","Disparity corresponding to estimated minimum elevation over the left image");
+    SetParameterDescription("epi.elevation.avgdem.mindisp","Disparity "
+      "corresponding to estimated minimum elevation over the left image");
     SetParameterRole("epi.elevation.avgdem.mindisp",Role_Output);
     DisableParameter("epi.elevation.avgdem.mindisp");
 
     AddParameter(ParameterType_Float,"epi.elevation.avgdem.maxdisp","Maximum disparity from DEM");
-    SetParameterDescription("epi.elevation.avgdem.maxdisp","Disparity corresponding to estimated maximum elevation over the left image");
+    SetParameterDescription("epi.elevation.avgdem.maxdisp","Disparity "
+      "corresponding to estimated maximum elevation over the left image");
     SetParameterRole("epi.elevation.avgdem.maxdisp",Role_Output);
     DisableParameter("epi.elevation.avgdem.maxdisp");
 
     AddParameter(ParameterType_Float,"epi.scale","Scale of epipolar images");
-    SetParameterDescription("epi.scale","The scale parameter allows generating zoomed-in (scale < 1) or zoomed-out (scale > 1) epipolar images.");
+    SetParameterDescription("epi.scale","The scale parameter allows generating"
+      " zoomed-in (scale < 1) or zoomed-out (scale > 1) epipolar images.");
     SetDefaultParameterFloat("epi.scale",1.);
 
     AddParameter(ParameterType_Int,"epi.step","Step of the deformation grid (in nb. of pixels)");
-    SetParameterDescription("epi.step","Stereo-rectification deformation grid only varies slowly. Therefore, it is recommended to use a coarser grid (higher step value) in case of large images");
+    SetParameterDescription("epi.step","Stereo-rectification deformation grid "
+      "only varies slowly. Therefore, it is recommended to use a coarser grid "
+      "(higher step value) in case of large images");
     SetDefaultParameterInt("epi.step",1);
 
     AddParameter(ParameterType_Int,"epi.rectsizex","Rectified image size X");
-    SetParameterDescription("epi.rectsizex","The application computes the optimal rectified image size so that the whole left input image fits into the rectified area. However, due to the scale and step parameter, this size may not match the size of the deformation field output. In this case, one can use these output values.");
+    SetParameterDescription("epi.rectsizex","The application computes the "
+      "optimal rectified image size so that the whole left input image fits "
+      "into the rectified area. However, due to the scale and step parameter, "
+      "this size may not match the size of the deformation field output. In "
+      "this case, one can use these output values.");
     SetParameterRole("epi.rectsizex", Role_Output);
 
     AddParameter(ParameterType_Int,"epi.rectsizey","Rectified image size Y");
-    SetParameterDescription("epi.rectsizey","The application computes the optimal rectified image size so that the whole left input image fits into the rectified area. However, due to the scale and step parameter, this size may not match the size of the deformation field output. In this case, one can use these output values.");
+    SetParameterDescription("epi.rectsizey","The application computes the "
+      "optimal rectified image size so that the whole left input image fits "
+      "into the rectified area. However, due to the scale and step parameter, "
+      "this size may not match the size of the deformation field output. In "
+      "this case, one can use these output values.");
     SetParameterRole("epi.rectsizey", Role_Output);
 
     AddParameter(ParameterType_Float,"epi.baseline","Mean baseline ratio");
-    SetParameterDescription("epi.baseline","This parameter is the mean value, in pixels.meters^-1, of the baseline to sensor altitude ratio. It can be used to convert disparities to physical elevation, since a disparity of one pixel will correspond to an elevation offset of the invert of this value with respect to the mean elevation.");
+    SetParameterDescription("epi.baseline","This parameter is the mean value, "
+      "in pixels.meters^-1, of the baseline to sensor altitude ratio. It can be"
+      " used to convert disparities to physical elevation, since a disparity of"
+      " one pixel will correspond to an elevation offset of the invert of this"
+      " value with respect to the mean elevation.");
     SetParameterRole("epi.baseline", Role_Output);
 
     AddParameter(ParameterType_Group,"inverse","Write inverse fields");
-    SetParameterDescription("inverse","This group of parameter allows generating the inverse fields as well");
+    SetParameterDescription("inverse","This group of parameter allows "
+      "generating the inverse fields as well");
 
     AddParameter(ParameterType_OutputImage, "inverse.outleft", "Left inverse deformation grid");
-    SetParameterDescription("inverse.outleft","The output deformation grid to be used to resample the epipolar left image");
+    SetParameterDescription("inverse.outleft","The deformation grid to resample"
+      " the left image from the epipolar geometry back into its original sensor"
+      " geometry.");
     MandatoryOff("inverse.outleft");
 
     AddParameter(ParameterType_OutputImage, "inverse.outright", "Right inverse deformation grid");
-    SetParameterDescription("inverse.outright","The output deformation grid to be used to resample the epipolar right image");
+    SetParameterDescription("inverse.outright","The output deformation grid to"
+      " resample the right image from the epipolar geometry back into its "
+      "original sensor geometry.");
     MandatoryOff("inverse.outright");
 
     AddParameter(ParameterType_Int, "inverse.ssrate", "Sub-sampling rate for inversion");
-    SetParameterDescription("inverse.ssrate","Grid inversion is an heavy process that implies spline regression on control points. To avoid eating to much memory, this parameter allows one to first sub-sample the field to invert.");
+    SetParameterDescription("inverse.ssrate","Grid inversion is an heavy "
+      "process that implies spline regression on control points. To avoid "
+      "eating to much memory, this parameter allows one to first sub-sample "
+      "the field to invert.");
     SetDefaultParameterInt("inverse.ssrate",16);
     SetMinimumParameterIntValue("inverse.ssrate",1);
 
@@ -229,7 +275,7 @@ private:
       {
       FloatImageType::PointType   origin  = GetParameterImage("io.inleft")->GetOrigin();
       FloatImageType::SizeType    size    = GetParameterImage("io.inleft")->GetLargestPossibleRegion().GetSize();
-      FloatImageType::SpacingType spacing = GetParameterImage("io.inleft")->GetSpacing();
+      FloatImageType::SpacingType spacing = GetParameterImage("io.inleft")->GetSignedSpacing();
 
       size[0]/=GetParameterInt("epi.elevation.avgdem.step");
       size[1]/=GetParameterInt("epi.elevation.avgdem.step");
@@ -289,7 +335,7 @@ private:
       m_LeftInvertDisplacementFieldFilter->SetInput(m_LeftDisplacementFieldCaster->GetOutput());
 
       FloatVectorImageType::PointType lorigin = GetParameterImage("io.inleft")->GetOrigin();
-      FloatVectorImageType::SpacingType lspacing = GetParameterImage("io.inleft")->GetSpacing();
+      FloatVectorImageType::SpacingType lspacing = GetParameterImage("io.inleft")->GetSignedSpacing();
       FloatVectorImageType::SizeType lsize = GetParameterImage("io.inleft")->GetLargestPossibleRegion().GetSize();
 
       if (lsize[0]*lsize[1]>256*256)
@@ -331,7 +377,7 @@ private:
 
       m_RightInvertDisplacementFieldFilter->SetInput(m_RightDisplacementFieldCaster->GetOutput());
       FloatVectorImageType::PointType rorigin = GetParameterImage("io.inright")->GetOrigin();
-      FloatVectorImageType::SpacingType rspacing = GetParameterImage("io.inright")->GetSpacing();
+      FloatVectorImageType::SpacingType rspacing = GetParameterImage("io.inright")->GetSignedSpacing();
       FloatVectorImageType::SizeType rsize = GetParameterImage("io.inright")->GetLargestPossibleRegion().GetSize();
 
       if (rsize[0]*rsize[1]>256*256)
diff --git a/Modules/Applications/AppTest/app/CMakeLists.txt b/Modules/Applications/AppTest/app/CMakeLists.txt
index 6de8cbe..44d54be 100644
--- a/Modules/Applications/AppTest/app/CMakeLists.txt
+++ b/Modules/Applications/AppTest/app/CMakeLists.txt
@@ -18,10 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppTest_LINK_LIBS
-  ${OTBApplicationEngine_LIBRARIES}
-)
-
 otb_create_application(
   NAME           TestApplication
   SOURCES        otbTestApplication.cxx
diff --git a/Modules/Applications/AppTest/app/otbTestApplication.cxx b/Modules/Applications/AppTest/app/otbTestApplication.cxx
index 662529c..a2e9ee9 100644
--- a/Modules/Applications/AppTest/app/otbTestApplication.cxx
+++ b/Modules/Applications/AppTest/app/otbTestApplication.cxx
@@ -20,6 +20,7 @@
 
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
+#include "otbWrapperInputFilenameListParameter.h"
 
 namespace otb
 {
@@ -46,7 +47,6 @@ private:
     SetName("TestApplication");
     SetDescription("This application helps developers to test parameters types");
 
-
     SetDocName("Test");
     SetDocLongDescription("The purpose of this application is to test parameters types.");
     SetDocLimitations("None");
@@ -76,7 +76,6 @@ private:
     AddParameter(ParameterType_Float,  "choice.choice3.floatchoice3", "Float of choice3");
     SetDefaultParameterFloat("choice.choice3.floatchoice3",   5.0);
 
-
     AddParameter(ParameterType_Group, "ingroup", "Input Group");
     MandatoryOff("ingroup");
     AddParameter(ParameterType_Float,  "ingroup.integer", "Integer of Group");
@@ -89,6 +88,15 @@ private:
     AddParameter(ParameterType_InputImageList,  "il",   "Input image list");
     MandatoryOff("il");
 
+    AddParameter( ParameterType_InputFilenameList, "fl", "Input filename list" );
+    MandatoryOff( "fl" );
+
+    AddParameter( ParameterType_InputVectorDataList, "vdl", "Input vector-data list" );
+    MandatoryOff( "vdl" );
+
+    AddParameter( ParameterType_StringList, "sl", "Input string list" );
+    MandatoryOff( "sl" );
+
     AddParameter(ParameterType_ListView,  "cl", "Output Image channels");
     AddChoice("cl.choice1", "Choice1");
     AddChoice("cl.choice2", "Choice2");
@@ -105,19 +113,62 @@ private:
   }
 
   void DoUpdateParameters() ITK_OVERRIDE
+  {}
+
+  void DoExecute() ITK_OVERRIDE
   {
-    //std::cout << "TestApplication::DoUpdateParameters" << std::endl;
+    if( HasValue("il") && IsParameterEnabled("il") )
+      {
+      FloatVectorImageListType * imgList = GetParameterImageList( "il" );
+      SetParameterOutputImage(
+        "outgroup.outputimage",
+        imgList->GetNthElement( 0 )
+      );
+      }
+    else if (HasValue("ingroup.images.inputimage") && IsParameterEnabled("ingroup") )
+      {
+      SetParameterOutputImage("outgroup.outputimage",
+        GetParameterImage("ingroup.images.inputimage"));
+      }
+    else
+      {
+      otbAppLogFATAL("Waiting at least one input image");
+      }
+
+    SetParameterComplexOutputImage(
+      "cout",
+      GetParameterComplexImage( "cin" )
+    );
+
+    PrintStrings( "fl" );
   }
 
-  void DoExecute() ITK_OVERRIDE
+private:
+  void PrintStrings( const std::string & key ) const
   {
-    FloatVectorImageListType* imgList = GetParameterImageList("il");
-    SetParameterOutputImage("outgroup.outputimage", imgList->GetNthElement(0));
-    SetParameterComplexOutputImage("cout", GetParameterComplexImage("cin"));
-    //std::cout << "TestApplication::DoExecute" << std::endl;
+    if( !IsParameterEnabled(key) )
+      return;
+
+    const Parameter * p = GetParameterByKey( key );
+    assert( p!=nullptr );
+    const StringListInterface * sli =
+      dynamic_cast< const StringListInterface * >(p);
+    assert( sli!=nullptr );
+
+    StringListInterface::StringVector strings;
+
+    sli->GetStrings( strings );
+
+    std::cout << "{" << std::endl;
+    {
+      for( auto s : strings )
+        std::cout << "'" << s << "'" << std::endl;
+    }
+    std::cout << "}"<< std::endl;
   }
 };
-}
-}
 
-OTB_APPLICATION_EXPORT(otb::Wrapper::TestApplication)
+} // end of namespace Wrapper
+} // end of namespace otb
+
+OTB_APPLICATION_EXPORT( otb::Wrapper::TestApplication )
diff --git a/Modules/Applications/AppTextures/app/CMakeLists.txt b/Modules/Applications/AppTextures/app/CMakeLists.txt
index 8f05f8d..c25a67f 100644
--- a/Modules/Applications/AppTextures/app/CMakeLists.txt
+++ b/Modules/Applications/AppTextures/app/CMakeLists.txt
@@ -18,14 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppTextures_LINK_LIBS
-  ${OTBTextures_LIBRARIES}
-  ${OTBImageBase_LIBRARIES}
-  ${OTBObjectList_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBImageManipulation_LIBRARIES}
-)
-
 otb_create_application(
   NAME           HaralickTextureExtraction
   SOURCES        otbHaralickTextureExtraction.cxx
diff --git a/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx b/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx
index cdde4cc..43e6b0b 100644
--- a/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx
+++ b/Modules/Applications/AppTextures/app/otbHaralickTextureExtraction.cxx
@@ -70,14 +70,34 @@ private:
 void DoInit() ITK_OVERRIDE
 {
 SetName("HaralickTextureExtraction");
-SetDescription("Computes textures on every pixel of the input image selected channel");
+SetDescription("Computes Haralick textural features on the selected channel of the input image");
 
 // Documentation
 SetDocName("Haralick Texture Extraction");
-SetDocLongDescription("This application computes Haralick, advanced and higher order textures on a mono band image");
-SetDocLimitations("None");
+SetDocLongDescription("This application computes three sets of Haralick features [1][2].\n"
+    "  * simple: a set of 8 local Haralick features: Energy (texture uniformity) , "
+    "Entropy (measure of randomness of intensity image), Correlation (how "
+    "correlated a pixel is to its neighborhood), Inverse Difference Moment (measures "
+    "the texture homogeneity), Inertia (intensity contrast between a pixel and its "
+    "neighborhood), Cluster Shade, Cluster Prominence, Haralick Correlation;\n"
+    "  * advanced: a set of 10 advanced Haralick features : Mean, Variance (measures the "
+    "texture heterogeneity), Dissimilarity, Sum Average, Sum Variance, Sum Entropy, "
+    "Difference of Entropies, Difference of Variances, IC1, IC2;\n"
+    "  * higher: a set of 11 higher Haralick features : Short Run Emphasis (measures the "
+    "texture sharpness), Long Run Emphasis (measures the texture roughness), Grey-Level "
+    "Nonuniformity, Run Length Nonuniformity, Run Percentage (measures the texture "
+    "sharpness homogeneity), Low Grey-Level Run Emphasis, High Grey-Level Run Emphasis, "
+    "Short Run Low Grey-Level Emphasis, Short Run High Grey-Level Emphasis, Long Run Low "
+    "Grey-Level Emphasis and Long Run High Grey-Level Emphasis.");
+SetDocLimitations("The computation of the features is based on a Gray Level Co-occurrence "
+    "matrix (GLCM) from the quantized input image. Consequently the quantization "
+    "parameters (min, max, nbbin) must be appropriate to the range of the pixel values.");
 SetDocAuthors("OTB-Team");
-SetDocSeeAlso("otbScalarImageToTexturesFilter, otbScalarImageToAdvancedTexturesFilter and otbScalarImageToHigherOrderTexturesFilter classes");
+SetDocSeeAlso("[1] HARALICK, Robert M., SHANMUGAM, Karthikeyan, et al. "
+    "Textural features for image classification. IEEE Transactions on systems, "
+    "man, and cybernetics, 1973, no 6, p. 610-621.\n"
+    "[2] otbScalarImageToTexturesFilter, otbScalarImageToAdvancedTexturesFilter and "
+    "otbScalarImageToHigherOrderTexturesFilter classes");
 
 AddDocTag(Tags::FeatureExtraction);
 AddDocTag("Textures");
@@ -100,7 +120,8 @@ MandatoryOff("step");
 AddRAMParameter();
 
 AddParameter(ParameterType_Group, "parameters", "Texture feature parameters");
-SetParameterDescription("parameters","This group of parameters allows one to define texture parameters.");
+SetParameterDescription("parameters","This group of parameters allows one to define "
+    "texture parameters.");
 
 AddParameter(ParameterType_Int,"parameters.xrad","X Radius");
 SetParameterDescription("parameters.xrad", "X Radius");
@@ -134,20 +155,25 @@ AddParameter(ParameterType_Choice, "texture", "Texture Set Selection");
 SetParameterDescription("texture", "Choice of The Texture Set");
 
 AddChoice("texture.simple", "Simple Haralick Texture Features");
-SetParameterDescription("texture.simple","This group of parameters defines the 8 local Haralick texture feature output image.\
-    The image channels are: Energy, Entropy, Correlation, Inverse Difference Moment,\
-    Inertia, Cluster Shade, Cluster Prominence and Haralick Correlation");
+SetParameterDescription("texture.simple", "This group of parameters defines "
+    "the 8 local Haralick texture feature output image. The image channels are: "
+    "Energy, Entropy, Correlation, Inverse Difference Moment, Inertia, Cluster "
+    "Shade, Cluster Prominence and Haralick Correlation");
 
 AddChoice("texture.advanced", "Advanced Texture Features");
-SetParameterDescription("texture.advanced","This group of parameters defines the 10 advanced texture feature output image.\
-    The image channels are: Mean, Variance, Dissimilarity, Sum Average, Sum Variance,\
-    Sum Entropy, Difference of Entropies, Difference of Variances, IC1 and IC2");
+SetParameterDescription("texture.advanced", "This group of parameters defines "
+    "the 10 advanced texture feature output image. The image channels are: Mean, "
+    "Variance, Dissimilarity, Sum Average, Sum Variance, Sum Entropy, Difference "
+    "of Entropies, Difference of Variances, IC1 and IC2");
 
 AddChoice("texture.higher", "Higher Order Texture Features");
-SetParameterDescription("texture.higher","This group of parameters defines the 11 higher order texture feature output image.\
-    The image channels are: Short Run Emphasis, Long Run Emphasis, Grey-Level Nonuniformity, Run Length Nonuniformity, Run Percentage, \
-    Low Grey-Level Run Emphasis, High Grey-Level Run Emphasis, Short Run Low Grey-Level Emphasis, Short Run High Grey-Level Emphasis, \
-    Long Run Low Grey-Level Emphasis and Long Run High Grey-Level Emphasis");
+SetParameterDescription("texture.higher", "This group of parameters defines the "
+    "11 higher order texture feature output image. The image channels are: "
+    "Short Run Emphasis, Long Run Emphasis, Grey-Level Nonuniformity, "
+    "Run Length Nonuniformity, Run Percentage, Low Grey-Level Run Emphasis, "
+    "High Grey-Level Run Emphasis, Short Run Low Grey-Level Emphasis, "
+    "Short Run High Grey-Level Emphasis, Long Run Low Grey-Level Emphasis and "
+    "Long Run High Grey-Level Emphasis");
 
 AddParameter(ParameterType_OutputImage, "out", "Output Image");
 SetParameterDescription("out", "Output image containing the selected texture features.");
diff --git a/Modules/Applications/AppTextures/app/otbSFSTextureExtraction.cxx b/Modules/Applications/AppTextures/app/otbSFSTextureExtraction.cxx
index 14fb6df..94fcc42 100644
--- a/Modules/Applications/AppTextures/app/otbSFSTextureExtraction.cxx
+++ b/Modules/Applications/AppTextures/app/otbSFSTextureExtraction.cxx
@@ -28,8 +28,6 @@
 #include "otbImageList.h"
 #include "otbImageListToVectorImageFilter.h"
 
-#include "itkTimeProbe.h"
-
 namespace otb
 {
 namespace Wrapper
@@ -61,14 +59,24 @@ private:
 void DoInit() ITK_OVERRIDE
 {
 SetName("SFSTextureExtraction");
-SetDescription("Computes Structural Feature Set textures on every pixel of the input image selected channel");
+SetDescription("Computes Structural Feature Set textures on every pixel of the "
+    "input image selected channel");
 
 // Documentation
 SetDocName("SFS Texture Extraction");
-SetDocLongDescription("This application computes SFS textures on a mono band image");
+SetDocLongDescription("Structural Feature Set [1] are based on the histograms of "
+    "the pixels in multiple directions of the image. The SFSTextureExtraction application "
+    "computes the  6 following features: SFS'Length, SFS'Width, SFS'PSI, SFS'W-Mean, "
+    "SFS'Ratio and SFS'SD (Standard Deviation). The texture indices are computed from "
+    "the neighborhood of each pixel. It is possible to change the length of the calculation "
+    "line (spatial threshold), as well as the maximum difference between a pixel of the line "
+    "and the pixel at the center of the neighborhood (spectral threshold) [2].");
 SetDocLimitations("None");
 SetDocAuthors("OTB-Team");
-SetDocSeeAlso("otbSFSTexturesImageFilter class");
+SetDocSeeAlso("[1] HUANG, Xin, ZHANG, Liangpei, et LI, Pingxiang. Classification and extraction "
+    "of spatial features in urban areas using high-resolution multispectral imagery. "
+    "IEEE Geoscience and Remote Sensing Letters, 2007, vol. 4, no 2, p. 260-264.\n"
+    "[2] otbSFSTexturesImageFilter class");
 
 AddDocTag(Tags::FeatureExtraction);
 AddDocTag("Textures");
@@ -84,9 +92,9 @@ SetMinimumParameterIntValue("channel", 1);
 AddRAMParameter();
 
 AddParameter(ParameterType_Group, "parameters", "Texture feature parameters");
-SetParameterDescription("parameters","This group of parameters allows one to define SFS texture parameters.\
-    The available texture features are SFS'Length, SFS'Width, SFS'PSI, SFS'W-Mean, SFS'Ratio and SFS'SD.\
-    They are provided in this exact order in the output image.");
+SetParameterDescription("parameters","This group of parameters allows one to define SFS texture "
+    "parameters. The available texture features are SFS'Length, SFS'Width, SFS'PSI, SFS'W-Mean, "
+    "SFS'Ratio and SFS'SD. They are provided in this exact order in the output image.");
 
 AddParameter(ParameterType_Float,"parameters.spethre","Spectral Threshold");
 SetParameterDescription("parameters.spethre", "Spectral Threshold");
diff --git a/Modules/Applications/AppVectorDataTranslation/app/CMakeLists.txt b/Modules/Applications/AppVectorDataTranslation/app/CMakeLists.txt
index 6f67792..23f8158 100644
--- a/Modules/Applications/AppVectorDataTranslation/app/CMakeLists.txt
+++ b/Modules/Applications/AppVectorDataTranslation/app/CMakeLists.txt
@@ -18,12 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppVectorDataTranslation_LINK_LIBS
-  ${OTBConversion_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-  ${OTBTransform_LIBRARIES}
-)
-
 otb_create_application(
   NAME           Rasterization
   SOURCES        otbRasterization.cxx
diff --git a/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx b/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx
index 7e35f67..748d8f2 100644
--- a/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx
+++ b/Modules/Applications/AppVectorDataTranslation/app/otbRasterization.cxx
@@ -233,7 +233,7 @@ private:
 
       origin = referenceImage->GetOrigin();
 
-      spacing = referenceImage->GetSpacing();
+      spacing = referenceImage->GetSignedSpacing();
       }
     else if (HasValue("spx") && HasValue("spy"))
       {
diff --git a/Modules/Applications/AppVectorUtils/app/CMakeLists.txt b/Modules/Applications/AppVectorUtils/app/CMakeLists.txt
index 4782c35..b3a4081 100644
--- a/Modules/Applications/AppVectorUtils/app/CMakeLists.txt
+++ b/Modules/Applications/AppVectorUtils/app/CMakeLists.txt
@@ -18,15 +18,6 @@
 # limitations under the License.
 #
 
-set(OTBAppVectorUtils_LINK_LIBS
-  ${OTBVectorDataBase_LIBRARIES}
-  ${OTBProjection_LIBRARIES}
-  ${OTBVectorDataManipulation_LIBRARIES}
-  ${OTBCarto_LIBRARIES}
-  ${OTBCommon_LIBRARIES}
-  ${OTBApplicationEngine_LIBRARIES}
-)
-
 otb_create_application(
   NAME           VectorDataTransform
   SOURCES        otbVectorDataTransform.cxx
diff --git a/Modules/Applications/AppVectorUtils/app/otbConcatenateVectorData.cxx b/Modules/Applications/AppVectorUtils/app/otbConcatenateVectorData.cxx
index 0710b1b..92b972e 100644
--- a/Modules/Applications/AppVectorUtils/app/otbConcatenateVectorData.cxx
+++ b/Modules/Applications/AppVectorUtils/app/otbConcatenateVectorData.cxx
@@ -50,22 +50,28 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("ConcatenateVectorData");
-    SetDescription("Concatenate VectorDatas");
-
-    SetDocName("Concatenate");
-    SetDocLongDescription("This application concatenates a list of VectorData to produce a unique VectorData as output."
-                          "Note that the VectorDatas must be of the same type (Storing polygons only, lines only, or points only)");
-    SetDocLimitations("None");
+    SetDescription("Concatenate vector data files");
+
+    SetDocName("Concatenate Vector Data");
+    SetDocLongDescription("This application concatenates a list of vector data "
+      "files to produce a unique vector data output file.\n\n"
+      "This application will gather all the geometries from the input files and"
+      " write them into an output vector data file. Any format supported by OGR"
+      " can be used. Ideally, all inputs should have the same set of fields and"
+      " the same spatial reference system.");
+    SetDocLimitations("The vector data must be contain the same type of "
+      "geometries (point / lines / polygons). The fields present in the output "
+      "file are the ones from the first input.");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
 
     AddDocTag(Tags::Vector);
 
-    AddParameter(ParameterType_InputVectorDataList, "vd", "Input VectorDatas to concatenate");
-    SetParameterDescription("vd", "VectorData files to be concatenated in an unique VectorData");
+    AddParameter(ParameterType_InputVectorDataList, "vd", "Input vector files");
+    SetParameterDescription("vd", "Vector data files to be concatenated.");
 
-    AddParameter(ParameterType_OutputVectorData, "out", "Concatenated VectorData");
-    SetParameterDescription("out", "Output conctenated VectorData");
+    AddParameter(ParameterType_OutputVectorData, "out", "Concatenated output");
+    SetParameterDescription("out", "Output conctenated vector data file.");
 
     // Doc example parameter settings
     SetDocExampleParameterValue("vd", "ToulousePoints-examples.shp ToulouseRoad-examples.shp");
diff --git a/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx b/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx
index 0cc82f5..d55626e 100644
--- a/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx
+++ b/Modules/Applications/AppVectorUtils/app/otbOSMDownloader.cxx
@@ -53,40 +53,55 @@ private:
   void DoInit() ITK_OVERRIDE
   {
     SetName("OSMDownloader");
-    SetDescription("Generate a vector data from OSM on the input image extend");
+    SetDescription("Download vector data from OSM and store it to file");
     // Documentation
-    SetDocName("Open Street Map layers importations applications");
-    SetDocLongDescription("Generate a vector data from Open Street Map data. A DEM could be use. By default, the entire layer is downloaded, an image can be use as support for the OSM data. The application can provide also available classes in layers . This application required an Internet access. Information about the OSM project : http://www.openstreetmap.fr/");
-    SetDocLimitations("None");
+    SetDocName("Open Street Map layers import");
+    SetDocLongDescription("The application connects to Open Street Map server"
+      ", downloads the data corresponding to the spatial extent of the support"
+      " image, and filters the geometries based on OSM tags to produce a vector"
+      " data file.\n\n"
+      "This application can be used to download reference data to perform the "
+      "training of a machine learning model (see for instance [1]).\n\n"
+      "By default, the entire layer is downloaded. The application has a "
+      "special mode to provide the list of available classes in the layers. "
+      "The downloaded features are filtered by giving an OSM tag 'key'. In "
+      "addition, the user can also choose what 'value' this key should have. "
+      "More information about the OSM project at [2].");
+    SetDocLimitations("This application requires an Internet access.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("Conversion");
+    SetDocSeeAlso("[1] TrainImagesClassifier \n"
+      "[2] http://www.openstreetmap.fr/");
 
 	AddDocTag("Miscellaneous");
     AddDocTag(Tags::Meta);
 	AddDocTag(Tags::Vector);
 
-    AddParameter(ParameterType_OutputVectorData,  "out",   "Output vector data");
-    SetParameterDescription("out", "Generated output vector data path");
+    AddParameter(ParameterType_OutputVectorData, "out", "Output vector data");
+    SetParameterDescription("out", "Vector data file to store downloaded features");
 
-    AddParameter(ParameterType_InputImage,  "support",   "Support image");
-    SetParameterDescription("support", "Image used as support to estimate the models");
+    AddParameter(ParameterType_InputImage, "support", "Support image");
+    SetParameterDescription("support", "Image used to derive the spatial extent"
+      " to be requested from OSM server (the bounding box of the extent is "
+      "used). Be aware that a request with a large extent may be rejected by "
+      "the server.");
 
     AddParameter(ParameterType_String, "key",  "OSM tag key");
-    SetParameterDescription("key", "OSM tag key to extract (highway, building...)");
+    SetParameterDescription("key", "OSM tag key to extract (highway, building"
+     "...). It defines a category to select features.");
     MandatoryOff("key");
 
     AddParameter(ParameterType_String, "value",  "OSM tag value");
-    SetParameterDescription("value", "OSM tag value to extract (motorway, footway...)");
+    SetParameterDescription("value", "OSM tag value to extract (motorway, "
+      "footway...). It defines the type of feature to select inside a category.");
     MandatoryOff("value");
 
     // Elevation
     ElevationParametersHandler::AddElevationParameters(this, "elev");
 
-    AddParameter(ParameterType_Empty, "printclasses", "option to display available key/value classes");
-    std::ostringstream oss;
-    oss << "Print the key/value classes available for the bounding box of the input image "<<std::endl;
-    oss << "\t\t\t\t  ** If not used : Note that the options OSMKey (-key) and Output (-out) become mandatory";
-    SetParameterDescription("printclasses", oss.str().c_str());
+    AddParameter(ParameterType_Empty, "printclasses", "Displays available key/value classes");
+    SetParameterDescription("printclasses","Print the key/value classes "
+      "available for the selected support image. If enabled, the OSM tag Key "
+      "(-key) and the output (-out) become optional" );
     MandatoryOff("printclasses");
 
     // Doc example parameter settings
diff --git a/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx b/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx
index 8dc890b..be16319 100644
--- a/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx
+++ b/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx
@@ -60,46 +60,64 @@ private:
     SetDescription("Apply a transform to each vertex of the input VectorData");
 
     SetDocName("Vector Data Transformation");
-    SetDocLongDescription("This application performs a transformation of an input vector data transforming each vertex in the vector data. The applied transformation manages translation, rotation and scale, and can be centered or not.");
+    SetDocLongDescription("This application iterates over each vertex in the "
+      "input vector data file and performs a transformation on this vertex.\n\n"
+      "It is the equivalent of [1] that transforms images. For instance, if you"
+      " extract the envelope of an image with [2], and you transform this image"
+      " with [1], you may want to use this application to operate the same "
+      "transform on the envelope.\n\n"
+      "The applied transformation is a 2D similarity. It manages translation, "
+      "rotation, scaling, and can be centered or not. Note that the support "
+      "image is used to define the reference coordinate system in which the "
+      "transform is applied. For instance the input vector data can have WGS84"
+      " coordinates, the support image is in UTM, so a translation of 1 pixel "
+      "along X corresponds to the X pixel size of the input image along the "
+      "X axis of the UTM coordinates frame. This image can also be in sensor "
+      "geometry.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+    SetDocSeeAlso("[1] RigidTransformResample\n"
+      "[2] ImageEnvelope");
 
     AddDocTag(Tags::Vector);
 
     AddParameter(ParameterType_InputVectorData, "vd", "Input Vector data");
-    SetParameterDescription("vd", "Input vector data to transform");
+    SetParameterDescription("vd", "Input vector data file to transform");
 
     AddParameter(ParameterType_OutputVectorData,"out","Output Vector data");
-    SetParameterDescription("out", "Output transformed vector data");
+    SetParameterDescription("out", "Output vector data with ");
 
     AddParameter(ParameterType_InputImage, "in", "Support image");
-    SetParameterDescription("in","Image needed as a support to the vector data");
+    SetParameterDescription("in","Image defining the reference coordinate "
+      "system in which the transform is applied. Both projected and sensor "
+      "images are supported.");
 
     // Transform Group
     AddParameter(ParameterType_Group, "transform", "Transform parameters");
     SetParameterDescription("transform", "Group of parameters to define the transform");
 
-    AddParameter(ParameterType_Float, "transform.tx", "Translation X");
+    AddParameter(ParameterType_Float, "transform.tx", "X Translation");
     SetParameterDescription("transform.tx","Translation in the X direction (in pixels)");
-    AddParameter(ParameterType_Float, "transform.ty", "Translation Y");
+    AddParameter(ParameterType_Float, "transform.ty", "Y Translation");
     SetParameterDescription("transform.ty","Translation in the Y direction (in pixels)");
     SetDefaultParameterFloat("transform.tx", 0.);
     SetDefaultParameterFloat("transform.ty", 0.);
 
     AddParameter(ParameterType_Float, "transform.ro", "Rotation Angle");
-    SetParameterDescription("transform.ro","Angle of the rotation to apply in degrees");
+    SetParameterDescription("transform.ro","Angle of the rotation (in degrees)");
     SetDefaultParameterFloat("transform.ro", 0.);
 
     AddParameter(ParameterType_Float, "transform.centerx", "Center X");
-    SetParameterDescription("transform.centerx","X coordinate of the rotation center (in physical units)");
+    SetParameterDescription("transform.centerx","X coordinate of the rotation "
+      "and scaling center (in physical units)");
     AddParameter(ParameterType_Float, "transform.centery", "Center Y");
-    SetParameterDescription("transform.centery","Y coordinate of the rotation center (in physical units)");
+    SetParameterDescription("transform.centery","Y coordinate of the rotation "
+      "and scaling center (in physical units)");
     SetDefaultParameterFloat("transform.centerx", 0.);
     SetDefaultParameterFloat("transform.centery", 0.);
 
     AddParameter(ParameterType_Float, "transform.scale", "Scale");
-    SetParameterDescription("transform.scale","The scale to apply");
+    SetParameterDescription("transform.scale","The scale coefficient to apply");
     SetDefaultParameterFloat("transform.scale", 1.);
 
     // Doc example parameter settings
@@ -140,8 +158,8 @@ private:
     parameters[1] = CONST_PI * GetParameterFloat("transform.ro")/180.;
     parameters[2] = GetParameterFloat("transform.centerx");
     parameters[3] = GetParameterFloat("transform.centery");
-    parameters[4] = inImage->GetSpacing()[0] * GetParameterFloat("transform.tx");
-    parameters[5] = vcl_abs(inImage->GetSpacing()[1]) * GetParameterFloat("transform.ty");
+    parameters[4] = inImage->GetSignedSpacing()[0] * GetParameterFloat("transform.tx");
+    parameters[5] = vcl_abs(inImage->GetSignedSpacing()[1]) * GetParameterFloat("transform.ty");
 
     // Set the parameters to the transform
     m_Transform->SetParameters(parameters);
diff --git a/Modules/Core/Common/include/otbFilterWatcherBase.h b/Modules/Core/Common/include/otbFilterWatcherBase.h
index 894d22a..a1a3f48 100644
--- a/Modules/Core/Common/include/otbFilterWatcherBase.h
+++ b/Modules/Core/Common/include/otbFilterWatcherBase.h
@@ -22,9 +22,9 @@
 #ifndef otbFilterWatcherBase_h
 #define otbFilterWatcherBase_h
 
+#include "otbStopwatch.h"
 #include "itkCommand.h"
 #include "itkProcessObject.h"
-#include "itkTimeProbe.h"
 
 #include "OTBCommonExport.h"
 
@@ -82,10 +82,10 @@ public:
     return m_Comment;
   }
 
-  /** Get a reference to the TimeProbe */
-  itk::TimeProbe& GetTimeProbe()
+  /** Get a reference to the Stopwatch */
+  otb::Stopwatch& GetStopwatch()
   {
-    return m_TimeProbe;
+    return m_Stopwatch;
   }
 
 protected:
@@ -126,7 +126,7 @@ protected:
   virtual void EndFilter() = 0;
 
   /** Computing time */
-  itk::TimeProbe m_TimeProbe;
+  otb::Stopwatch m_Stopwatch;
 
   /** Associated comment */
   std::string m_Comment;
diff --git a/Modules/Core/Common/include/otbImportImageFilter.h b/Modules/Core/Common/include/otbImportImageFilter.h
index 7c322b6..9f21873 100644
--- a/Modules/Core/Common/include/otbImportImageFilter.h
+++ b/Modules/Core/Common/include/otbImportImageFilter.h
@@ -113,7 +113,7 @@ public:
   }
 
   /** Set the spacing (size of a pixel) of the image.
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   itkSetVectorMacro(Spacing, const double, OutputImageType::ImageDimension);
   itkSetVectorMacro(Spacing, const float, OutputImageType::ImageDimension);
 
diff --git a/Modules/Core/Common/include/otbImportImageFilter.txx b/Modules/Core/Common/include/otbImportImageFilter.txx
index a28fc33..204899a 100644
--- a/Modules/Core/Common/include/otbImportImageFilter.txx
+++ b/Modules/Core/Common/include/otbImportImageFilter.txx
@@ -169,7 +169,7 @@ ImportImageFilter<TOutputImage>
 
   // we need to compute the output spacing, the output origin, the
   // output image size, and the output image start index
-  outputPtr->SetSpacing(m_Spacing);
+  outputPtr->SetSignedSpacing(m_Spacing);
   outputPtr->SetOrigin(m_Origin);
   outputPtr->SetDirection(m_Direction);
   outputPtr->SetLargestPossibleRegion(m_Region);
diff --git a/Modules/Core/Common/include/otbImportVectorImageFilter.h b/Modules/Core/Common/include/otbImportVectorImageFilter.h
index 899651a..c7db035 100644
--- a/Modules/Core/Common/include/otbImportVectorImageFilter.h
+++ b/Modules/Core/Common/include/otbImportVectorImageFilter.h
@@ -114,7 +114,7 @@ public:
   }
 
   /** Set the spacing (size of a pixel) of the image.
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   itkSetVectorMacro(Spacing, const double, OutputImageType::ImageDimension);
   itkSetVectorMacro(Spacing, const float, OutputImageType::ImageDimension);
 
diff --git a/Modules/Core/Common/include/otbImportVectorImageFilter.txx b/Modules/Core/Common/include/otbImportVectorImageFilter.txx
index 49c95ab..1db7462 100644
--- a/Modules/Core/Common/include/otbImportVectorImageFilter.txx
+++ b/Modules/Core/Common/include/otbImportVectorImageFilter.txx
@@ -170,7 +170,7 @@ ImportVectorImageFilter<TOutputImage>
 
   // we need to compute the output spacing, the output origin, the
   // output image size, and the output image start index
-  outputPtr->SetSpacing(m_Spacing);
+  outputPtr->SetSignedSpacing(m_Spacing);
   outputPtr->SetOrigin(m_Origin);
   outputPtr->SetDirection(m_Direction);
   outputPtr->SetLargestPossibleRegion(m_Region);
diff --git a/Modules/Core/Common/include/otbStopwatch.h b/Modules/Core/Common/include/otbStopwatch.h
new file mode 100644
index 0000000..33a0f99
--- /dev/null
+++ b/Modules/Core/Common/include/otbStopwatch.h
@@ -0,0 +1,85 @@
+/*
+ * 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 otbStopwatch_h
+#define otbStopwatch_h
+
+#include <cstdint>
+
+#include "OTBCommonExport.h"
+
+namespace otb
+{
+
+/** \class Stopwatch
+ * \brief Stopwatch timer.
+ *
+ * A simple class for measuring elapsed time.
+ *
+ *
+ * \ingroup OTBCommon
+ */
+class OTBCommon_EXPORT Stopwatch final
+{
+public:
+  /** Standard class typedefs. */
+  typedef Stopwatch  Self;
+
+  /** Represents a duration measured in milliseconds */
+  typedef uint64_t   DurationType;
+
+  /** Constructs a timer instance */
+  Stopwatch();
+
+  /** Start the timer if not already running */
+  void Start();
+
+  /** Stop the timer if running */
+  void Stop();
+
+  /** Reset the timer */
+  void Reset();
+
+  /** Reset and restart the timer */
+  void Restart();
+
+  /** Get the total duration, excluding the current iteration */
+  DurationType GetElapsedMilliseconds() const;
+
+  /** Returns whether the stopwatch is running */
+  bool IsRunning() const;
+
+  /** Creates and starts a new stopwatch instance */
+  static Stopwatch StartNew();
+
+private:
+  typedef uint64_t   TimepointType;
+
+  TimepointType GetTimestamp() const;
+  DurationType GetRunningElapsedTime() const;
+
+  TimepointType m_StartTime;
+  DurationType m_ElapsedMilliseconds;
+  bool m_IsRunning;
+};
+
+} // namespace otb
+
+#endif
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx b/Modules/Core/Common/include/otbStringToHTML.h
similarity index 50%
copy from Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
copy to Modules/Core/Common/include/otbStringToHTML.h
index e4104cd..9fc71c2 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
+++ b/Modules/Core/Common/include/otbStringToHTML.h
@@ -18,37 +18,40 @@
  * limitations under the License.
  */
 
-#if defined(_MSC_VER)
-#pragma warning ( disable : 4786 )
-#endif
+#ifndef otbStringToHTML_h
+#define otbStringToHTML_h
+
+#include <string>
+#include <iostream>
+
+#include "OTBCommonExport.h"
 
-#include "otbWrapperParameter.h"
+namespace otb
+{
 
-int otbWrapperParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+/**
+ * \class StringToHTML
+ *
+ * Prepare a plain string for HTML encapsulation (protection of special
+ * characters)
+ *
+ * \ingroup OTBCommon
+ */
+class OTBCommon_EXPORT StringToHTML
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
+public:
+  StringToHTML(const std::string & str);
 
-  //std::cout << parameter << std::endl;
+  void Print(std::ostream& os) const;
 
-  return EXIT_SUCCESS;
-}
+protected:
 
-int otbWrapperParameterTest1(int itkNotUsed(argc), char* argv[])
-{
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
-
-  const std::string name = argv[1];
-
-  parameter->SetName(name);
-
-  if (name == parameter->GetName())
-    {
-    return EXIT_SUCCESS;
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
-}
+private:
+  const std::string & m_Str;
+};
+
+extern OTBCommon_EXPORT std::ostream & operator<< (std::ostream& os, const otb::StringToHTML& str);
+
+} // end of namespace otb
+
+#endif
diff --git a/Modules/Core/Common/include/otbWriterWatcherBase.h b/Modules/Core/Common/include/otbWriterWatcherBase.h
index f94615d..cba8db3 100644
--- a/Modules/Core/Common/include/otbWriterWatcherBase.h
+++ b/Modules/Core/Common/include/otbWriterWatcherBase.h
@@ -22,9 +22,10 @@
 #ifndef otbWriterWatcherBase_h
 #define otbWriterWatcherBase_h
 
+#include "otbStopwatch.h"
+
 #include "itkCommand.h"
 #include "itkProcessObject.h"
-#include "itkTimeProbe.h"
 
 #include "OTBCommonExport.h"
 
@@ -89,10 +90,10 @@ public:
     return m_Comment;
   }
 
-  /** Get a reference to the TimeProbe */
-  itk::TimeProbe& GetTimeProbe()
+  /** Get a reference to the Stopwatch */
+  otb::Stopwatch& GetStopwatch()
   {
-    return m_TimeProbe;
+    return m_Stopwatch;
   }
 
 protected:
@@ -116,7 +117,7 @@ protected:
   virtual void EndFilter() = 0;
 
   /** Computing time */
-  itk::TimeProbe m_TimeProbe;
+  otb::Stopwatch m_Stopwatch;
 
   /** Associated comment */
   std::string m_Comment;
diff --git a/Modules/Core/Common/src/CMakeLists.txt b/Modules/Core/Common/src/CMakeLists.txt
index af251e1..02ff625 100644
--- a/Modules/Core/Common/src/CMakeLists.txt
+++ b/Modules/Core/Common/src/CMakeLists.txt
@@ -27,10 +27,12 @@ set(OTBCommon_SRC
   otbConfigurationManager.cxx
   otbStandardOneLineFilterWatcher.cxx
   otbWriterWatcherBase.cxx
+  otbStopwatch.cxx
+  otbStringToHTML.cxx
   )
 
 add_library(OTBCommon ${OTBCommon_SRC})
-target_link_libraries(OTBCommon 
+target_link_libraries(OTBCommon
   ${OTBITK_LIBRARIES}
 
   )
diff --git a/Modules/Core/Common/src/otbFilterWatcherBase.cxx b/Modules/Core/Common/src/otbFilterWatcherBase.cxx
index 47f3e56..2e4f964 100644
--- a/Modules/Core/Common/src/otbFilterWatcherBase.cxx
+++ b/Modules/Core/Common/src/otbFilterWatcherBase.cxx
@@ -81,7 +81,7 @@ FilterWatcherBase
     }
 
   // Initialize state
-  m_TimeProbe = watch.m_TimeProbe;
+  m_Stopwatch = watch.m_Stopwatch;
   m_Process = watch.m_Process;
   m_Comment = watch.m_Comment;
 
@@ -125,7 +125,7 @@ FilterWatcherBase
     }
 
   // Initialize state
-  m_TimeProbe = watch.m_TimeProbe;
+  m_Stopwatch = watch.m_Stopwatch;
   m_Process = watch.m_Process;
   m_Comment = watch.m_Comment;
 
diff --git a/Modules/Core/Common/src/otbStandardFilterWatcher.cxx b/Modules/Core/Common/src/otbStandardFilterWatcher.cxx
index e722735..fda5693 100644
--- a/Modules/Core/Common/src/otbStandardFilterWatcher.cxx
+++ b/Modules/Core/Common/src/otbStandardFilterWatcher.cxx
@@ -100,7 +100,7 @@ void
 StandardFilterWatcher
 ::StartFilter()
 {
-  m_TimeProbe.Start();
+  m_Stopwatch.Start();
   std::cout << (m_Process.GetPointer() ? m_Process->GetNameOfClass() : "None")
             << " \"" << m_Comment << "\" " << std::endl;
 }
@@ -109,9 +109,9 @@ void
 StandardFilterWatcher
 ::EndFilter()
 {
-  m_TimeProbe.Stop();
+  m_Stopwatch.Stop();
   std::cout << std::endl << "Filter took "
-            << m_TimeProbe.GetMean()
+            << m_Stopwatch.GetElapsedMilliseconds() / 1000
             << " seconds." << std::endl;
 }
 } // end namespace otb
diff --git a/Modules/Core/Common/src/otbStandardOneLineFilterWatcher.cxx b/Modules/Core/Common/src/otbStandardOneLineFilterWatcher.cxx
index 96ee38f..77e3504 100644
--- a/Modules/Core/Common/src/otbStandardOneLineFilterWatcher.cxx
+++ b/Modules/Core/Common/src/otbStandardOneLineFilterWatcher.cxx
@@ -94,19 +94,19 @@ void
 StandardOneLineFilterWatcher
 ::StartFilter()
 {
-  m_TimeProbe.Start();
+  m_Stopwatch.Start();
 }
 
 void
 StandardOneLineFilterWatcher
 ::EndFilter()
 {
-  m_TimeProbe.Stop();
+  m_Stopwatch.Stop();
 
   // Ensure we don't depend on std::cout configuration
   std::ostringstream elapsedTime;
   elapsedTime.precision(1);
-  elapsedTime << m_TimeProbe.GetMean();
+  elapsedTime << m_Stopwatch.GetElapsedMilliseconds() / 1000;
 
   std::cout << " ("
             << elapsedTime.str()
diff --git a/Modules/Core/Common/src/otbStandardWriterWatcher.cxx b/Modules/Core/Common/src/otbStandardWriterWatcher.cxx
index 50e6e9b..6a7c175 100644
--- a/Modules/Core/Common/src/otbStandardWriterWatcher.cxx
+++ b/Modules/Core/Common/src/otbStandardWriterWatcher.cxx
@@ -147,7 +147,7 @@ void
 StandardWriterWatcher
 ::StartWriter()
 {
-  m_TimeProbe.Start();
+  m_Stopwatch.Start();
   std::cout << "Writing task: " << " \"" << m_Comment << "\" " << std::endl;
   std::cout << "Writer type: " << (m_Process.GetPointer() ? m_Process->GetNameOfClass() : "None") << std::endl;
   std::cout << "Filter type: " << (m_SourceProcess.GetPointer() ? m_SourceProcess->GetNameOfClass() : "None") <<
@@ -158,9 +158,9 @@ void
 StandardWriterWatcher
 ::EndWriter()
 {
-  m_TimeProbe.Stop();
+  m_Stopwatch.Stop();
   std::cout << std::endl << "Writing task took "
-            << m_TimeProbe.GetMean()
+            << m_Stopwatch.GetElapsedMilliseconds() / 1000
             << " seconds." << std::endl;
 }
 
diff --git a/Modules/Core/Common/src/otbStopwatch.cxx b/Modules/Core/Common/src/otbStopwatch.cxx
new file mode 100644
index 0000000..5c45c48
--- /dev/null
+++ b/Modules/Core/Common/src/otbStopwatch.cxx
@@ -0,0 +1,119 @@
+/*
+ * 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 <chrono>
+
+#include "otbStopwatch.h"
+
+namespace otb
+{
+
+Stopwatch
+::Stopwatch()
+  : m_StartTime(), m_ElapsedMilliseconds(), m_IsRunning()
+{
+}
+
+void
+Stopwatch
+::Start()
+{
+  if (!this->m_IsRunning)
+    {
+    this->m_IsRunning = true;
+    this->m_StartTime = this->GetTimestamp();
+    }
+}
+
+void
+Stopwatch
+::Stop()
+{
+  if (this->m_IsRunning)
+    {
+    this->m_ElapsedMilliseconds += GetRunningElapsedTime();
+    this->m_IsRunning = false;
+    }
+}
+
+void
+Stopwatch
+::Reset()
+{
+  this->m_ElapsedMilliseconds = 0;
+  this->m_IsRunning = false;
+}
+
+void
+Stopwatch
+::Restart()
+{
+  this->m_ElapsedMilliseconds = 0;
+  this->m_IsRunning = true;
+  this->m_StartTime = this->GetTimestamp();
+}
+
+Stopwatch::DurationType
+Stopwatch
+::GetElapsedMilliseconds() const
+{
+  auto result = this->m_ElapsedMilliseconds;
+
+  if (this->m_IsRunning)
+    result += this->GetRunningElapsedTime();
+
+  return result;
+}
+
+bool
+Stopwatch
+::IsRunning() const
+{
+  return this->m_IsRunning;
+}
+
+Stopwatch
+Stopwatch
+::StartNew()
+{
+  Stopwatch sw;
+  sw.Start();
+
+  return sw;
+}
+
+inline
+Stopwatch::TimepointType
+Stopwatch
+::GetTimestamp() const
+{
+  auto now = std::chrono::steady_clock::now();
+  return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
+}
+
+inline
+Stopwatch::DurationType
+Stopwatch
+::GetRunningElapsedTime() const
+{
+  return this->GetTimestamp() - this->m_StartTime;
+}
+
+}
diff --git a/Modules/Core/Common/src/otbStringToHTML.cxx b/Modules/Core/Common/src/otbStringToHTML.cxx
new file mode 100644
index 0000000..064ec85
--- /dev/null
+++ b/Modules/Core/Common/src/otbStringToHTML.cxx
@@ -0,0 +1,68 @@
+/*
+ * 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 "otbStringToHTML.h"
+
+namespace otb
+{
+
+StringToHTML::StringToHTML(const std::string & str)
+  : m_Str(str)
+{
+}
+
+void
+StringToHTML::Print(std::ostream& os) const
+{
+  // TODO : add a Tex to HTML translator (maybe try TtH)
+  bool formulaMode=false;
+  for(auto&& c : m_Str)
+    {
+    if (c=='`')
+      {
+      formulaMode = !formulaMode;
+      }
+    switch (c)
+      {
+      case '<':
+        os.write("<",4);
+        break;
+      case '>':
+        os.write(">",4);
+        break;
+      case '&':
+        os.write("&",5);
+        break;
+      case '\n':
+        os.write("<br/>",5);
+        break;
+      default:
+        os.put(c);
+      }
+    }
+}
+
+std::ostream & operator<< (std::ostream& os, const StringToHTML& str)
+{
+  str.Print(os);
+  return os;
+}
+
+} // end of namespace otb
diff --git a/Modules/Core/Common/src/otbWriterWatcherBase.cxx b/Modules/Core/Common/src/otbWriterWatcherBase.cxx
index ae4ef61..a2fcf9e 100644
--- a/Modules/Core/Common/src/otbWriterWatcherBase.cxx
+++ b/Modules/Core/Common/src/otbWriterWatcherBase.cxx
@@ -188,7 +188,7 @@ WriterWatcherBase
     }
 
   // Initialize state
-  m_TimeProbe = watch.m_TimeProbe;
+  m_Stopwatch = watch.m_Stopwatch;
   m_Process = watch.m_Process;
   m_SourceProcess = watch.m_SourceProcess;
   m_Comment = watch.m_Comment;
@@ -281,7 +281,7 @@ WriterWatcherBase
     }
 
   // Initialize state
-  m_TimeProbe = watch.m_TimeProbe;
+  m_Stopwatch = watch.m_Stopwatch;
   m_Process = watch.m_Process;
   m_SourceProcess = watch.m_SourceProcess;
   m_Comment = watch.m_Comment;
diff --git a/Modules/Core/Common/test/CMakeLists.txt b/Modules/Core/Common/test/CMakeLists.txt
index a77a36f..fe6010a 100644
--- a/Modules/Core/Common/test/CMakeLists.txt
+++ b/Modules/Core/Common/test/CMakeLists.txt
@@ -37,6 +37,7 @@ otbConfigurationManagerTest.cxx
 otbStandardFilterWatcherNew.cxx
 otbStandardOneLineFilterWatcherTest.cxx
 otbStandardWriterWatcher.cxx
+otbStopwatchTest.cxx
 )
 
 add_executable(otbCommonTestDriver ${OTBCommonTests})
@@ -167,6 +168,9 @@ otb_add_test(NAME coTuSystemTests_IsA_Methods COMMAND otbCommonTestDriver
   ${OTB_DATA_ROOT}
   )
 
+otb_add_test(NAME coTuStopwatchTests COMMAND otbCommonTestDriver
+  otbStopwatchTest)
+
 otb_add_test(NAME coTvParseHdfSubsetName COMMAND otbCommonTestDriver
   otbParseHdfSubsetName)
 
diff --git a/Modules/Core/Common/test/otbCommonTestDriver.cxx b/Modules/Core/Common/test/otbCommonTestDriver.cxx
index 99bc5d5..b38f388 100644
--- a/Modules/Core/Common/test/otbCommonTestDriver.cxx
+++ b/Modules/Core/Common/test/otbCommonTestDriver.cxx
@@ -31,6 +31,7 @@ void RegisterTests()
   REGISTER_TEST(otbRectangle);
   REGISTER_TEST(otbImageRegionNonUniformMultidimensionalSplitterNew);
   REGISTER_TEST(otbSystemTest);
+  REGISTER_TEST(otbStopwatchTest);
   REGISTER_TEST(otbParseHdfSubsetName);
   REGISTER_TEST(otbParseHdfFileName);
   REGISTER_TEST(otbImageRegionSquareTileSplitterNew);
diff --git a/Modules/Core/Common/test/otbStopwatchTest.cxx b/Modules/Core/Common/test/otbStopwatchTest.cxx
new file mode 100644
index 0000000..c271f00
--- /dev/null
+++ b/Modules/Core/Common/test/otbStopwatchTest.cxx
@@ -0,0 +1,92 @@
+/*
+ * 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 <cassert>
+#include <iostream>
+#include <cstdlib>
+
+#if 0
+#include <unistd.h>
+
+#include "itkTimeProbe.h"
+#endif
+
+#include "itkMacro.h"
+#include "otbStopwatch.h"
+
+int otbStopwatchTest(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+{
+  otb::Stopwatch sw;
+
+  assert( !sw.IsRunning() );
+  assert( sw.GetElapsedMilliseconds() == 0 );
+
+  sw.Start();
+  assert( sw.IsRunning() );
+  sw.Stop();
+
+  sw.Reset();
+  assert( !sw.IsRunning() );
+  assert( sw.GetElapsedMilliseconds() == 0 );
+
+  sw = otb::Stopwatch::StartNew();
+  assert( sw.IsRunning() );
+  sw.Stop();
+
+#if 0
+  // We have no portable sleep() and otbThreads is not linked here
+  sw.Start();
+  usleep(500 * 1000);
+  sw.Stop();
+  assert( sw.GetElapsedMilliseconds() > 450 && sw.GetElapsedMilliseconds() < 550 );
+
+  sw.Start();
+  usleep(500 * 1000);
+  sw.Stop();
+  assert( sw.GetElapsedMilliseconds() > 900 && sw.GetElapsedMilliseconds() < 1100 );
+
+  sw.Restart();
+  usleep(500 * 1000);
+  sw.Stop();
+  assert( sw.GetElapsedMilliseconds() > 450 && sw.GetElapsedMilliseconds() < 550 );
+
+  const int iterations = 100000;
+  sw.Restart();
+  for (int i = 0; i < iterations; i++)
+    {
+    itk::TimeProbe chrono;
+    chrono.Start();
+    chrono.Stop();
+    }
+  std::cerr << "itk::TimeProbe time: " << sw.GetElapsedMilliseconds() << std::endl;
+
+  sw.Restart();
+  for (int i = 0; i < iterations; i++)
+    {
+    auto chrono = otb::Stopwatch::StartNew();
+    chrono.Stop();
+    }
+  std::cerr << "otb::Stopwatch time: " << sw.GetElapsedMilliseconds() << std::endl;
+
+  #endif
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Core/ImageBase/include/otbExtractROIBase.txx b/Modules/Core/ImageBase/include/otbExtractROIBase.txx
index b7c6e0e..78f5463 100644
--- a/Modules/Core/ImageBase/include/otbExtractROIBase.txx
+++ b/Modules/Core/ImageBase/include/otbExtractROIBase.txx
@@ -247,7 +247,7 @@ ExtractROIBase<TInputImage, TOutputImage>
   // This logic needs to be augmented with logic that select which
   // dimensions to copy
   const typename InputImageType::SpacingType&
-    inputSpacing = inputPtr->GetSpacing();
+    inputSpacing = inputPtr->GetSignedSpacing();
   const typename InputImageType::DirectionType&
     inputDirection = inputPtr->GetDirection();
   const typename InputImageType::PointType&
@@ -304,7 +304,7 @@ ExtractROIBase<TInputImage, TOutputImage>
     }
 
   // set the spacing and origin
-  outputPtr->SetSpacing(outputSpacing);
+  outputPtr->SetSignedSpacing(outputSpacing);
   outputPtr->SetDirection(outputDirection);
   outputPtr->SetOrigin(outputOrigin);
 
diff --git a/Modules/Core/ImageBase/include/otbImage.h b/Modules/Core/ImageBase/include/otbImage.h
index c13d9b9..3bec599 100644
--- a/Modules/Core/ImageBase/include/otbImage.h
+++ b/Modules/Core/ImageBase/include/otbImage.h
@@ -34,6 +34,49 @@
 
 namespace otb
 {
+namespace internal
+{
+  template < class ImageType >
+  typename ImageType::SpacingType GetSignedSpacing( const ImageType * input)
+  {
+    typename ImageType::SpacingType spacing = input->GetSpacing();
+    typename ImageType::DirectionType direction = input->GetDirection();
+    for ( unsigned int i = 0 ; i < ImageType::ImageDimension ; i++ )
+      {
+      spacing[i] *= direction[i][i] ;
+      }
+    return spacing;
+  }
+
+  template < class InputImage , typename SpacingType >
+  void SetSignedSpacing( InputImage input , SpacingType spacing )
+  {
+    // TODO check for spacing size ==> error
+    typename InputImage::DirectionType direction = input->GetDirection();
+    for ( unsigned int i = 0 ; i < InputImage::VImageDimension ; i++ )
+      {
+      // TODO check if spacing[i] = 0 ==> error
+      if ( spacing[ i ] < 0 )
+        {
+        if ( direction[i][i] > 0 )
+          {
+          for ( unsigned int j = 0 ; j < InputImage::VImageDimension ; j++ )
+            {
+            direction[j][i] = - direction[j][i];
+            }
+          }
+        spacing[i] = -spacing[i];
+        }
+      }
+    input->SetDirection( direction );
+    input->SetSpacing( spacing );
+  }
+}
+}
+
+
+namespace otb
+{
 /** \class Image
  * \brief Creation of an "otb" image which contains metadata.
  *
@@ -174,6 +217,21 @@ public:
   /** Get the six coefficients of affine geoTtransform. */
   virtual VectorType GetGeoTransform(void) const;
 
+  /** Get signed spacing */
+  SpacingType GetSignedSpacing() const;
+
+  // SpacingType GetSpacing() const
+  //   {
+  //     PixelType a;
+  //     a.toto();
+  //     SpacingType t = this->GetSignedSpacing();
+  //     return t ;
+  //   };
+
+  /** Set signed spacing */
+  virtual void SetSignedSpacing( SpacingType spacing );
+  virtual void SetSignedSpacing( double spacing[ VImageDimension ] );
+
   /** Get image corners. */
   virtual VectorType GetUpperLeftCorner(void) const;
   virtual VectorType GetUpperRightCorner(void) const;
diff --git a/Modules/Core/ImageBase/include/otbImage.txx b/Modules/Core/ImageBase/include/otbImage.txx
index 09e3e05..096a725 100644
--- a/Modules/Core/ImageBase/include/otbImage.txx
+++ b/Modules/Core/ImageBase/include/otbImage.txx
@@ -149,6 +149,51 @@ Image<TPixel, VImageDimension>::GetLowerRightCorner(void) const
 }
 
 template <class TPixel, unsigned int VImageDimension>
+typename Image<TPixel, VImageDimension>::SpacingType
+Image<TPixel, VImageDimension>::GetSignedSpacing() const
+{
+  auto spacing = this->GetSpacing();
+  for ( unsigned int i = 0; i < Image::ImageDimension; ++i )
+    {
+    if (this->m_Direction[i][i] < 0 )
+      spacing[i] = - spacing[i];
+    }
+  return spacing;
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void Image<TPixel, VImageDimension>
+::SetSignedSpacing( SpacingType spacing)
+{
+
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+      if ( this->m_Direction[i][i] > 0 )
+        {
+        for ( unsigned j = 0; j < VImageDimension; ++j )
+          {
+          this->m_Direction[j][i] = - this->m_Direction[j][i];
+          }  
+        }
+      spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+  this->ComputeIndexToPhysicalPointMatrices();
+  this->Modified();
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void Image<TPixel, VImageDimension>
+::SetSignedSpacing( double spacing[ VImageDimension ])
+{
+  SpacingType s(spacing);
+  this->SetSignedSpacing(s);
+}
+
+template <class TPixel, unsigned int VImageDimension>
 typename Image<TPixel, VImageDimension>::ImageKeywordlistType
 Image<TPixel, VImageDimension>::GetImageKeywordlist(void)
 {
diff --git a/Modules/Core/ImageBase/include/otbVectorImage.h b/Modules/Core/ImageBase/include/otbVectorImage.h
index d867f48..2fa39e5 100644
--- a/Modules/Core/ImageBase/include/otbVectorImage.h
+++ b/Modules/Core/ImageBase/include/otbVectorImage.h
@@ -144,6 +144,13 @@ public:
   /** Get the six coefficients of affine geoTtransform. */
   virtual VectorType GetGeoTransform(void) const;
 
+    /** Get signed spacing */
+  SpacingType GetSignedSpacing() const;
+
+  /** Set signed spacing */
+  virtual void SetSignedSpacing( SpacingType spacing );
+  virtual void SetSignedSpacing( double spacing[ VImageDimension ] );
+
   /** Get image corners. */
   virtual VectorType GetUpperLeftCorner(void) const;
   virtual VectorType GetUpperRightCorner(void) const;
diff --git a/Modules/Core/ImageBase/include/otbVectorImage.txx b/Modules/Core/ImageBase/include/otbVectorImage.txx
index ef89e66..f6123af 100644
--- a/Modules/Core/ImageBase/include/otbVectorImage.txx
+++ b/Modules/Core/ImageBase/include/otbVectorImage.txx
@@ -151,6 +151,51 @@ VectorImage<TPixel, VImageDimension>::GetLowerRightCorner(void) const
 }
 
 template <class TPixel, unsigned int VImageDimension>
+typename VectorImage<TPixel, VImageDimension>::SpacingType
+VectorImage<TPixel, VImageDimension>::GetSignedSpacing() const
+{
+  auto spacing = this->GetSpacing();
+  for ( unsigned int i = 0; i < VImageDimension; ++i )
+    {
+    if (this->m_Direction[i][i] < 0 )
+      spacing[i] = - spacing[i];
+    }
+  return spacing;
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void VectorImage<TPixel, VImageDimension>
+::SetSignedSpacing( SpacingType spacing)
+{
+
+  for ( unsigned int i = 0; i < VImageDimension; i++ )
+    {
+    if ( spacing[i] < 0.0 )
+      {
+      if ( this->m_Direction[i][i] > 0 )
+        {
+        for ( unsigned j = 0; j < VImageDimension; ++j )
+          {
+          this->m_Direction[j][i] = - this->m_Direction[j][i];
+          }  
+        }
+      spacing[i] = - spacing[i];
+      }
+    }
+  this->SetSpacing(spacing);
+  this->ComputeIndexToPhysicalPointMatrices();
+  this->Modified();
+}
+
+template <class TPixel, unsigned int VImageDimension>
+void VectorImage<TPixel, VImageDimension>
+::SetSignedSpacing( double spacing[ VImageDimension ])
+{
+  SpacingType s(spacing);
+  this->SetSignedSpacing(s);
+}
+
+template <class TPixel, unsigned int VImageDimension>
 typename VectorImage<TPixel, VImageDimension>::ImageKeywordlistType
 VectorImage<TPixel, VImageDimension>::GetImageKeywordlist(void)
 {
diff --git a/Modules/Core/ImageBase/src/otbImageIOBase.cxx b/Modules/Core/ImageBase/src/otbImageIOBase.cxx
index 1e01c55..d88d601 100644
--- a/Modules/Core/ImageBase/src/otbImageIOBase.cxx
+++ b/Modules/Core/ImageBase/src/otbImageIOBase.cxx
@@ -1320,8 +1320,8 @@ ImageIOBase
 void ImageIOBase::PrintSelf(std::ostream& os, itk::Indent indent) const
 {
   Superclass::PrintSelf(os, indent);
-  using namespace std::string_literals;
-  os << indent << "FileName: "s << m_FileName << std::endl;
+
+  os << indent << "FileName: " << m_FileName << std::endl;
   os << indent << "FileType: " << this->GetFileTypeAsString(m_FileType) << std::endl;
   os << indent << "ByteOrder: " << this->GetByteOrderAsString(m_ByteOrder) << std::endl;
   os << indent << "IORegion: " << std::endl;
diff --git a/Modules/Core/ImageBase/test/otbImageTest.cxx b/Modules/Core/ImageBase/test/otbImageTest.cxx
index ab3036a..f95afb8 100644
--- a/Modules/Core/ImageBase/test/otbImageTest.cxx
+++ b/Modules/Core/ImageBase/test/otbImageTest.cxx
@@ -61,7 +61,7 @@ int otbImageTest(int itkNotUsed(argc), char* argv[])
   std::cout << "---------------------" << std::endl;
 
   file << "------ IMAGE --------" << std::endl;
-  file << "Spacing " << image->GetSpacing() << std::endl;
+  file << "Spacing " << image->GetSignedSpacing() << std::endl;
   file << "Origin " << image->GetOrigin() << std::endl;
   file << "Projection REF " << image->GetProjectionRef() << std::endl;
   file << "GCP Projection " << image->GetGCPProjection() << std::endl;
diff --git a/Modules/Core/ImageBase/test/otbMultiChannelExtractROI.cxx b/Modules/Core/ImageBase/test/otbMultiChannelExtractROI.cxx
index f2b41b1..7edf68e 100644
--- a/Modules/Core/ImageBase/test/otbMultiChannelExtractROI.cxx
+++ b/Modules/Core/ImageBase/test/otbMultiChannelExtractROI.cxx
@@ -26,7 +26,7 @@
 
 #include "otbImage.h"
 
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 
 template <typename  InputPixelType /*= unsigned char */, typename OutputPixelType /*= unsigned char*/>
@@ -130,20 +130,11 @@ int generic_otbMultiChannelExtractROI(int itkNotUsed(argc), char * argv[], const
 
   writer->SetInput(extractROIFilter->GetOutput());
 
-  itk::TimeProbe chrono;
-
-  if (computeExtractTime)
-  {
-         chrono.Start();
-  }
-
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   writer->Update();
 
   if (computeExtractTime)
-  {
-         chrono.Stop();
-         std::cout << " Time to compute the extracted image: " << chrono.GetTotal() << " seconds" << std::endl;
-  }
+    std::cout << " Time to compute the extracted image: " << chrono.GetElapsedMilliseconds() << " ms" << std::endl;
 
   std::cout << " Number of channels in the input image: " << reader->GetOutput()->GetNumberOfComponentsPerPixel() <<
   std::endl;
diff --git a/Modules/Core/ImageBase/test/otbVectorImageTest.cxx b/Modules/Core/ImageBase/test/otbVectorImageTest.cxx
index 00d7f37..5fa7664 100644
--- a/Modules/Core/ImageBase/test/otbVectorImageTest.cxx
+++ b/Modules/Core/ImageBase/test/otbVectorImageTest.cxx
@@ -63,7 +63,7 @@ int otbVectorImageLegacyTest(int argc, char* argv[])
   std::cout << "---------------------" << std::endl;
 
   file << "------ IMAGE --------" << std::endl;
-  file << "Spacing " << image->GetSpacing() << std::endl;
+  file << "Spacing " << image->GetSignedSpacing() << std::endl;
   file << "Origin " << image->GetOrigin() << std::endl;
   file << "Projection REF " << image->GetProjectionRef() << std::endl;
   file << "GCP Projection " << image->GetGCPProjection() << std::endl;
diff --git a/Modules/Core/Interpolation/include/otbBSplineInterpolateImageFunction.txx b/Modules/Core/Interpolation/include/otbBSplineInterpolateImageFunction.txx
index b6a8c96..28b3937 100644
--- a/Modules/Core/Interpolation/include/otbBSplineInterpolateImageFunction.txx
+++ b/Modules/Core/Interpolation/include/otbBSplineInterpolateImageFunction.txx
@@ -245,7 +245,7 @@ BSplineInterpolateImageFunction<TImageType, TCoordRep, TCoefficientType>
         }
       derivativeValue[n] += m_Coefficients->GetPixel(coefficientIndex) * tempValue;
       }
-    derivativeValue[n] /= this->GetInputImage()->GetSpacing()[n];   // take spacing into account
+    derivativeValue[n] /= this->GetInputImage()->GetSignedSpacing()[n];   // take spacing into account
     }
 
   return (derivativeValue);
diff --git a/Modules/Core/Interpolation/test/otbProlateValidationTest.cxx b/Modules/Core/Interpolation/test/otbProlateValidationTest.cxx
index 2964cde..b45a5d6 100644
--- a/Modules/Core/Interpolation/test/otbProlateValidationTest.cxx
+++ b/Modules/Core/Interpolation/test/otbProlateValidationTest.cxx
@@ -54,7 +54,7 @@ int otbProlateValidationTest(int itkNotUsed(argc), char * argv[])
   reader->UpdateOutputInformation();
 
   ImageType::PointType   origin = reader->GetOutput()->GetOrigin();
-  ImageType::SpacingType spacing = reader->GetOutput()->GetSpacing();
+  ImageType::SpacingType spacing = reader->GetOutput()->GetSignedSpacing();
   ImageType::SpacingType newSpacing;
   newSpacing[0] = spacing[0] * factor;
   newSpacing[1] = spacing[1] * factor;
diff --git a/Modules/Core/LabelMap/include/otbShapeAttributesLabelMapFilter.txx b/Modules/Core/LabelMap/include/otbShapeAttributesLabelMapFilter.txx
index a2cb207..6393fed 100644
--- a/Modules/Core/LabelMap/include/otbShapeAttributesLabelMapFilter.txx
+++ b/Modules/Core/LabelMap/include/otbShapeAttributesLabelMapFilter.txx
@@ -205,13 +205,13 @@ ShapeAttributesLabelObjectFunctor<TLabelObject, TLabelImage>
   double sizePerPixel = 1;
   for (DimensionType i = 0; i < LabelObjectType::ImageDimension; ++i)
     {
-    sizePerPixel *= vcl_abs(m_LabelImage->GetSpacing()[i]);
+    sizePerPixel *= vcl_abs(m_LabelImage->GetSignedSpacing()[i]);
     }
 
   typename std::vector<double> sizePerPixelPerDimension;
   for (DimensionType i = 0; i < LabelObjectType::ImageDimension; ++i)
     {
-    sizePerPixelPerDimension.push_back(sizePerPixel / vcl_abs(m_LabelImage->GetSpacing()[i]));
+    sizePerPixelPerDimension.push_back(sizePerPixel / vcl_abs(m_LabelImage->GetSignedSpacing()[i]));
     }
 
   // compute the max the index on the border of the image
@@ -367,7 +367,7 @@ ShapeAttributesLabelObjectFunctor<TLabelObject, TLabelImage>
     // get the physical position and the spacing - they are used several times later
     typename TLabelImage::PointType physicalPosition;
     m_LabelImage->TransformIndexToPhysicalPoint(idx, physicalPosition);
-    const typename TLabelImage::SpacingType& spacing = m_LabelImage->GetSpacing();
+    const typename TLabelImage::SpacingType& spacing = m_LabelImage->GetSignedSpacing();
     // the sum of x positions, also reused several times
     double sumX = length * (physicalPosition[0] + (spacing[0] * (length - 1)) / 2.0);
     // the real job - the sum of square of x positions
@@ -406,7 +406,7 @@ ShapeAttributesLabelObjectFunctor<TLabelObject, TLabelImage>
     {
     centroid[i] /= size;
     regionSize[i] = maxs[i] - mins[i] + 1;
-    double s = regionSize[i] * vcl_abs(m_LabelImage->GetSpacing()[i]);
+    double s = regionSize[i] * vcl_abs(m_LabelImage->GetSignedSpacing()[i]);
     minSize = std::min(s, minSize);
     maxSize = std::max(s, maxSize);
     for (DimensionType j = 0; j < LabelObjectType::ImageDimension; ++j)
@@ -550,7 +550,7 @@ ShapeAttributesLabelObjectFunctor<TLabelObject, TLabelImage>
     SimplifyPolygonFunctorType simplifyFunctor;
     polygonFunctor.SetStartIndex(m_LabelImage->GetLargestPossibleRegion().GetIndex());
     polygonFunctor.SetOrigin(m_LabelImage->GetOrigin());
-    polygonFunctor.SetSpacing(m_LabelImage->GetSpacing());
+    polygonFunctor.SetSpacing(m_LabelImage->GetSignedSpacing());
     typename PolygonType::Pointer polygon = simplifyFunctor(polygonFunctor(lo));
     lo->SetPolygon(polygon);
     }
@@ -622,7 +622,7 @@ ShapeAttributesLabelObjectFunctor<TLabelObject, TLabelImage>
         double length = 0;
         for (DimensionType i = 0; i < LabelObjectType::ImageDimension; ++i)
           {
-          length += vcl_pow((iIt1->operator[] (i) - iIt2->operator[] (i)) * m_LabelImage->GetSpacing()[i], 2);
+          length += vcl_pow((iIt1->operator[] (i) - iIt2->operator[] (i)) * m_LabelImage->GetSignedSpacing()[i], 2);
           }
         if (feretDiameter < length)
           {
@@ -853,7 +853,7 @@ ShapeAttributesLabelObjectFunctor<TLabelObject, TLabelImage>
     }
 
   // compute the perimeter based on the intercept counts
-  double perimeter = PerimeterFromInterceptCount( intercepts, m_LabelImage->GetSpacing() );
+  double perimeter = PerimeterFromInterceptCount( intercepts, m_LabelImage->GetSignedSpacing() );
   return perimeter;
 }
 
diff --git a/Modules/Core/LabelMap/test/otbLabelObjectMapVectorizer.cxx b/Modules/Core/LabelMap/test/otbLabelObjectMapVectorizer.cxx
index dbefe32..54de60a 100644
--- a/Modules/Core/LabelMap/test/otbLabelObjectMapVectorizer.cxx
+++ b/Modules/Core/LabelMap/test/otbLabelObjectMapVectorizer.cxx
@@ -26,7 +26,7 @@
 #include "otbVectorData.h"
 #include "otbVectorDataProjectionFilter.h"
 #include "otbVectorDataFileWriter.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include "itkMinimumMaximumImageCalculator.h"
 
 #include "otbCorrectPolygonFunctor.h"
@@ -87,15 +87,13 @@ int otbLabelObjectMapVectorizer(int argc, char * argv[])
   data->GetDataTree()->Add(folder1, document);
   data->SetProjectionRef(lreader->GetOutput()->GetProjectionRef());
 
-  itk::TimeProbe chrono;
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
 
   // If a label is given, extract only this label
   if (argc == 4)
     {
     std::cout << "Label is given; Vectorizing object " << atoi(argv[3]) << std::endl;
-    chrono.Start();
     PolygonType::Pointer polygon = functor(labelMapFilter->GetOutput()->GetLabelObject(atoi(argv[3])));
-    chrono.Stop();
 
     //correct polygon
     PolygonType::Pointer correct_polygon = correctPolygon(polygon);
@@ -117,9 +115,7 @@ int otbLabelObjectMapVectorizer(int argc, char * argv[])
       if (labelMapFilter->GetOutput()->HasLabel(label) && label != labelMapFilter->GetOutput()->GetBackgroundValue())
         {
         std::cout << "Vectorizing object " << label << std::endl;
-        chrono.Start();
         PolygonType::Pointer polygon = functor(labelMapFilter->GetOutput()->GetLabelObject(label));
-        chrono.Stop();
 
         //correct polygon
         PolygonType::Pointer correct_polygon = correctPolygon(polygon);
@@ -131,11 +127,12 @@ int otbLabelObjectMapVectorizer(int argc, char * argv[])
         }
       }
     }
-  std::cout << "Average vectorization time: " << chrono.GetMean() << " s." << std::endl;
+
+  std::cout << "Total vectorization time: " << chrono.GetElapsedMilliseconds() << " ms." << std::endl;
 
   VectorDataFilterType::Pointer vectorDataProjection = VectorDataFilterType::New();
   vectorDataProjection->SetInputOrigin(lreader->GetOutput()->GetOrigin());
-  vectorDataProjection->SetInputSpacing(lreader->GetOutput()->GetSpacing());
+  vectorDataProjection->SetInputSpacing(lreader->GetOutput()->GetSignedSpacing());
   vectorDataProjection->SetInput(data);
 
   writer->SetFileName(outfname);
diff --git a/Modules/Core/Metadata/include/otbNoDataHelper.h b/Modules/Core/Metadata/include/otbNoDataHelper.h
index 9203a6b..4fa8d8b 100644
--- a/Modules/Core/Metadata/include/otbNoDataHelper.h
+++ b/Modules/Core/Metadata/include/otbNoDataHelper.h
@@ -61,18 +61,7 @@ template<typename T> bool IsNoData(const T & pixel, const
   assert(flags.size()>0);
   assert(values.size()>0);
 
-  if(nanIsNoData && vnl_math_isnan(values[0]))
-    return true;
-
-
-  if(flags[0])
-    {
-    return (pixel == values[0]);
-    }
-  else
-    {
-    return false;
-    }
+  return ((nanIsNoData && vnl_math_isnan(pixel)) || (flags[0] && (pixel == values[0])));
 }
 
 /**
diff --git a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
index cae5761..97f504b 100644
--- a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
+++ b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
@@ -25,7 +25,7 @@
 #include "otbMacro.h"
 #include "itkMetaDataObject.h"
 #include "otbImageKeywordlist.h"
-#include "ossimTimeUtilities.h"
+#include "ossim/ossimTimeUtilities.h"
 
 //useful constants
 #include <otbMath.h>
diff --git a/Modules/Core/ObjectList/include/otbObjectList.h b/Modules/Core/ObjectList/include/otbObjectList.h
index 9d6baba..b9db494 100644
--- a/Modules/Core/ObjectList/include/otbObjectList.h
+++ b/Modules/Core/ObjectList/include/otbObjectList.h
@@ -200,7 +200,6 @@ public:
       Iterator lIter(m_Iter + i);
       return lIter;
     }
-
     /**
        * Remove
        */
@@ -210,6 +209,20 @@ public:
       return lIter;
     }
     /**
+     */
+    Iterator
+      operator += ( int i )
+    {
+      return m_Iter + i;
+    }
+    /**
+     */
+    Iterator
+      operator -= ( int i )
+    {
+      return m_Iter - i;
+    }
+    /**
        * Difference comparison operator.
        */
     bool operator !=(const Iterator& it)
diff --git a/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.txx b/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.txx
index 9d2615f..70991ea 100644
--- a/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.txx
+++ b/Modules/Core/SpatialObjects/include/otbSpatialObjectToImageDrawingFilter.txx
@@ -362,11 +362,11 @@ SpatialObjectToImageDrawingFilter<TInputSpatialObject, TOutputImage>
 
   if (specified)
     {
-    OutputImage->SetSpacing(this->m_Spacing);           // set spacing
+    OutputImage->SetSignedSpacing(this->m_Spacing);           // set spacing
     }
   else
     {
-    OutputImage->SetSpacing(InputObject->GetIndexToObjectTransform()->GetScaleComponent());     // set spacing
+    OutputImage->SetSignedSpacing(InputObject->GetIndexToObjectTransform()->GetScaleComponent());     // set spacing
     m_Spacing[0] = InputObject->GetIndexToObjectTransform()->GetScaleComponent()[0];
     m_Spacing[1] = InputObject->GetIndexToObjectTransform()->GetScaleComponent()[1];
     }
diff --git a/Modules/Core/Transform/include/otbGenericRSTransform.h b/Modules/Core/Transform/include/otbGenericRSTransform.h
index 09a8ed3..aac8f94 100644
--- a/Modules/Core/Transform/include/otbGenericRSTransform.h
+++ b/Modules/Core/Transform/include/otbGenericRSTransform.h
@@ -142,7 +142,7 @@ public:
   itkGetConstReferenceMacro(InputOrigin, OriginType);
 
   /** Set the spacing (size of a pixel) of the vector data.
-    * \sa GetSpacing() */
+    * \sa GetSignedSpacing() */
   itkSetMacro(InputSpacing, SpacingType);
   itkGetConstReferenceMacro(InputSpacing, SpacingType);
 
@@ -152,7 +152,7 @@ public:
   itkGetConstReferenceMacro(OutputOrigin, OriginType);
 
   /** Set the spacing (size of a pixel) of the vector data.
-  * \sa GetSpacing() */
+  * \sa GetSignedSpacing() */
   itkSetMacro(OutputSpacing, SpacingType);
   itkGetConstReferenceMacro(OutputSpacing, SpacingType);
 
diff --git a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h
index ee6c50c..97a32a5 100644
--- a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h
+++ b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h
@@ -72,6 +72,7 @@ public:
   typedef typename OutputImageType::PointType       PointType;
   typedef typename OutputImageType::IndexType       IndexType;
   typedef typename OutputImageType::PixelType       PixelType;
+  typedef typename OutputImageType::SpacingType     SpacingType;
   typedef typename OutputImageType::Pointer         OutputImagePointerType;
   typedef typename OutputImageType::RegionType      OutputImageRegionType;
   typedef TDisplacementField                         DisplacementFieldType;
@@ -83,6 +84,14 @@ public:
   itkSetMacro(MaximumDisplacement, DisplacementValueType);
   itkGetConstReferenceMacro(MaximumDisplacement, DisplacementValueType);
 
+  const SpacingType & GetOutputSpacing() const override
+  {
+    return m_OutputSignedSpacing;
+  };
+
+  void SetOutputSpacing( const SpacingType OutputSpacing ) override ;
+  void SetOutputSpacing( const double *values ) override ;
+
 protected:
   /** Constructor */
   StreamingWarpImageFilter();
@@ -108,6 +117,10 @@ private:
   StreamingWarpImageFilter(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
 
+  //Because of itk positive spacing we need this member to be compliant with otb
+  //signed spacing
+  SpacingType m_OutputSignedSpacing;
+
   // Assessment of the maximum displacement for streaming
   DisplacementValueType m_MaximumDisplacement;
 };
diff --git a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx
index 60dc825..211bf8f 100644
--- a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx
+++ b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx
@@ -37,8 +37,51 @@ StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
  {
   // Fill the default maximum displacement
   m_MaximumDisplacement.Fill(1);
+  m_OutputSignedSpacing = this->Superclass::GetOutputSpacing();
  }
 
+
+template<class TInputImage, class TOutputImage, class TDisplacementField>
+void
+StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
+::SetOutputSpacing( const SpacingType outputSpacing )
+{
+  m_OutputSignedSpacing = outputSpacing;
+  SpacingType spacing = outputSpacing;
+  typename TInputImage::DirectionType direction = 
+      this->GetOutput()->GetDirection();
+  for( unsigned int i = 0 ; i < TInputImage::ImageDimension ; ++i )
+    {
+    if ( spacing[i] < 0 )
+      {
+      if ( direction[i][i] > 0 )
+        {
+        for( unsigned int j = 0 ; j < TInputImage::ImageDimension ; ++j )
+          {
+          direction[j][i] = - direction[j][i];
+          }
+        }
+      spacing[i] = - spacing[i];
+      }
+    }
+  this->Superclass::SetOutputSpacing( spacing );
+  this->Superclass::SetOutputDirection( direction );
+  this->Modified();
+}
+
+template<class TInputImage, class TOutputImage, class TDisplacementField>
+void
+StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
+::SetOutputSpacing( const double *values )
+{
+  SpacingType s;
+  for(unsigned int i = 0; i < TInputImage::ImageDimension; ++i)
+    {
+    s[i] = static_cast< typename SpacingType::ValueType >(values[i]);
+    }
+  this->SetOutputSpacing(s);
+}
+
 template<class TInputImage, class TOutputImage, class TDisplacementField>
 void
 StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
@@ -260,7 +303,13 @@ StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
   // second pass on the thread region to mask pixels outside the displacement grid
   const PixelType paddingValue = this->GetEdgePaddingValue();
   OutputImagePointerType outputPtr = this->GetOutput();
-  DisplacementFieldPointerType fieldPtr = this->GetDisplacementField();
+
+  // ITK 4.13 fix const correctness of GetDisplacementField. 
+  // Related commit in ITK: https://github.com/InsightSoftwareConsortium/ITK/commit/0070848b91baf69f04893bc3ce85bcf110c3c63a
+  
+  // DisplacementFieldPointerType fieldPtr = this->GetDisplacementField();
+  const DisplacementFieldType * fieldPtr = this->GetDisplacementField();
+
 
   DisplacementFieldRegionType defRegion = fieldPtr->GetLargestPossibleRegion();
 
diff --git a/Modules/Core/VectorDataBase/include/otbVectorData.h b/Modules/Core/VectorDataBase/include/otbVectorData.h
index 54ea18c..0a1b896 100644
--- a/Modules/Core/VectorDataBase/include/otbVectorData.h
+++ b/Modules/Core/VectorDataBase/include/otbVectorData.h
@@ -103,7 +103,7 @@ public:
 
   /** Set the spacing of the vector data to put it in the corresponding
    * image coordinates
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   virtual void SetSpacing(const SpacingType& spacing);
   virtual void SetSpacing(const double spacing[2]);
   virtual void SetSpacing(const float spacing[2]);
diff --git a/Modules/Detection/RoadExtraction/include/otbGenericRoadExtractionFilter.txx b/Modules/Detection/RoadExtraction/include/otbGenericRoadExtractionFilter.txx
index bb83922..32d2638 100644
--- a/Modules/Detection/RoadExtraction/include/otbGenericRoadExtractionFilter.txx
+++ b/Modules/Detection/RoadExtraction/include/otbGenericRoadExtractionFilter.txx
@@ -82,7 +82,7 @@ GenericRoadExtractionFilter<TInputImage, TOutputPath>
 ::BeforeGenerateData()
 {
   /** Calculation of resolution value */
-  typename InputImageType::SpacingType spacing = this->GetInput()->GetSpacing();
+  typename InputImageType::SpacingType spacing = this->GetInput()->GetSignedSpacing();
   // Getting x Spacing for the resolution
   m_Resolution = static_cast<double>(spacing[0]);
   if (m_Resolution == 0.)
diff --git a/Modules/Detection/RoadExtraction/include/otbImageToPathListAlignFilter.txx b/Modules/Detection/RoadExtraction/include/otbImageToPathListAlignFilter.txx
index 10c0d81..459b093 100644
--- a/Modules/Detection/RoadExtraction/include/otbImageToPathListAlignFilter.txx
+++ b/Modules/Detection/RoadExtraction/include/otbImageToPathListAlignFilter.txx
@@ -239,7 +239,7 @@ ImageToPathListAlignFilter<TInputImage, TOutputPath>
   region.SetIndex(IndexOut);
   m_AngleImage->SetRegions(region);
   m_AngleImage->SetOrigin(InputImage->GetOrigin());
-  m_AngleImage->SetSpacing(InputImage->GetSpacing());
+  m_AngleImage->SetSignedSpacing(InputImage->GetSignedSpacing());
   m_AngleImage->Allocate();
 
   n = Taille[0];
diff --git a/Modules/Feature/Density/include/otbKeyPointDensityImageFilter.txx b/Modules/Feature/Density/include/otbKeyPointDensityImageFilter.txx
index f007b11..e08c7e5 100644
--- a/Modules/Feature/Density/include/otbKeyPointDensityImageFilter.txx
+++ b/Modules/Feature/Density/include/otbKeyPointDensityImageFilter.txx
@@ -70,7 +70,7 @@ KeyPointDensityImageFilter<TInputImage, TOutputImage, TDetector>
   /** Applying the pointsetTodensityImageFilter*/
   m_PointSetToDensityImageFilter->SetInput(m_Detector->GetOutput());
   m_PointSetToDensityImageFilter->SetRadius(m_NeighborhoodRadius);
-  m_PointSetToDensityImageFilter->SetSpacing(ptr->GetSpacing());
+  m_PointSetToDensityImageFilter->SetSpacing(ptr->GetSignedSpacing());
   m_PointSetToDensityImageFilter->SetSize(ptr->GetLargestPossibleRegion().GetSize());
   m_PointSetToDensityImageFilter->SetOrigin(ptr->GetOrigin());
   m_PointSetToDensityImageFilter->Update();
diff --git a/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx b/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx
index 474c6b1..09c672b 100644
--- a/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx
+++ b/Modules/Feature/Density/include/otbPointSetToDensityImageFilter.txx
@@ -113,7 +113,7 @@ PointSetToDensityImageFilter<TInputPointSet, TOutputImage, TDensityFunction>
   region.SetIndex(start);
 
   outputPtr->SetOrigin(this->GetOrigin());
-  outputPtr->SetSpacing(this->GetSpacing());
+  outputPtr->SetSignedSpacing(this->GetSpacing());
   outputPtr->SetRegions(region);
 }
 
diff --git a/Modules/Feature/Density/test/otbPointSetToDensityImageFilterTest.cxx b/Modules/Feature/Density/test/otbPointSetToDensityImageFilterTest.cxx
index 773a117..937d64a 100644
--- a/Modules/Feature/Density/test/otbPointSetToDensityImageFilterTest.cxx
+++ b/Modules/Feature/Density/test/otbPointSetToDensityImageFilterTest.cxx
@@ -63,7 +63,7 @@ int otbPointSetToDensityImageFilterTest(int itkNotUsed(argc), char* argv[])
   /** PointSetImageToDensity ImageFilter*/
   filter->SetInput(detector->GetOutput());
   filter->SetRadius(radius);
-  filter->SetSpacing(reader->GetOutput()->GetSpacing());
+  filter->SetSpacing(reader->GetOutput()->GetSignedSpacing());
   filter->SetSize(reader->GetOutput()->GetLargestPossibleRegion().GetSize());
   filter->SetOrigin(reader->GetOutput()->GetOrigin());
 
diff --git a/Modules/Feature/Descriptors/include/otbForwardFourierMellinTransformImageFilter.txx b/Modules/Feature/Descriptors/include/otbForwardFourierMellinTransformImageFilter.txx
index 4871b8f..9d48d66 100644
--- a/Modules/Feature/Descriptors/include/otbForwardFourierMellinTransformImageFilter.txx
+++ b/Modules/Feature/Descriptors/include/otbForwardFourierMellinTransformImageFilter.txx
@@ -81,7 +81,7 @@ ForwardFourierMellinTransformImageFilter<TPixel, TInterpol, Dimension>
 
   // Compute centre of the transform
   SizeType inputSize = this->GetInput()->GetLargestPossibleRegion().GetSize();
-  SpacingType inputSpacing = this->GetInput()->GetSpacing();
+  SpacingType inputSpacing = this->GetInput()->GetSignedSpacing();
   itk::ContinuousIndex<double,2> centre;
   centre[0] = -0.5 + 0.5 * static_cast<double>(inputSize[0]);
   centre[1] = -0.5 + 0.5 * static_cast<double>(inputSize[1]);
diff --git a/Modules/Feature/Descriptors/include/otbImageToSIFTKeyPointSetFilter.txx b/Modules/Feature/Descriptors/include/otbImageToSIFTKeyPointSetFilter.txx
index 8c3d0e7..e34a5a8 100644
--- a/Modules/Feature/Descriptors/include/otbImageToSIFTKeyPointSetFilter.txx
+++ b/Modules/Feature/Descriptors/include/otbImageToSIFTKeyPointSetFilter.txx
@@ -144,7 +144,7 @@ ImageToSIFTKeyPointSetFilter<TInputImage, TOutputPointSet>
     input = m_ShrinkFilter->GetOutput();
 
     typename InputImageType::PointType   origin1;
-    typename InputImageType::SpacingType spacing = input->GetSpacing();
+    typename InputImageType::SpacingType spacing = input->GetSignedSpacing();
 
     origin1[0] = origin0[0] + spacing[0] * 0.25;
     origin1[1] = origin0[1] + spacing[1] * 0.25;
@@ -181,7 +181,7 @@ ImageToSIFTKeyPointSetFilter<TInputImage, TOutputPointSet>
 
   typename InputImageType::PointType   origin0 = this->GetInput()->GetOrigin();
   typename InputImageType::PointType   origin1;
-  typename InputImageType::SpacingType spacing = m_ExpandFilter->GetOutput()->GetSpacing();
+  typename InputImageType::SpacingType spacing = m_ExpandFilter->GetOutput()->GetSignedSpacing();
 
   origin1[0] = origin0[0] - spacing[0] * 0.5;
   origin1[1] = origin0[1] - spacing[1] * 0.5;
@@ -213,8 +213,8 @@ ImageToSIFTKeyPointSetFilter<TInputImage, TOutputPointSet>
   //
   // with multiply by spacing before filtering, length sigma gaussian
   // is compute in pixel
-  double xsigman = vcl_abs(input->GetSpacing()[0]) * m_Sigma0;
-  double ysigman = vcl_abs(input->GetSpacing()[1]) * m_Sigma0;
+  double xsigman = vcl_abs(input->GetSignedSpacing()[0]) * m_Sigma0;
+  double ysigman = vcl_abs(input->GetSignedSpacing()[1]) * m_Sigma0;
 
   for (lScale = 0; lScale != m_ScalesNumber + 2; lScale++)
     {
@@ -276,7 +276,7 @@ ImageToSIFTKeyPointSetFilter<TInputImage, TOutputPointSet>
     typename ImageListType::Iterator     lIterDoG = m_DoGList->Begin() + 1;
     unsigned int                         lScale = 1;
     OutputPointSetPointerType            outputPointSet = this->GetOutput();
-    typename InputImageType::SpacingType spacing = lIterDoG.Get()->GetSpacing();
+    typename InputImageType::SpacingType spacing = lIterDoG.Get()->GetSignedSpacing();
 
     while ((lIterDoG + 1) != m_DoGList->End())
       {
diff --git a/Modules/Feature/Descriptors/include/otbImageToSURFKeyPointSetFilter.txx b/Modules/Feature/Descriptors/include/otbImageToSURFKeyPointSetFilter.txx
index 4c7ffe0..4221e4b 100644
--- a/Modules/Feature/Descriptors/include/otbImageToSURFKeyPointSetFilter.txx
+++ b/Modules/Feature/Descriptors/include/otbImageToSURFKeyPointSetFilter.txx
@@ -94,7 +94,7 @@ ImageToSURFKeyPointSetFilter<TInputImage, TOutputPointSet>
 
     sigma_in = 2.;
     m_ImageList = ImageListType::New();
-        spacing = this->GetInput()->GetSpacing();
+        spacing = this->GetInput()->GetSignedSpacing();
 
     /*--------------------------------------------------------
     Octave per octave
diff --git a/Modules/Feature/Descriptors/test/otbFourierMellinDescriptors.cxx b/Modules/Feature/Descriptors/test/otbFourierMellinDescriptors.cxx
index 1d0e44e..675f831 100644
--- a/Modules/Feature/Descriptors/test/otbFourierMellinDescriptors.cxx
+++ b/Modules/Feature/Descriptors/test/otbFourierMellinDescriptors.cxx
@@ -218,7 +218,7 @@ int otbFourierMellinDescriptorsRotationInvariant(int itkNotUsed(argc), char * ar
   filter->SetInterpolator(interpolator);
   filter->SetDefaultPixelValue( 100 );
 
-  const InputImageType::SpacingType & spacing = reader->GetOutput()->GetSpacing();
+  const InputImageType::SpacingType & spacing = reader->GetOutput()->GetSignedSpacing();
   const InputImageType::PointType & origin  = reader->GetOutput()->GetOrigin();
   InputImageType::SizeType size =
     reader->GetOutput()->GetLargestPossibleRegion().GetSize();
diff --git a/Modules/Feature/Descriptors/test/otbHistogramOfOrientedGradientCovariantImageFunction.cxx b/Modules/Feature/Descriptors/test/otbHistogramOfOrientedGradientCovariantImageFunction.cxx
index 66538c9..1732f66 100644
--- a/Modules/Feature/Descriptors/test/otbHistogramOfOrientedGradientCovariantImageFunction.cxx
+++ b/Modules/Feature/Descriptors/test/otbHistogramOfOrientedGradientCovariantImageFunction.cxx
@@ -60,6 +60,7 @@ int otbHistogramOfOrientedGradientCovariantImageFunction(int itkNotUsed(argc), c
   GradientFilterType::Pointer gradient = GradientFilterType::New();
   gradient->SetInput(reader->GetOutput());
   gradient->SetUseImageSpacing(false);
+  gradient->SetUseImageDirection(false);
   gradient->Update();
 
   // Instantiating object
diff --git a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterDistanceMap.cxx b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterDistanceMap.cxx
index d9741ee..afbeddd 100644
--- a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterDistanceMap.cxx
+++ b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterDistanceMap.cxx
@@ -74,7 +74,7 @@ OutputImageType::Pointer sift(ImageType::Pointer input,
   pointSetFilter->SetOutsideValue(0);
   pointSetFilter->SetInsideValue(255);
   pointSetFilter->SetSize(input->GetLargestPossibleRegion().GetSize());
-  pointSetFilter->SetSpacing(input->GetSpacing());
+  pointSetFilter->SetSpacing(input->GetSignedSpacing());
   pointSetFilter->SetOrigin(input->GetOrigin());
   pointSetFilter->Update();
 
@@ -116,7 +116,7 @@ ImageType::Pointer rotate(ImageType::Pointer input,
   TransformType::OutputVectorType translation1;
   TransformType::OutputVectorType translation2;
 
-  const ImageType::SpacingType& spacing = input->GetSpacing();
+  const ImageType::SpacingType& spacing = input->GetSignedSpacing();
   const ImageType::PointType&   origin  = input->GetOrigin();
   ImageType::SizeType           size = input->GetLargestPossibleRegion().GetSize();
 
@@ -155,7 +155,7 @@ OutputImageType::Pointer invRotate(OutputImageType::Pointer input,
   TransformType::OutputVectorType translation1;
   TransformType::OutputVectorType translation2;
 
-  const ImageType::SpacingType& spacing = input->GetSpacing();
+  const ImageType::SpacingType& spacing = input->GetSignedSpacing();
   const ImageType::PointType&   origin  = input->GetOrigin();
   ImageType::SizeType           size = input->GetLargestPossibleRegion().GetSize();
 
diff --git a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputImage.cxx b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputImage.cxx
index e8e5671..355dc8d 100644
--- a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputImage.cxx
+++ b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputImage.cxx
@@ -116,7 +116,7 @@ int otbImageToSIFTKeyPointSetFilterOutputImage(int itkNotUsed(argc), char * argv
   std::cout << "Copy Input image in Output image" << std::endl;
 
   PointsIteratorType        pIt = filter->GetOutput()->GetPoints()->Begin();
-  ImageType::SpacingType    spacing = reader->GetOutput()->GetSpacing();
+  ImageType::SpacingType    spacing = reader->GetOutput()->GetSignedSpacing();
   ImageType::PointType      origin = reader->GetOutput()->GetOrigin();
   //OutputImageType::SizeType size = outputImage->GetLargestPossibleRegion().GetSize();
 
diff --git a/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.txx b/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.txx
index a9c1e88..7f8aa38 100644
--- a/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.txx
+++ b/Modules/Feature/Edge/include/otbHoughTransform2DLinesImageFilter.txx
@@ -195,7 +195,7 @@ HoughTransform2DLinesImageFilter<TInputPixelType, TOutputPixelType>
   m_SimplifyAccumulator = OutputImageType::New();
   m_SimplifyAccumulator->SetRegions(outputImage->GetLargestPossibleRegion());
   m_SimplifyAccumulator->SetOrigin(inputImage->GetOrigin());
-  m_SimplifyAccumulator->SetSpacing(inputImage->GetSpacing());
+  m_SimplifyAccumulator->SetSignedSpacing(inputImage->GetSignedSpacing());
   m_SimplifyAccumulator->Allocate();
   m_SimplifyAccumulator->FillBuffer(0);
 
diff --git a/Modules/Feature/Edge/include/otbLineSegmentDetector.txx b/Modules/Feature/Edge/include/otbLineSegmentDetector.txx
index aecdb8b..c06344e 100644
--- a/Modules/Feature/Edge/include/otbLineSegmentDetector.txx
+++ b/Modules/Feature/Edge/include/otbLineSegmentDetector.txx
@@ -323,7 +323,7 @@ LineSegmentDetector<TInputImage, TPrecision>
   this->GetOutput(0)->GetDataTree()->Add(folder, document);
   this->GetOutput(0)->SetProjectionRef(this->GetInput()->GetProjectionRef());
 
-  SpacingType spacing = this->GetInput()->GetSpacing();
+  SpacingType spacing = this->GetInput()->GetSignedSpacing();
   OriginType  origin  = this->GetInput()->GetOrigin();
 
   /** store the lines*/
diff --git a/Modules/Feature/Edge/include/otbLocalHoughFilter.txx b/Modules/Feature/Edge/include/otbLocalHoughFilter.txx
index 0d78f68..a3b0d6e 100644
--- a/Modules/Feature/Edge/include/otbLocalHoughFilter.txx
+++ b/Modules/Feature/Edge/include/otbLocalHoughFilter.txx
@@ -195,7 +195,7 @@ LocalHoughFilter<TInputImage>
       region.SetIndex(index);
       localImage->SetRegions(region);
       localImage->SetOrigin(filterImage->GetOrigin());
-      localImage->SetSpacing(filterImage->GetSpacing());
+      localImage->SetSignedSpacing(filterImage->GetSignedSpacing());
       localImage->Allocate();
 
       typedef itk::ImageRegionIteratorWithIndex<InputImageType>      LocalIteratorType;
diff --git a/Modules/Feature/Edge/include/otbTouziEdgeDetectorImageFilter.txx b/Modules/Feature/Edge/include/otbTouziEdgeDetectorImageFilter.txx
index fec32eb..8f80efc 100644
--- a/Modules/Feature/Edge/include/otbTouziEdgeDetectorImageFilter.txx
+++ b/Modules/Feature/Edge/include/otbTouziEdgeDetectorImageFilter.txx
@@ -115,7 +115,7 @@ TouziEdgeDetectorImageFilter<TInputImage, TOutputImage, TOutputImageDirection>
   region.SetIndex(output->GetRequestedRegion().GetIndex());
   direction->SetRegions(region);
   direction->SetOrigin(output->GetOrigin());
-  direction->SetSpacing(output->GetSpacing());
+  direction->SetSignedSpacing(output->GetSignedSpacing());
   direction->Allocate();
 }
 
diff --git a/Modules/Feature/Moments/test/otbFlusserMomentsImageFunction.cxx b/Modules/Feature/Moments/test/otbFlusserMomentsImageFunction.cxx
index bdeef74..e2e5c38 100644
--- a/Modules/Feature/Moments/test/otbFlusserMomentsImageFunction.cxx
+++ b/Modules/Feature/Moments/test/otbFlusserMomentsImageFunction.cxx
@@ -205,7 +205,7 @@ int otbFlusserMomentsImageFunctionRotationInvariant(int itkNotUsed(argc), char *
   filter->SetInterpolator(interpolator);
   filter->SetDefaultPixelValue( 100 );
 
-  const InputImageType::SpacingType & spacing = reader->GetOutput()->GetSpacing();
+  const InputImageType::SpacingType & spacing = reader->GetOutput()->GetSignedSpacing();
   const InputImageType::PointType & origin  = reader->GetOutput()->GetOrigin();
   InputImageType::SizeType size =
       reader->GetOutput()->GetLargestPossibleRegion().GetSize();
diff --git a/Modules/Feature/Moments/test/otbHuMomentsImageFunction.cxx b/Modules/Feature/Moments/test/otbHuMomentsImageFunction.cxx
index eceb2d3..3a1da3f 100644
--- a/Modules/Feature/Moments/test/otbHuMomentsImageFunction.cxx
+++ b/Modules/Feature/Moments/test/otbHuMomentsImageFunction.cxx
@@ -204,7 +204,7 @@ int otbHuMomentsImageFunctionRotationInvariant(int itkNotUsed(argc), char * argv
   filter->SetInterpolator(interpolator);
   filter->SetDefaultPixelValue( 100 );
 
-  const InputImageType::SpacingType & spacing = reader->GetOutput()->GetSpacing();
+  const InputImageType::SpacingType & spacing = reader->GetOutput()->GetSignedSpacing();
   const InputImageType::PointType & origin  = reader->GetOutput()->GetOrigin();
   InputImageType::SizeType size =
       reader->GetOutput()->GetLargestPossibleRegion().GetSize();
diff --git a/Modules/Feature/SeamCarving/include/otbAddCarvingPathFilter.txx b/Modules/Feature/SeamCarving/include/otbAddCarvingPathFilter.txx
index d43274f..506f894 100644
--- a/Modules/Feature/SeamCarving/include/otbAddCarvingPathFilter.txx
+++ b/Modules/Feature/SeamCarving/include/otbAddCarvingPathFilter.txx
@@ -226,7 +226,7 @@ AddCarvingPathFilter<TInputImage, TInputPath, TOutputImage>
   // we need to compute the output spacing, the output image size, and the
   // output image start index
   const typename TInputImage::SpacingType&
-                                        inputSpacing = inputPtr->GetSpacing();
+                                        inputSpacing = inputPtr->GetSignedSpacing();
   const typename TInputImage::SizeType& inputSize
     = inputPtr->GetLargestPossibleRegion().GetSize();
   const typename TInputImage::IndexType& inputStartIndex
@@ -245,7 +245,7 @@ AddCarvingPathFilter<TInputImage, TInputPath, TOutputImage>
   // we remove one column of the image
   outputSize[dir0] = inputSize[dir0] + 1;
 
-  outputPtr->SetSpacing(outputSpacing);
+  outputPtr->SetSignedSpacing(outputSpacing);
 
   typename TOutputImage::RegionType outputLargestPossibleRegion;
   outputLargestPossibleRegion.SetSize(outputSize);
diff --git a/Modules/Feature/SeamCarving/include/otbRemoveCarvingPathFilter.txx b/Modules/Feature/SeamCarving/include/otbRemoveCarvingPathFilter.txx
index ceed579..5052be6 100644
--- a/Modules/Feature/SeamCarving/include/otbRemoveCarvingPathFilter.txx
+++ b/Modules/Feature/SeamCarving/include/otbRemoveCarvingPathFilter.txx
@@ -191,7 +191,7 @@ RemoveCarvingPathFilter<TInputImage, TInputPath, TOutputImage>
   // we need to compute the output spacing, the output image size, and the
   // output image start index
   const typename TInputImage::SpacingType&
-                                        inputSpacing = inputPtr->GetSpacing();
+                                        inputSpacing = inputPtr->GetSignedSpacing();
   const typename TInputImage::SizeType& inputSize
     = inputPtr->GetLargestPossibleRegion().GetSize();
   const typename TInputImage::IndexType& inputStartIndex
@@ -210,7 +210,7 @@ RemoveCarvingPathFilter<TInputImage, TInputPath, TOutputImage>
   // we remove one column of the image
   outputSize[dir0] = inputSize[dir0] - 1;
 
-  outputPtr->SetSpacing(outputSpacing);
+  outputPtr->SetSignedSpacing(outputSpacing);
 
   typename TOutputImage::RegionType outputLargestPossibleRegion;
   outputLargestPossibleRegion.SetSize(outputSize);
diff --git a/Modules/Feature/Textures/include/otbScalarImageToAdvancedTexturesFilter.txx b/Modules/Feature/Textures/include/otbScalarImageToAdvancedTexturesFilter.txx
index 94a5cbf..43ab8ca 100644
--- a/Modules/Feature/Textures/include/otbScalarImageToAdvancedTexturesFilter.txx
+++ b/Modules/Feature/Textures/include/otbScalarImageToAdvancedTexturesFilter.txx
@@ -212,7 +212,7 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
   outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
   outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);
 
-  typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSpacing();
+  typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSignedSpacing();
   outSpacing[0] *= m_SubsampleFactor[0];
   outSpacing[1] *= m_SubsampleFactor[1];
 
@@ -224,7 +224,7 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
     OutputImagePointerType outputPtr = this->GetOutput(i);
     outputPtr->SetLargestPossibleRegion(outputRegion);
     outputPtr->SetOrigin(outOrigin);
-    outputPtr->SetSpacing(outSpacing);
+    outputPtr->SetSignedSpacing(outSpacing);
     }
 }
 
diff --git a/Modules/Feature/Textures/include/otbScalarImageToHigherOrderTexturesFilter.txx b/Modules/Feature/Textures/include/otbScalarImageToHigherOrderTexturesFilter.txx
index abeba22..9c7aed6 100644
--- a/Modules/Feature/Textures/include/otbScalarImageToHigherOrderTexturesFilter.txx
+++ b/Modules/Feature/Textures/include/otbScalarImageToHigherOrderTexturesFilter.txx
@@ -254,7 +254,7 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
   outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
   outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);
 
-  typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSpacing();
+  typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSignedSpacing();
   outSpacing[0] *= m_SubsampleFactor[0];
   outSpacing[1] *= m_SubsampleFactor[1];
 
@@ -266,7 +266,7 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
     OutputImagePointerType outputPtr = this->GetOutput(i);
     outputPtr->SetLargestPossibleRegion(outputRegion);
     outputPtr->SetOrigin(outOrigin);
-    outputPtr->SetSpacing(outSpacing);
+    outputPtr->SetSignedSpacing(outSpacing);
     }
 }
 
diff --git a/Modules/Feature/Textures/include/otbScalarImageToTexturesFilter.txx b/Modules/Feature/Textures/include/otbScalarImageToTexturesFilter.txx
index 5939697..e7473f7 100644
--- a/Modules/Feature/Textures/include/otbScalarImageToTexturesFilter.txx
+++ b/Modules/Feature/Textures/include/otbScalarImageToTexturesFilter.txx
@@ -187,7 +187,7 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
   outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
   outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);
 
-  typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSpacing();
+  typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSignedSpacing();
   outSpacing[0] *= m_SubsampleFactor[0];
   outSpacing[1] *= m_SubsampleFactor[1];
 
@@ -199,7 +199,7 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
     OutputImagePointerType outputPtr = this->GetOutput(i);
     outputPtr->SetLargestPossibleRegion(outputRegion);
     outputPtr->SetOrigin(outOrigin);
-    outputPtr->SetSpacing(outSpacing);
+    outputPtr->SetSignedSpacing(outSpacing);
     }
 }
 
diff --git a/Modules/ThirdParty/Ossim/otb-module-init.cmake b/Modules/Filtering/Contrast/CMakeLists.txt
similarity index 94%
copy from Modules/ThirdParty/Ossim/otb-module-init.cmake
copy to Modules/Filtering/Contrast/CMakeLists.txt
index 12dd307..45a89f2 100644
--- a/Modules/ThirdParty/Ossim/otb-module-init.cmake
+++ b/Modules/Filtering/Contrast/CMakeLists.txt
@@ -18,4 +18,5 @@
 # limitations under the License.
 #
 
-find_package ( Ossim REQUIRED )
+project(OTBContrast)
+otb_module_impl()
\ No newline at end of file
diff --git a/Modules/Filtering/Contrast/include/otbApplyGainFilter.h b/Modules/Filtering/Contrast/include/otbApplyGainFilter.h
new file mode 100644
index 0000000..c735725
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbApplyGainFilter.h
@@ -0,0 +1,145 @@
+/*
+ * 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 otbApplyGainFilter_h
+#define otbApplyGainFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "otbImage.h"
+
+namespace otb
+{
+
+/** \class ApplyGainFilter
+ *  \brief Apply gain on the input image with a bilineare interpolation
+ *
+ *  This class implements the third part of the CLAHE algorithm. It's aim 
+ *  is to apply the computed gain with a bilineare interpolation. The gain 
+ *  is in a look up table, and the minimum and maximum asked by the filter
+ *  should be the same as the one used to compute those look up table.
+ *
+ * \ingroup OTBContrast
+ */
+
+template < class TInputImage , class TLut , class TOutputImage >
+class ITK_EXPORT ApplyGainFilter :
+  public itk::ImageToImageFilter< TInputImage , TOutputImage >
+{
+public :
+  /** typedef for standard classes. */
+
+  typedef TInputImage InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  typedef ApplyGainFilter Self;
+  typedef itk::ImageToImageFilter< InputImageType, OutputImageType > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
+
+  typedef TLut LutType;
+  typedef typename InputImageType::InternalPixelType InputPixelType;
+  typedef typename OutputImageType::InternalPixelType OutputPixelType;
+  typedef typename OutputImageType::RegionType OutputImageRegionType;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self)
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(ComputeHistoFilter, ImageToImageFilter)
+
+  /** Get/Set macro to get/set the nodata value */
+  itkSetMacro(NoData, InputPixelType)
+  itkGetMacro(NoData, InputPixelType)
+
+  /** Get/Set macro to get/set the nodata flag value */
+  itkBooleanMacro(NoDataFlag)
+  itkGetMacro(NoDataFlag, bool)
+  itkSetMacro(NoDataFlag, bool)
+
+  /** Get/Set macro to get/set the ThumbSizeFromSpacing flag value */
+  itkBooleanMacro(ThumbSizeFromSpacing)
+  itkGetMacro(ThumbSizeFromSpacing, bool)
+  itkSetMacro(ThumbSizeFromSpacing, bool)
+
+  /** Get/Set macro to get/set the thumbnail's size */
+  itkSetMacro(ThumbSize, typename InputImageType::SizeType)
+  itkGetMacro(ThumbSize, typename InputImageType::SizeType)
+
+  /** Get/Set macro to get/set the minimum value */
+  itkSetMacro(Min, InputPixelType)
+  itkGetMacro(Min, InputPixelType)
+
+  /** Get/Set macro to get/set the maximum value */
+  itkSetMacro(Max, InputPixelType)
+  itkGetMacro(Max, InputPixelType)
+
+  /** Set the input look up table*/
+  void SetInputLut( const LutType * lut) ;
+
+  /** Set the input image*/
+  void SetInputImage( const InputImageType * input) ;
+
+protected :
+  ApplyGainFilter();
+  ~ApplyGainFilter() override {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
+  
+  /** Get the input image*/  
+  const InputImageType * GetInputImage() const;
+
+  /** Get the input look up table*/
+  const LutType * GetInputLut() const;
+
+  void GenerateInputRequestedRegion() override;
+
+  void BeforeThreadedGenerateData() override;
+
+  void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
+                            itk::ThreadIdType threadId) override;
+  void VerifyInputInformation() override {} ;
+
+private :
+  ApplyGainFilter(const Self &) = delete ;
+  void operator =(const Self&) = delete ; 
+
+  /** Bilinear interpolation of the gain between the different window.*/
+  double InterpolateGain( typename LutType::ConstPointer gridLut ,
+                       unsigned int pixelValue , 
+                       typename InputImageType::IndexType index);
+
+  InputPixelType m_NoData;
+  InputPixelType m_Min;
+  InputPixelType m_Max;
+  bool m_NoDataFlag;
+  bool m_ThumbSizeFromSpacing;
+  double m_Step;
+  typename LutType::SizeType m_LutSize;
+  typename InputImageType::SizeType m_ThumbSize;
+
+
+};
+
+}  // End namespace otb
+  
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbApplyGainFilter.txx"
+#endif
+
+
+#endif
diff --git a/Modules/Filtering/Contrast/include/otbApplyGainFilter.txx b/Modules/Filtering/Contrast/include/otbApplyGainFilter.txx
new file mode 100644
index 0000000..28bd851
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbApplyGainFilter.txx
@@ -0,0 +1,224 @@
+/*
+ * 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 otbApplyGainFilter_txx
+#define otbApplyGainFilter_txx
+
+#include "otbApplyGainFilter.h"
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIteratorWithIndex.h"
+#include "itkContinuousIndex.h"
+
+#include <limits>
+
+namespace otb
+{
+template <class TInputImage , class TLut , class TOutputImage >
+ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::ApplyGainFilter()
+{
+  this->SetNumberOfRequiredInputs(2);
+  m_Min = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_Max = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_NoData = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_NoDataFlag = false;
+  m_ThumbSizeFromSpacing = true;
+  m_Step = -1;
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+void ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::SetInputImage(const InputImageType * input)
+{
+  // Process object is not const-correct so the const casting is required.
+  this->SetNthInput( 0 , const_cast<InputImageType *>( input ) );
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+const TInputImage * ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::GetInputImage() const
+{
+  return static_cast< const InputImageType * >
+        ( this->itk::ProcessObject::GetInput(0) );
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+void ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::SetInputLut(const LutType * lut)
+{
+  // Process object is not const-correct so the const casting is required.
+  this->SetNthInput( 1 , const_cast<LutType *>( lut ) );
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+const TLut * ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::GetInputLut() const
+{
+  return static_cast< const LutType * >
+       ( this->itk::ProcessObject::GetInput(1) );
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+void ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::GenerateInputRequestedRegion()
+{
+  typename InputImageType::Pointer input ( 
+    const_cast<InputImageType *>( GetInputImage() ) );
+  typename LutType::Pointer lut ( const_cast<LutType *>( GetInputLut() ) );
+  typename OutputImageType::Pointer output ( this->GetOutput() );
+  
+  lut->SetRequestedRegion( lut->GetLargestPossibleRegion() );
+  input->SetRequestedRegion( output->GetRequestedRegion() );
+  if ( input->GetRequestedRegion().GetNumberOfPixels() == 0 )
+  {
+  input->SetRequestedRegionToLargestPossibleRegion();
+  }
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+void ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::BeforeThreadedGenerateData()
+{
+  typename LutType::ConstPointer lut ( GetInputLut() );
+  typename InputImageType::ConstPointer input ( GetInputImage() );
+  if ( m_ThumbSizeFromSpacing )
+    {
+    m_ThumbSize[0] = std::round( lut->GetSignedSpacing()[0] 
+          / input->GetSignedSpacing()[0] );
+    m_ThumbSize[1] = std::round( lut->GetSignedSpacing()[1] 
+          / input->GetSignedSpacing()[1] );
+    }
+  m_Step = static_cast<double>( m_Max - m_Min ) \
+                / static_cast<double>( lut->GetVectorLength() - 1 );
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+void ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread ,
+                             itk::ThreadIdType itkNotUsed(threadId) )
+{
+  assert( m_Step > 0 );
+  // TODO error
+  // support progress methods/callbacks
+  // itk::ProgressReporter progress(this , threadId , 
+  //               outputRegionForThread.GetNumberOfPixels() );
+
+  typename InputImageType::ConstPointer input ( GetInputImage() );
+  typename LutType::ConstPointer lut ( GetInputLut() );
+  typename OutputImageType::Pointer output ( this->GetOutput() );
+  typename InputImageType::RegionType inputRegionForThread( 
+    outputRegionForThread );
+
+
+  itk::ImageRegionConstIteratorWithIndex < InputImageType > it ( input , 
+                                                        inputRegionForThread );
+  itk::ImageRegionIterator <OutputImageType > oit ( output ,
+                                                    outputRegionForThread );
+
+  unsigned int pixelLutValue(0);
+  double gain(0.0) , newValue(0);
+  InputPixelType currentPixel(0);
+
+  for( it.GoToBegin() , oit.GoToBegin() ; !oit.IsAtEnd() || !it.IsAtEnd() ;
+      ++oit , ++it )
+    {
+    currentPixel = it.Get();
+    newValue = static_cast< double > ( currentPixel );
+    if( !( ( currentPixel == m_NoData && m_NoDataFlag ) ||
+              currentPixel > m_Max || currentPixel < m_Min ) )
+      {
+      pixelLutValue =  static_cast< unsigned int > (
+                      std::round( ( currentPixel - m_Min ) / m_Step ) );
+      gain = InterpolateGain( lut , pixelLutValue , it.GetIndex() );
+      newValue *= gain;
+      }
+    oit.Set( static_cast<OutputPixelType>( newValue ) );
+    }
+    assert ( oit.IsAtEnd() && it.IsAtEnd() );
+}
+
+template <class TInputImage , class TLut , class TOutputImage >
+double ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::InterpolateGain( typename LutType::ConstPointer gridLut,
+                 unsigned int pixelLutValue ,
+                 typename InputImageType::IndexType index)
+{
+  typename InputImageType::PointType pixelPoint;
+  typename itk::ContinuousIndex< double , 2 > pixelIndex;
+  typename InputImageType::ConstPointer input ( GetInputImage() );
+  typename LutType::ConstPointer lut ( GetInputLut() );
+  input->TransformIndexToPhysicalPoint( index , pixelPoint );
+  lut->TransformPhysicalPointToContinuousIndex( pixelPoint , pixelIndex );
+  std::vector< typename LutType::IndexType > neighbors(4);
+  neighbors[0][0] = std::floor(pixelIndex[0]) ; 
+  neighbors[0][1] = std::floor(pixelIndex[1]) ;
+  neighbors[1][0] = neighbors[0][0] + 1 ;
+  neighbors[1][1] = neighbors[0][1] ;
+  neighbors[2][0] = neighbors[0][0] ;
+  neighbors[2][1] = neighbors[0][1] + 1 ;
+  neighbors[3][0] = neighbors[0][0] + 1 ;
+  neighbors[3][1] = neighbors[0][1] + 1 ;
+  float gain(0.f) , w(0.f) , wtm(0.f);
+  typename LutType::IndexType maxIndex;
+  maxIndex[0] = lut->GetLargestPossibleRegion().GetSize()[0];
+  maxIndex[1] = lut->GetLargestPossibleRegion().GetSize()[1];
+  for ( auto i : neighbors )
+    {
+    if ( i[0] < 0 || i[1] < 0  || i[0] >= maxIndex[0] || i[1] >= maxIndex[1] )
+      continue;
+    if ( gridLut->GetPixel(i)[pixelLutValue] == -1 )
+      continue;
+    wtm = ( 1 - std::abs( pixelIndex[0] - i[0] ) ) 
+          * ( 1 - std::abs( pixelIndex[1] - i[1] ) );
+    gain += gridLut->GetPixel(i)[pixelLutValue] * wtm;
+    w += wtm; 
+    }
+  if ( w == 0 )
+    {
+    w = 1;
+    gain = 1;
+    }
+
+  return gain/w;
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage , class TLut , class TOutputImage >
+void ApplyGainFilter < TInputImage , TLut , TOutputImage >
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "Is no data activated : " << m_NoDataFlag << std::endl;
+  os << indent << "No Data : " << m_NoData << std::endl;
+  os << indent << "Minimum : " << m_Min << std::endl;
+  os << indent << "Maximum : " << m_Max << std::endl;
+  os << indent << "Step : " << m_Step << std::endl;
+  os << indent << "Look up table size : " << m_LutSize << std::endl;
+  os << indent << "Is ThumbSize from sapcing is activated : " 
+                  << m_NoDataFlag << std::endl;
+  os << indent << "Thumbnail size : " << m_ThumbSize << std::endl;
+}
+
+  
+}  // End namespace otb
+
+#endif
diff --git a/Modules/Filtering/Contrast/include/otbCLHistogramEqualizationFilter.h b/Modules/Filtering/Contrast/include/otbCLHistogramEqualizationFilter.h
new file mode 100644
index 0000000..edd5167
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbCLHistogramEqualizationFilter.h
@@ -0,0 +1,186 @@
+/*
+ * 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 otbCLHistogramEqualizationFilter_h
+#define otbCLHistogramEqualizationFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbComputeHistoFilter.h"
+#include "otbComputeGainLutFilter.h"
+#include "otbApplyGainFilter.h"
+#include "itkStreamingImageFilter.h"
+#include "otbInPlacePassFilter.h"
+
+namespace otb
+{
+
+/** \class CLHistogramEqualizationFilter
+ *  \brief Implement CLAHE algorithm
+ *  
+ *  This class implement CLAHE algorithm. It is a composite filter that gathers
+ *  the 3 filters (ComputeHisto, ComputeGainLut, ApplyGain) and pipes them with
+ *  additional filters (InPlacePass and StreamingImage) in order to make 
+ *  streaming available. 
+ * \ingroup OTBContrast
+ */
+
+template < class TInputImage , class TOutputImage >
+class ITK_EXPORT CLHistogramEqualizationFilter :
+  public itk::ImageToImageFilter< TInputImage , TOutputImage >
+{
+public :
+  /** typedef for standard classes. */
+
+  typedef TInputImage InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  typedef CLHistogramEqualizationFilter Self;
+  typedef itk::ImageToImageFilter< InputImageType, OutputImageType > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
+
+  typedef otb::VectorImage< unsigned int , 2 > HistogramType;
+  typedef otb::VectorImage< double , 2 > LutType;
+
+  typedef itk::StreamingImageFilter< LutType , LutType >
+    StreamingImageFilter;
+
+  typedef otb::InPlacePassFilter < InputImageType > BufferFilter;
+
+  typedef otb::ComputeHistoFilter< InputImageType , HistogramType >
+    HistoFilter;
+
+  typedef otb::ComputeGainLutFilter< HistogramType , LutType >
+    GainLutFilter;
+
+  typedef otb::ApplyGainFilter< InputImageType , LutType , OutputImageType >
+    ApplyGainFilter;
+
+  typedef typename InputImageType::PixelType InputPixelType;
+  typedef typename OutputImageType::RegionType OutputImageRegionType;
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self)
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(CLHistogramEqualizationFilter, ImageToImageFilter)
+
+  itkGetMacro(Min , InputPixelType)
+  // itkSetMacro(Min, InputPixelType)
+  void SetMin( InputPixelType min )
+    {
+    m_HistoFilter->SetMin(min);
+    m_GainLutFilter->SetMin(min);
+    m_ApplyGainFilter->SetMin(min);
+    m_Min = min;
+    };
+
+  itkGetMacro(Max , InputPixelType)
+  // itkSetMacro(Max, InputPixelType)
+  void SetMax( InputPixelType max )
+    {
+    m_HistoFilter->SetMax(max);
+    m_GainLutFilter->SetMax(max);
+    m_ApplyGainFilter->SetMax(max);
+    m_Max = max;
+    };
+
+  itkGetMacro(NbBin , unsigned long)
+  // itkSetMacro(NbBin, unsigned long)
+  void SetNbBin( unsigned long bin )
+    {
+    m_HistoFilter->SetNbBin(bin);
+    m_NbBin = bin;
+    };
+
+  itkGetMacro(ThumbSize , typename InputImageType::SizeType)
+  // itkSetMacro(ThumbSize, typename InputImageType::SizeType)
+  void SetThumbSize( typename InputImageType::SizeType size )
+    {
+    m_HistoFilter->SetThumbSize(size);
+    m_ApplyGainFilter->SetThumbSize(size);
+    m_GainLutFilter->SetNbPixel(size[0]*size[1]);
+    m_ThumbSize = size;
+    };
+
+  itkGetMacro(Threshold , double)
+  // itkSetMacro(Threshold, double)
+  void SetThreshold( double t )
+    {
+    m_HistoFilter->SetThreshold(t);
+    m_Threshold = t;
+    };
+
+  itkGetMacro(NoData , InputPixelType)
+  // itkSetMacro(NoData, InputPixelType)
+  void SetNoData( InputPixelType n )
+    {
+    m_HistoFilter->SetNoData(n);
+    m_ApplyGainFilter->SetNoData(n);
+    m_NoData = n;
+    }
+
+
+  itkGetMacro(NoDataFlag , bool)
+  // itkSetMacro(NoDataFlag, bool)
+  void SetNoDataFlag( bool flag )
+    {
+    m_HistoFilter->SetNoDataFlag(flag);
+    m_ApplyGainFilter->SetNoDataFlag(flag);
+    m_NoDataFlag = flag;
+    }
+
+protected :
+  CLHistogramEqualizationFilter();
+  ~CLHistogramEqualizationFilter() override {}
+
+  void PrintSelf(std::ostream& os, itk::Indent indent) const override ;
+
+  void UpdateOutputInformation() override;
+
+  void PropagateRequestedRegion( itk::DataObject * output  ) override;
+
+  void GenerateData() override;
+
+private :
+  CLHistogramEqualizationFilter(const Self &) = delete ;
+  void operator =(const Self&) = delete ;
+
+  typename HistoFilter::Pointer m_HistoFilter;
+  typename GainLutFilter::Pointer m_GainLutFilter;
+  typename ApplyGainFilter::Pointer m_ApplyGainFilter;
+  typename StreamingImageFilter::Pointer m_StreamingImageFilter;
+  typename BufferFilter::Pointer m_BufferFilter;
+  InputPixelType m_Min , m_Max , m_NoData;
+  unsigned long m_NbBin;
+  typename InputImageType::SizeType m_ThumbSize;
+  double m_Threshold;
+  bool m_NoDataFlag;
+
+};
+
+}  // End namespace otb
+  
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbCLHistogramEqualizationFilter.txx"
+#endif
+
+
+#endif
diff --git a/Modules/Filtering/Contrast/include/otbCLHistogramEqualizationFilter.txx b/Modules/Filtering/Contrast/include/otbCLHistogramEqualizationFilter.txx
new file mode 100644
index 0000000..f5cbebd
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbCLHistogramEqualizationFilter.txx
@@ -0,0 +1,102 @@
+/*
+ * 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 otbCLHistogramEqualizationFilter_txx
+#define otbCLHistogramEqualizationFilter_txx
+
+#include "otbCLHistogramEqualizationFilter.h"
+#include "itkImageRegionIterator.h"
+
+#include <limits>
+
+namespace otb
+{
+template < class TInputImage , class TOutputImage >
+CLHistogramEqualizationFilter < TInputImage , TOutputImage >
+::CLHistogramEqualizationFilter():
+m_HistoFilter( HistoFilter::New() ) ,
+m_GainLutFilter ( GainLutFilter::New() ) ,
+m_ApplyGainFilter ( ApplyGainFilter::New() ) ,
+m_StreamingImageFilter ( StreamingImageFilter::New() ) ,
+m_BufferFilter ( BufferFilter::New() )
+{
+  m_Min = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_Max = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_NbBin = 256;
+  m_Threshold = -1;
+  m_NoDataFlag = false;
+  m_NoData = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_ThumbSize.Fill(0);
+  m_GainLutFilter->SetInput( m_HistoFilter->GetHistoOutput() );
+  m_StreamingImageFilter->SetInput( m_GainLutFilter->GetOutput() );
+  m_ApplyGainFilter->SetInputLut( m_StreamingImageFilter->GetOutput() );
+  m_ApplyGainFilter->SetInputImage( m_BufferFilter->GetOutput() );
+}
+
+template < class TInputImage , class TOutputImage >
+void CLHistogramEqualizationFilter < TInputImage , TOutputImage >
+::UpdateOutputInformation()
+{ 
+  const InputImageType * input =  this->GetInput() ;
+  m_HistoFilter->SetInput( input );
+  m_BufferFilter->SetInput( input );
+  m_ApplyGainFilter->GetOutput()->UpdateOutputInformation();
+  this->GetOutput()->CopyInformation( m_ApplyGainFilter->GetOutput() );
+}
+
+template < class TInputImage , class TOutputImage >
+void CLHistogramEqualizationFilter < TInputImage , TOutputImage >
+::PropagateRequestedRegion( itk::DataObject * output )
+{ 
+  m_ApplyGainFilter->GetOutput()->SetRequestedRegion( static_cast<OutputImageType *>(output)->GetRequestedRegion() );
+  m_ApplyGainFilter->GetOutput()->PropagateRequestedRegion();
+}
+
+template < class TInputImage , class TOutputImage >
+void CLHistogramEqualizationFilter < TInputImage , TOutputImage >
+::GenerateData()
+{
+  m_ApplyGainFilter->GraftOutput( this->GetOutput() );
+  m_ApplyGainFilter->Update();
+  this->GraftOutput( m_ApplyGainFilter->GetOutput() );
+  
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage , class TOutputImage >
+void CLHistogramEqualizationFilter < TInputImage , TOutputImage >
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "Minimum : " << m_Min << std::endl;
+  os << indent << "Maximum : " << m_Max << std::endl;
+  os << indent << "Bin Number : " << m_NbBin << std::endl;
+  os << indent << "Thumbnail size : " << m_ThumbSize << std::endl;
+  os << indent << "Threshold value : " << m_Threshold << std::endl;
+  os << indent << "Is no data activated : " << m_NoDataFlag << std::endl;
+  os << indent << "No Data : " << m_NoData << std::endl;
+}
+
+  
+}  // End namespace otb
+
+#endif
diff --git a/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.h b/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.h
new file mode 100644
index 0000000..5a4c088
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.h
@@ -0,0 +1,128 @@
+/*
+ * 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 otbComputeGainLutFilter_h
+#define otbComputeGainLutFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "otbImage.h"
+
+namespace otb
+{
+
+/** \class ComputeGainLutFilter
+ *  \brief Compute the gain for each pixel value from a histogram
+ *
+ *  This class implements the second part of the CLAHE algorithm. It's aim 
+ *  is to compute a look up table filled with gain that need to be applied
+ *  on the input to match the target histogram. To keep consistency with 
+ *  the other parts of the algorithm it needs the minimum and maximum value
+ *  of the input image and also the theorical number of pixel per histogram.
+ *
+ * \ingroup OTBContrast
+ */
+
+template <class TInputImage , class TOutputImage >
+class ITK_EXPORT ComputeGainLutFilter :
+  public itk::ImageToImageFilter< TInputImage , TOutputImage >
+{
+public:
+
+  /** typedef for standard classes. */
+
+  typedef TInputImage InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  typedef ComputeGainLutFilter Self;
+  typedef itk::ImageToImageFilter< InputImageType, OutputImageType > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
+
+  typedef typename InputImageType::PixelType HistoType;
+  typedef typename OutputImageType::PixelType LutType;
+  typedef typename OutputImageType::InternalPixelType OutputPixelType;
+  typedef typename OutputImageType::RegionType OutputImageRegionType;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self)
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(ComputeGainLutFilter, ImageToImageFilter)
+
+  /** Get/Set macro to get/set the number of pixel by histogram */
+  itkSetMacro(NbPixel, unsigned long)
+  itkGetMacro(NbPixel, unsigned long)
+
+  /** Get/Set macro to get/set the minimum value */
+  itkSetMacro(Min, double)
+  itkGetMacro(Min, double)
+
+  /** Get/Set macro to get/set the maximum value */
+  itkSetMacro(Max, double)
+  itkGetMacro(Max, double)
+
+protected:
+  ComputeGainLutFilter() ;
+  ~ComputeGainLutFilter() override {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
+
+  void BeforeThreadedGenerateData() override ;
+
+  void ThreadedGenerateData(
+        const OutputImageRegionType & outputRegionForThread ,
+        itk::ThreadIdType threadId) override ;
+
+private:
+  ComputeGainLutFilter(const Self &) = delete ;
+  void operator =(const Self&) = delete ;
+
+  /** Post-process the look up tabe to get a gain instead of a simple value */
+  OutputPixelType PostProcess( unsigned int countMapValue ,
+                               unsigned int countValue ) ;
+
+  /** Equalized input histogram regarding the target and filling the 
+    * corresponding look up table */
+  void Equalized( const HistoType & inputHisto ,
+                  HistoType & targetHisto ,
+                  LutType & lut) ;
+
+  /** Create target depending on the number of pixel in the input histogram */
+  void CreateTarget( const HistoType & inputHisto ,
+                     HistoType & targetHisto ) ;
+  //TODO Give the opportunity to choose the histogram target
+  
+  /** Check whether the input histogram has enough pixel to be meaningful */
+  bool IsValid(const HistoType & inputHisto ) ;
+
+  double m_Min;
+  double m_Max;
+  double m_Step;
+  unsigned int m_NbBin;
+  unsigned long m_NbPixel;
+
+};
+
+  // End namespace otb
+}
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbComputeGainLutFilter.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.txx b/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.txx
new file mode 100644
index 0000000..ccf1b85
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.txx
@@ -0,0 +1,191 @@
+/*
+ * 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 otbComputeGainLutFilter_txx
+#define otbComputeGainLutFilter_txx
+
+#include "otbComputeGainLutFilter.h"
+#include "itkImageRegionIterator.h"
+
+#include <limits>
+#include <numeric>
+
+namespace otb
+{
+
+template < class TInputImage, class TOutputImage >
+ComputeGainLutFilter < TInputImage , TOutputImage >
+::ComputeGainLutFilter()
+{
+  m_NbBin = 256;
+  m_NbPixel = 0;
+  m_Min = std::numeric_limits< double >::quiet_NaN();
+  m_Max = std::numeric_limits< double >::quiet_NaN();
+  m_Step = -1;
+}
+
+template <class TInputImage , class TOutputImage >
+void ComputeGainLutFilter <TInputImage , TOutputImage >
+::BeforeThreadedGenerateData()
+{
+  m_NbBin = this->GetInput()->GetNumberOfComponentsPerPixel();
+  m_Step = static_cast<double>( m_Max - m_Min ) \
+                / static_cast<double>( m_NbBin -1 );
+}
+
+template <class TInputImage , class TOutputImage >
+void ComputeGainLutFilter <TInputImage , TOutputImage >
+::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread,
+                       itk::ThreadIdType itkNotUsed(threadId) )
+{
+  assert( m_Step > 0 );
+  assert( m_NbBin > 0 );
+  // TODO error
+  // itk::ProgressReporter progress(this , threadId , 
+  //               outputRegionForThread.GetNumberOfPixels() );
+
+  typename InputImageType::ConstPointer input ( this->GetInput() );
+  typename OutputImageType::Pointer output ( this->GetOutput() );
+
+  itk::ImageRegionConstIterator < InputImageType > it ( input , 
+                                                        outputRegionForThread );
+
+  itk::ImageRegionIterator <OutputImageType > oit ( output ,
+                                                    outputRegionForThread );
+
+  HistoType target;
+  target.SetSize( m_NbBin );
+
+  HistoType currentHisto;
+
+  LutType lut;
+  lut.SetSize( m_NbBin );
+
+  for (it.GoToBegin() , oit.GoToBegin() ; !oit.IsAtEnd() || !it.IsAtEnd() ;
+       ++oit , ++it )
+    {
+    currentHisto = it.Get();
+    target.Fill(0);
+    lut.Fill(-1);
+    if ( IsValid( currentHisto ) )
+      {
+      CreateTarget( currentHisto , target );
+      Equalized( currentHisto , target , lut ); 
+      }
+    oit.Set( lut );
+    }
+  assert ( oit.IsAtEnd() && it.IsAtEnd() );
+}
+
+template <class TInputImage, class TOutputImage >
+typename TOutputImage::InternalPixelType 
+  ComputeGainLutFilter < TInputImage , TOutputImage >
+::PostProcess( unsigned int countValue ,
+               unsigned int countMapValue )
+{ 
+  double denum ( countValue * m_Step + m_Min );
+  if ( denum == 0 )
+    return 0;
+  return static_cast< OutputPixelType > ( (countMapValue * m_Step + m_Min)
+          / denum );
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeGainLutFilter < TInputImage , TOutputImage >
+::Equalized( const HistoType & inputHisto ,
+             HistoType & targetHisto ,
+             LutType & lut)
+{
+  unsigned int countValue(0) , countMapValue(0) ;
+  lut[countValue] = 1; // Black stays black
+  ++countValue;
+  unsigned int countInput ( inputHisto[ 0 ] + inputHisto[ countValue ] );
+  lut[m_NbBin - 1 ] = 1 ; // White stays white
+  unsigned int countTarget ( targetHisto[ countMapValue ] );
+
+  while ( ( countMapValue <  m_NbBin ) && countValue < ( m_NbBin - 1 ) )
+    {
+    if ( countInput > countTarget )
+      {
+      ++countMapValue;
+      countTarget += targetHisto[ countMapValue ];
+      }
+    else
+      { 
+      lut[countValue] =  PostProcess( countValue , countMapValue );
+      ++countValue;
+      countInput  += inputHisto[ countValue ];
+      }
+    }
+  for (unsigned int i = 0 ; i < m_NbBin ; i++)
+    {
+    if (lut[i] == -1)
+      {
+      lut[i] = 1;
+      } 
+    }
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeGainLutFilter < TInputImage , TOutputImage >
+::CreateTarget( const HistoType & inputHisto ,
+                HistoType & targetHisto )
+{
+  unsigned int nbPixel(0);
+  for ( unsigned int i = 0 ; i < m_NbBin ; i++ )
+    {
+    nbPixel += inputHisto[i];
+    }
+  unsigned int rest ( nbPixel % m_NbBin ) , height ( nbPixel / m_NbBin );
+  targetHisto.Fill(height);
+  for ( unsigned int i = 0 ; i < rest ; i++ )
+    {
+    ++targetHisto[ ( m_NbBin - rest ) / 2 + i ];
+    }  
+}
+
+template <class TInputImage, class TOutputImage >
+bool ComputeGainLutFilter < TInputImage , TOutputImage >
+::IsValid( const HistoType & inputHisto )
+{
+  long acc = std::accumulate( &inputHisto[0] , 
+                              &inputHisto[ m_NbBin - 1 ] ,
+                              0);
+  return acc >= (0.5 * m_NbPixel);
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage , class TOutputImage >
+void ComputeGainLutFilter < TInputImage , TOutputImage >
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "Minimum: " << m_Min << std::endl;
+  os << indent << "Maximum: " << m_Max << std::endl;
+  os << indent << "Step: " << m_Step << std::endl;
+  os << indent << "Number of bin: " << m_NbBin << std::endl;
+  os << indent << "Number of pixel by histogram: " << m_NbPixel << std::endl;
+}
+
+} // End namespace otb
+
+#endif
diff --git a/Modules/Filtering/Contrast/include/otbComputeHistoFilter.h b/Modules/Filtering/Contrast/include/otbComputeHistoFilter.h
new file mode 100644
index 0000000..2f54203
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbComputeHistoFilter.h
@@ -0,0 +1,160 @@
+/*
+ * 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 otbComputeHistoFilter_h
+#define otbComputeHistoFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "otbImage.h"
+#include "itkImageRegionIterator.h"
+
+namespace otb
+{
+
+/** \class ComputeHistoFilter
+ *  \brief Compute local histogram with several parameters
+ *
+ *  This class implements the first part of the CLAHE algorithm. It aims 
+ *  to compute local histogram with several input parameters such as 
+ *  nodata value, threshold, thumbnail size and number of bin. Mandatory parameters are min 
+ *  and max value as it will be used in the histogram computation.
+ *
+ * \ingroup OTBContrast
+ */
+
+template < class TInputImage , class TOutputImage >
+class ITK_EXPORT ComputeHistoFilter :
+  public itk::ImageToImageFilter< TInputImage , TOutputImage >
+{
+public:
+  /** typedef for standard classes. */
+
+  typedef TInputImage InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  typedef ComputeHistoFilter Self;
+  typedef itk::ImageToImageFilter< InputImageType, OutputImageType > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
+
+  typedef typename InputImageType::InternalPixelType InputPixelType;
+  typedef typename InputImageType::IndexType IndexType;
+  typedef typename InputImageType::SizeType SizeType;
+  typedef typename OutputImageType::RegionType OutputImageRegionType;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self)
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(ComputeHistoFilter, ImageToImageFilter)
+
+  /** Get/Set macro to get/set the number of bin. Default value is 256 */
+  itkSetMacro(NbBin, unsigned int)
+  itkGetMacro(NbBin, unsigned int)
+
+  /** Get/Set macro to get/set the minimum value */
+  itkSetMacro(Min, InputPixelType)
+  itkGetMacro(Min, InputPixelType)
+
+  /** Get/Set macro to get/set the maximum value */
+  itkSetMacro(Max, InputPixelType)
+  itkGetMacro(Max, InputPixelType)
+
+  /** Get/Set macro to get/set the nodata value */
+  itkSetMacro(NoData, InputPixelType)
+  itkGetMacro(NoData, InputPixelType)
+
+  /** Get/Set macro to get/set the nodata flag value */
+  itkBooleanMacro(NoDataFlag)
+  itkGetMacro(NoDataFlag, bool)
+  itkSetMacro(NoDataFlag, bool)
+
+  /** Get/Set macro to get/set the thumbnail's size */
+  itkSetMacro(ThumbSize, SizeType)
+  itkGetMacro(ThumbSize, SizeType)
+
+  /** Get/Set macro to get/set the threshold parameter */
+  itkSetMacro(Threshold , float)
+  itkGetMacro(Threshold , float)
+
+  typename OutputImageType::Pointer GetHistoOutput();
+
+  virtual itk::ProcessObject::DataObjectPointer 
+    MakeOutput(itk::ProcessObject::DataObjectPointerArraySizeType idx) 
+      override;
+
+  virtual itk::ProcessObject::DataObjectPointer 
+    MakeOutput(const itk::ProcessObject::DataObjectIdentifierType &) 
+      override;
+
+
+protected:
+  ComputeHistoFilter();
+  ~ComputeHistoFilter() override {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
+
+  void GenerateInputRequestedRegion() override;
+
+  void GenerateOutputInformation() override;
+
+  // Call  BeforeThreadedGenerateData after getting the number of thread
+  void GenerateData() override;
+
+  
+  void BeforeThreadedGenerateData() override;
+
+  virtual void ThreadedGenerateData(
+          const OutputImageRegionType & outputRegionForThread ,
+          itk::ThreadIdType threadId) override;
+
+  void AfterThreadedGenerateData() override;
+
+  void GenerateOutputRequestedRegion( itk::DataObject *output ) override;
+
+private:
+  ComputeHistoFilter(const Self &) = delete ;
+  void operator =(const Self&) = delete ;
+
+  void SetRequestedRegion( itk::ImageBase<2> * image ) ;
+
+  void ApplyThreshold( 
+       typename itk::ImageRegionIterator < OutputImageType > oit ,
+       unsigned int total );
+
+  std::vector< typename OutputImageType::PixelType > m_HistoThread;
+  InputPixelType m_Min;
+  InputPixelType m_Max;
+  InputPixelType m_NoData;
+  SizeType m_ThumbSize;
+  bool m_NoDataFlag;
+  double m_Step;
+  float m_Threshold;
+  unsigned int m_NbBin;
+  unsigned int m_ValidThreads;
+
+};
+
+}  // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbComputeHistoFilter.txx"
+#endif
+  
+#endif
diff --git a/Modules/Filtering/Contrast/include/otbComputeHistoFilter.txx b/Modules/Filtering/Contrast/include/otbComputeHistoFilter.txx
new file mode 100644
index 0000000..c29b223
--- /dev/null
+++ b/Modules/Filtering/Contrast/include/otbComputeHistoFilter.txx
@@ -0,0 +1,369 @@
+/*
+ * 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 otbComputeHistoFilter_txx
+#define otbComputeHistoFilter_txx
+
+#include "otbComputeHistoFilter.h"
+
+#include <limits>
+
+namespace otb
+{
+
+template <class TInputImage, class TOutputImage >
+ComputeHistoFilter < TInputImage , TOutputImage >
+::ComputeHistoFilter()
+{
+  this->SetNumberOfRequiredOutputs(2);
+  this->SetNthOutput( 0, this->MakeOutput(0) );
+  this->SetNthOutput( 1, this->MakeOutput(1) );
+  m_Min = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_Max = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_NoDataFlag = false;
+  m_NoData = std::numeric_limits< InputPixelType >::quiet_NaN();
+  m_NbBin = 256;
+  m_Threshold = -1;
+  m_ThumbSize.Fill(0);
+  m_ValidThreads = 1;
+  m_Step = -1;
+}
+
+template <class TInputImage, class TOutputImage >
+itk::ProcessObject::DataObjectPointer 
+ComputeHistoFilter < TInputImage , TOutputImage >
+::MakeOutput(itk::ProcessObject::DataObjectPointerArraySizeType idx)
+{
+  itk::DataObject::Pointer output;
+ 
+  switch ( idx )
+    {
+    case 0:
+      output = ( OutputImageType::New() ).GetPointer();
+      break;
+    case 1:
+      output = ( OutputImageType::New() ).GetPointer();
+      break;
+    default:
+      std::cerr << "No output " << idx << std::endl;
+      output = NULL;
+      break;
+    }
+  return output;
+}
+
+template <class TInputImage, class TOutputImage >
+itk::ProcessObject::DataObjectPointer 
+ComputeHistoFilter < TInputImage , TOutputImage >
+::MakeOutput(const itk::ProcessObject::DataObjectIdentifierType & name)
+{
+  return Superclass::MakeOutput( name );
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::GenerateInputRequestedRegion()
+{
+  typename Superclass::InputImagePointer inputPtr (
+                  const_cast<InputImageType *>( this->GetInput() ) );
+  inputPtr->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() );
+  if ( inputPtr->GetRequestedRegion().GetNumberOfPixels() == 0 )
+  {
+  inputPtr->SetRequestedRegionToLargestPossibleRegion();
+  }
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::GenerateOutputInformation()
+{
+  Superclass::GenerateOutputInformation();
+  typename InputImageType::ConstPointer input ( this->GetInput() );
+  typename OutputImageType::Pointer output ( this->GetHistoOutput() );
+  typename OutputImageType::Pointer outImage ( this->GetOutput() );
+
+  typename InputImageType::RegionType inputLargestRegion (
+        input->GetLargestPossibleRegion());
+  outImage->SetLargestPossibleRegion( inputLargestRegion );
+
+  typename OutputImageType::IndexType start;
+  typename OutputImageType::SizeType size;
+
+  start.Fill(0);
+
+  assert( m_ThumbSize[0] != 0 );
+  assert( m_ThumbSize[1] != 0 );
+
+  //TODO throw error if 0
+
+  size[0] = std::ceil( inputLargestRegion.GetSize()[0] / 
+        static_cast< double > ( m_ThumbSize[0] ) );
+  size[1] = std::ceil( inputLargestRegion.GetSize()[1] / 
+        static_cast< double > ( m_ThumbSize[1] ) );
+
+  typename OutputImageType::RegionType region;
+  region.SetSize(size);
+  region.SetIndex(start);
+  output->SetNumberOfComponentsPerPixel(m_NbBin);
+  output->SetLargestPossibleRegion(region);
+  typename InputImageType::SpacingType inputSpacing ( input->GetSignedSpacing() );
+  typename InputImageType::PointType inputOrigin ( input->GetOrigin() );
+
+  typename OutputImageType::SpacingType histoSpacing ;
+  histoSpacing[0] = inputSpacing[0] * m_ThumbSize[0] ;
+  histoSpacing[1] = inputSpacing[1] * m_ThumbSize[1] ;
+  output->SetSignedSpacing( histoSpacing ) ;
+
+  typename OutputImageType::PointType histoOrigin ;
+  histoOrigin[0] = histoSpacing[0] / 2 +  inputOrigin[0] - inputSpacing[0] / 2 ;
+  histoOrigin[1] = histoSpacing[1] / 2 +  inputOrigin[1] - inputSpacing[1] / 2 ;
+  output->SetOrigin( histoOrigin );
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::GenerateOutputRequestedRegion( itk::DataObject * itkNotUsed(output) )
+{
+  if ( GetHistoOutput()->GetRequestedRegion().GetNumberOfPixels() == 0 )
+    {
+    GetHistoOutput()->SetRequestedRegionToLargestPossibleRegion();
+    }
+  typename OutputImageType::Pointer outImage ( this->GetOutput() );
+  SetRequestedRegion( outImage );
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::GenerateData()
+{
+  this->AllocateOutputs();
+
+  // Set up the multithreaded processing
+  typename itk::ImageSource<OutputImageType>::ThreadStruct str;
+  str.Filter = this;
+
+  // Get the output pointer
+  const OutputImageType * outputPtr ( this->GetOutput() );
+  const itk::ImageRegionSplitterBase * splitter ( 
+    this->GetImageRegionSplitter() );
+  m_ValidThreads = 
+    splitter->GetNumberOfSplits( outputPtr->GetRequestedRegion() , 
+                                 this->GetNumberOfThreads() );
+
+  this->BeforeThreadedGenerateData();
+
+  this->GetMultiThreader()->SetNumberOfThreads( m_ValidThreads );
+  this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str);
+  // multithread the execution
+  this->GetMultiThreader()->SingleMethodExecute();
+
+  this->AfterThreadedGenerateData();
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::BeforeThreadedGenerateData()
+{
+  // Initializing output
+  typename OutputImageType::Pointer output ( this->GetHistoOutput() );
+  typename OutputImageType::PixelType zeroPixel(m_NbBin) ;
+  zeroPixel.Fill(0);
+  output->FillBuffer( zeroPixel );
+
+  // Initializing shared variable with thread number parameter
+  SizeType outSize ( output->GetRequestedRegion().GetSize() );
+  m_HistoThread.resize( m_ValidThreads * outSize[0] * outSize[1] );
+  m_HistoThread.shrink_to_fit();
+  std::fill( m_HistoThread.begin() , m_HistoThread.end() , zeroPixel );
+
+  m_Step = static_cast<double>( m_Max - m_Min ) \
+                / static_cast<double>( m_NbBin -1 );
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread ,
+                       itk::ThreadIdType threadId )
+{
+  assert(m_Step>0);
+  // TODO throw error
+
+  // itk::ProgressReporter progress(this , threadId , 
+  //               outputRegionForThread.GetNumberOfPixels() );
+  typename InputImageType::ConstPointer input ( this->GetInput() );
+  typename OutputImageType::Pointer output ( this->GetHistoOutput() );
+
+  OutputImageRegionType histoRegion ( 
+                            GetHistoOutput()->GetRequestedRegion() );
+  SizeType outSize ( histoRegion.GetSize() );
+  IndexType outIndex ( histoRegion.GetIndex() );
+  
+  typename InputImageType::RegionType region;
+
+  unsigned int threadIndex ( threadId  * outSize[0] * outSize[1] ) , pixel(0) ;
+
+  for ( unsigned int nthHisto = 0 ;
+        nthHisto < outSize[0] * outSize[1] ; nthHisto++ )
+    {
+    IndexType start;
+    start[0] = ( outIndex[0] +  nthHisto % outSize[0] ) * m_ThumbSize[0];
+    start[1] = ( outIndex[1] +  nthHisto / outSize[0] ) * m_ThumbSize[1];
+    region.SetSize( m_ThumbSize );
+    region.SetIndex(start);
+
+    if ( !region.Crop( outputRegionForThread ) )
+      continue;
+
+    typename itk::ImageRegionConstIterator < InputImageType > 
+      it( input , region );
+    InputPixelType currentPixel(0);
+    for ( it.GoToBegin() ; !it.IsAtEnd() ; ++it )
+      {
+      currentPixel = it.Get();
+      if( ( currentPixel == m_NoData && m_NoDataFlag ) || 
+            currentPixel > m_Max || currentPixel < m_Min )
+        continue;
+
+      pixel = static_cast< unsigned int >( 
+        std::round( ( currentPixel - m_Min ) / m_Step ) );
+      ++m_HistoThread[threadIndex + nthHisto][pixel];
+      }
+    
+    }
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::AfterThreadedGenerateData()
+{
+  typename OutputImageType::Pointer output ( this->GetHistoOutput() );
+  typename itk::ImageRegionIterator < OutputImageType > 
+      oit( output , output->GetRequestedRegion() );
+  OutputImageRegionType histoRegion ( 
+                        GetHistoOutput()->GetRequestedRegion() );
+  SizeType outSize ( histoRegion.GetSize() );
+  IndexType outIndex ( histoRegion.GetIndex() );
+
+  unsigned int agreg(0) , total(0) ;
+
+  for ( oit.GoToBegin() ; !oit.IsAtEnd() ; ++oit )
+    {
+    total = 0;
+
+    for ( unsigned int i = 0 ; i < m_NbBin ; i++ )
+      {
+      agreg = 0;
+
+      for ( unsigned int threadId = 0 ; threadId < m_ValidThreads ; threadId++ )
+        {
+        agreg += m_HistoThread[ threadId * outSize[0] * outSize[1]
+          + ( oit.GetIndex()[1] - outIndex[1] ) * outSize[0] 
+          + ( ( oit.GetIndex()[0] - outIndex[0] ) ) ][i] ;
+        }
+      oit.Get()[i] = agreg;
+      total += agreg;
+      }
+    if ( m_Threshold > 0 )
+      ApplyThreshold( oit , total );
+    }
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::ApplyThreshold( typename itk::ImageRegionIterator < OutputImageType > oit ,
+                  unsigned int total )
+{
+  unsigned int rest(0);
+  unsigned int height ( static_cast<unsigned int>( 
+        m_Threshold * ( total / m_NbBin ) ) );
+  // Do i need to static_cast in a an assignation?
+  // Warning!!!! Need to handle out of bound int!!!
+
+  for( unsigned int i = 0 ; i < m_NbBin ; i++ )
+    {
+    if ( static_cast<unsigned int>( oit.Get()[i] ) > height )
+      {
+      rest += oit.Get()[i] - height ;
+      oit.Get()[i] = height ;
+      }
+    }
+  height = rest / m_NbBin;
+  rest = rest % m_NbBin;
+  for( unsigned int i = 0 ; i < m_NbBin ; i++ )
+    {
+    oit.Get()[i] += height ;
+    if ( i > (m_NbBin - rest)/2 && i <= (m_NbBin - rest)/2 + rest )
+      {
+      ++oit.Get()[i];
+      }
+    }
+}
+
+template <class TInputImage, class TOutputImage >
+typename TOutputImage::Pointer ComputeHistoFilter < TInputImage , TOutputImage >
+::GetHistoOutput()
+{
+  assert( this->itk::ProcessObject::GetOutput( 1 ) );
+
+  return dynamic_cast< TOutputImage * >(
+           this->itk::ProcessObject::GetOutput(1) );
+}
+
+template <class TInputImage, class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::SetRequestedRegion( itk::ImageBase<2> * image )
+{
+  OutputImageRegionType histoRegion ( 
+                      GetHistoOutput()->GetRequestedRegion() );
+
+  IndexType start ;
+  start[0] = histoRegion.GetIndex()[0] * m_ThumbSize[0];
+  start[1] = histoRegion.GetIndex()[1] * m_ThumbSize[1];
+
+  SizeType size ;
+  size[0] = histoRegion.GetSize()[0] * m_ThumbSize[0];
+  size[1] = histoRegion.GetSize()[1] * m_ThumbSize[1];
+
+  typename OutputImageType::RegionType outputRequestedRegion;
+  outputRequestedRegion.SetIndex( start );
+  outputRequestedRegion.SetSize( size );
+
+  outputRequestedRegion.Crop( image->GetLargestPossibleRegion() );
+  image->SetRequestedRegion( outputRequestedRegion );
+}
+
+template <class TInputImage , class TOutputImage >
+void ComputeHistoFilter < TInputImage , TOutputImage >
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "Is no data activated: " << m_NoDataFlag << std::endl;
+  os << indent << "No Data: " << m_NoData << std::endl;
+  os << indent << "Minimum: " << m_Min << std::endl;
+  os << indent << "Maximum: " << m_Max << std::endl;
+  os << indent << "Step: " << m_Step << std::endl;
+  os << indent << "Number of bin: " << m_NbBin << std::endl;
+  os << indent << "Thumbnail size: " << m_ThumbSize << std::endl;
+  os << indent << "Threshold value: " << m_Threshold << std::endl;
+}
+  
+} // End namespace otb
+
+#endif
diff --git a/Modules/Applications/AppFiltering/otb-module.cmake b/Modules/Filtering/Contrast/otb-module.cmake
similarity index 87%
copy from Modules/Applications/AppFiltering/otb-module.cmake
copy to Modules/Filtering/Contrast/otb-module.cmake
index 5e8fc45..58c014c 100644
--- a/Modules/Applications/AppFiltering/otb-module.cmake
+++ b/Modules/Filtering/Contrast/otb-module.cmake
@@ -18,18 +18,19 @@
 # limitations under the License.
 #
 
-set(DOCUMENTATION "Image filtering application.")
+set(DOCUMENTATION "work in progress")
 
-otb_module(OTBAppFiltering
+otb_module(OTBContrast
   DEPENDS
     OTBImageManipulation
     OTBITK
-    OTBApplicationEngine
-    OTBImageBase
+  	OTBCommon
+  	OTBImageBase  
 
   TEST_DEPENDS
     OTBTestKernel
-    OTBCommandLine
+    OTBImageBase
+    OTBImageIO
 
   DESCRIPTION
     "${DOCUMENTATION}"
diff --git a/Modules/Filtering/Contrast/test/CMakeLists.txt b/Modules/Filtering/Contrast/test/CMakeLists.txt
new file mode 100644
index 0000000..ee6950a
--- /dev/null
+++ b/Modules/Filtering/Contrast/test/CMakeLists.txt
@@ -0,0 +1,88 @@
+#
+# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+#     https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+otb_module_test()
+
+set(OTBContrastTests
+otbContrastTestDriver.cxx
+otbComputeHistoFilterNew.cxx
+otbComputeHistoFilter.cxx
+otbApplyGainFilterNew.cxx
+otbApplyGainFilter.cxx
+otbComputeGainLutFilterNew.cxx
+otbComputeGainLutFilter.cxx
+otbCLHistogramEqualizationFilterNew.cxx
+otbCLHistogramEqualizationFilter.cxx
+otbHelperCLAHE.cxx
+)
+
+add_executable(otbContrastTestDriver ${OTBContrastTests})
+target_link_libraries(otbContrastTestDriver ${OTBContrast-Test_LIBRARIES})
+otb_module_target_label(otbContrastTestDriver)
+
+otb_add_test(NAME bfTuCLHistogramEqualizationFilterNew COMMAND otbContrastTestDriver
+  otbCLHistogramEqualizationFilterNew)
+
+otb_add_test(NAME bfTuApplyGainFilterNew COMMAND otbContrastTestDriver
+  otbApplyGainFilterNew)
+
+otb_add_test(NAME bfTuComputeGainLutFilterNew COMMAND otbContrastTestDriver
+  otbComputeGainLutFilterNew)
+
+otb_add_test(NAME bfTuComputeHistoFilterNew COMMAND otbContrastTestDriver
+  otbComputeHistoFilterNew)
+
+otb_add_test(NAME bfTvComputeHistoFilter COMMAND otbContrastTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvComputeHistoFilter.tif
+  ${TEMP}/bfTvComputeHistoFilter.tif
+  otbComputeHistoFilter
+  ${INPUTDATA}/QB_Suburb.png
+  ${TEMP}/bfTvComputeHistoFilter.tif
+  )
+
+otb_add_test(NAME bfTvComputeGainLutFilter COMMAND otbContrastTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvComputeGainLutFilter.tif
+  ${TEMP}/bfTvComputeGainLutFilter.tif
+  otbComputeGainLutFilter
+  ${INPUTDATA}/QB_Suburb.png
+  ${INPUTDATA}/inputHisto_QB_Suburb.tif
+  ${TEMP}/bfTvComputeGainLutFilter.tif
+  )
+
+otb_add_test(NAME bfTvApplyGainFilter COMMAND otbContrastTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvApplyGainFilter.tif
+  ${TEMP}/bfTvApplyGainFilter.tif
+  otbApplyGainFilter
+  ${INPUTDATA}/QB_Suburb.png
+  ${INPUTDATA}/inputLut_QB_Suburb.tif
+  ${TEMP}/bfTvApplyGainFilter.tif
+  )
+
+otb_add_test(NAME bfTvCLHistoEqFilter COMMAND otbContrastTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvApplyGainFilter.tif
+  ${TEMP}/bfTvCLHistoEqFilter.tif
+  otbCLHistogramEqualizationFilter
+  ${INPUTDATA}/QB_Suburb.png
+  ${TEMP}/bfTvCLHistoEqFilter.tif
+  )
\ No newline at end of file
diff --git a/Modules/Filtering/Contrast/test/otbApplyGainFilter.cxx b/Modules/Filtering/Contrast/test/otbApplyGainFilter.cxx
new file mode 100644
index 0000000..f16636f
--- /dev/null
+++ b/Modules/Filtering/Contrast/test/otbApplyGainFilter.cxx
@@ -0,0 +1,66 @@
+/*
+ * 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 "otbImageFileWriter.h"
+#include "otbImageFileReader.h"
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbApplyGainFilter.h"
+
+int otbApplyGainFilter(int itkNotUsed(argc), char * argv [])
+{
+  typedef int InputPixelType;
+  typedef double LutPixelType;
+  const unsigned int Dimension = 2;
+
+  typedef otb::Image< InputPixelType ,  Dimension > InputImageType;
+  typedef otb::VectorImage< LutPixelType , Dimension > LutImageType;
+  typedef otb::ApplyGainFilter
+      < InputImageType , LutImageType , InputImageType > FilterType;
+
+  
+  typedef otb::ImageFileReader< InputImageType > ReaderType; 
+  typedef otb::ImageFileReader< LutImageType > ReaderLutType;
+  typedef otb::ImageFileWriter< InputImageType > WriterType;
+  ReaderType::Pointer reader ( ReaderType::New() );
+  ReaderLutType::Pointer readerLut ( ReaderLutType::New() );
+  WriterType::Pointer writer ( WriterType::New() );
+  reader->SetFileName( argv[1] );
+  readerLut->SetFileName( argv[2] );
+  writer->SetFileName( argv[3] );
+  reader->UpdateOutputInformation();
+  readerLut->UpdateOutputInformation();
+
+  FilterType::Pointer appGain ( FilterType::New() );
+
+  appGain->SetInputLut( readerLut->GetOutput() );
+  appGain->SetInputImage( reader->GetOutput() );
+  appGain->SetMin(0);
+  appGain->SetMax(255);
+  appGain->ThumbSizeFromSpacingOn();
+
+  auto size = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
+  appGain->SetThumbSize(size);
+
+  writer->SetInput( appGain->GetOutput() );
+  writer->Update();
+
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx b/Modules/Filtering/Contrast/test/otbApplyGainFilterNew.cxx
similarity index 51%
copy from Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
copy to Modules/Filtering/Contrast/test/otbApplyGainFilterNew.cxx
index e4104cd..47f5101 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
+++ b/Modules/Filtering/Contrast/test/otbApplyGainFilterNew.cxx
@@ -18,37 +18,29 @@
  * limitations under the License.
  */
 
-#if defined(_MSC_VER)
-#pragma warning ( disable : 4786 )
-#endif
 
-#include "otbWrapperParameter.h"
 
-int otbWrapperParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbApplyGainFilter.h"
+
+int otbApplyGainFilterNew(int itkNotUsed(argc), char * itkNotUsed(argv) [])
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
+  typedef double InputPixelType;
+  typedef double OutputPixelType;
+  typedef float LutPixelType;
+  const unsigned int Dimension = 2;
 
-  //std::cout << parameter << std::endl;
+  typedef otb::Image< InputPixelType ,  Dimension > InputImageType;
+  typedef otb::Image< OutputPixelType , Dimension > OutputImageType;
+  typedef otb::VectorImage< LutPixelType , Dimension > LutImageType;
+  typedef otb::ApplyGainFilter
+      < InputImageType , LutImageType , OutputImageType > FilterType;
 
-  return EXIT_SUCCESS;
-}
 
-int otbWrapperParameterTest1(int itkNotUsed(argc), char* argv[])
-{
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
-
-  const std::string name = argv[1];
-
-  parameter->SetName(name);
-
-  if (name == parameter->GetName())
-    {
-    return EXIT_SUCCESS;
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
-}
+  FilterType::Pointer appGain ( FilterType::New() );
+
+  std::cout << appGain << std::endl;
+
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/Modules/Filtering/Contrast/test/otbCLHistogramEqualizationFilter.cxx b/Modules/Filtering/Contrast/test/otbCLHistogramEqualizationFilter.cxx
new file mode 100644
index 0000000..7ddbe3e
--- /dev/null
+++ b/Modules/Filtering/Contrast/test/otbCLHistogramEqualizationFilter.cxx
@@ -0,0 +1,57 @@
+/*
+ * 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 "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+#include "otbImage.h"
+#include "otbCLHistogramEqualizationFilter.h"
+
+int otbCLHistogramEqualizationFilter(int itkNotUsed(argc), char * argv [])
+{
+  typedef int InputPixelType;
+  const unsigned int Dimension = 2;
+
+  typedef otb::Image< InputPixelType ,  Dimension > InputImageType;
+  typedef otb::CLHistogramEqualizationFilter< InputImageType , InputImageType > 
+    FilterType;
+  typedef otb::ImageFileReader< InputImageType > ReaderType; 
+  typedef otb::ImageFileWriter< InputImageType > WriterType;
+
+  ReaderType::Pointer reader ( ReaderType::New() );
+  WriterType::Pointer writer ( WriterType::New() );
+  reader->SetFileName( argv[1] );
+  writer->SetFileName( argv[2] );
+  reader->UpdateOutputInformation();
+
+  FilterType::Pointer histoEqualize ( FilterType::New() );
+
+  histoEqualize->SetInput( reader->GetOutput() );
+  histoEqualize->SetMin(0);
+  histoEqualize->SetMax(255);
+  histoEqualize->SetNbBin(256);
+  auto size = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
+  size[0] /= 4;
+  size[1] /= 4;
+  histoEqualize->SetThumbSize( size );
+
+  writer->SetInput( histoEqualize->GetOutput() );
+  writer->Update();
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx b/Modules/Filtering/Contrast/test/otbCLHistogramEqualizationFilterNew.cxx
similarity index 51%
copy from Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
copy to Modules/Filtering/Contrast/test/otbCLHistogramEqualizationFilterNew.cxx
index e4104cd..4978121 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
+++ b/Modules/Filtering/Contrast/test/otbCLHistogramEqualizationFilterNew.cxx
@@ -18,37 +18,24 @@
  * limitations under the License.
  */
 
-#if defined(_MSC_VER)
-#pragma warning ( disable : 4786 )
-#endif
 
-#include "otbWrapperParameter.h"
 
-int otbWrapperParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+#include "otbImage.h"
+#include "otbCLHistogramEqualizationFilter.h"
+
+int otbCLHistogramEqualizationFilterNew(int itkNotUsed(argc), char * itkNotUsed(argv) [])
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
+  typedef double InputPixelType;
+  const unsigned int Dimension = 2;
 
-  //std::cout << parameter << std::endl;
+  typedef otb::Image< InputPixelType ,  Dimension > InputImageType;
+  typedef otb::CLHistogramEqualizationFilter< InputImageType , InputImageType > 
+    FilterType;
 
-  return EXIT_SUCCESS;
-}
 
-int otbWrapperParameterTest1(int itkNotUsed(argc), char* argv[])
-{
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
-
-  const std::string name = argv[1];
-
-  parameter->SetName(name);
-
-  if (name == parameter->GetName())
-    {
-    return EXIT_SUCCESS;
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
-}
+  FilterType::Pointer histoEqualize ( FilterType::New() );
+
+  std::cout << histoEqualize << std::endl;
+
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/Modules/Filtering/Contrast/test/otbComputeGainLutFilter.cxx b/Modules/Filtering/Contrast/test/otbComputeGainLutFilter.cxx
new file mode 100644
index 0000000..77a8c3f
--- /dev/null
+++ b/Modules/Filtering/Contrast/test/otbComputeGainLutFilter.cxx
@@ -0,0 +1,68 @@
+/*
+ * 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 "otbVectorImage.h"
+#include "otbImage.h"
+#include "otbImageFileWriter.h"
+#include "otbImageFileReader.h"
+#include "otbComputeGainLutFilter.h"
+
+int otbComputeGainLutFilter(int itkNotUsed(argc), char * argv [])
+{
+  typedef int InputPixelType;
+  typedef double OutputPixelType;
+  const unsigned int Dimension = 2;
+
+  typedef otb::VectorImage< InputPixelType , Dimension > HistoImageType;
+  typedef otb::Image< InputPixelType , Dimension > InputImageType;
+  typedef otb::VectorImage< OutputPixelType , Dimension > LutImageType;
+  typedef otb::ComputeGainLutFilter< HistoImageType , LutImageType > FilterType;
+
+  typedef otb::ImageFileReader< InputImageType > ReaderImageType; 
+  typedef otb::ImageFileReader< HistoImageType > ReaderType; 
+  typedef otb::ImageFileWriter< LutImageType > WriterType;
+  ReaderImageType::Pointer readerImage( ReaderImageType::New() );
+  ReaderType::Pointer reader( ReaderType::New() );
+  WriterType::Pointer writer ( WriterType::New() );
+  readerImage->SetFileName( argv[1] );
+  reader->SetFileName( argv[2] );
+  writer->SetFileName( argv[3] );
+  reader->UpdateOutputInformation();
+  readerImage->UpdateOutputInformation();
+
+  FilterType::Pointer computeGainLut ( FilterType::New() );
+
+  computeGainLut->SetInput( reader->GetOutput() );
+  computeGainLut->SetMin(0);
+  computeGainLut->SetMax(255);
+  auto size = readerImage->GetOutput()->GetLargestPossibleRegion().GetSize();
+  size[0] /= 4;
+  size[1] /= 4;
+  auto nbPix = size[0]*size[1] ;
+  computeGainLut->SetNbPixel( nbPix );
+
+  writer->SetInput( computeGainLut->GetOutput() );
+  writer->Update();
+
+  auto index = computeGainLut->GetOutput()->GetLargestPossibleRegion().GetIndex();
+  std::cout<<computeGainLut->GetOutput()->GetPixel( index )<<std::endl;
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx b/Modules/Filtering/Contrast/test/otbComputeGainLutFilterNew.cxx
similarity index 51%
copy from Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
copy to Modules/Filtering/Contrast/test/otbComputeGainLutFilterNew.cxx
index e4104cd..642e805 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
+++ b/Modules/Filtering/Contrast/test/otbComputeGainLutFilterNew.cxx
@@ -18,37 +18,23 @@
  * limitations under the License.
  */
 
-#if defined(_MSC_VER)
-#pragma warning ( disable : 4786 )
-#endif
+#include "otbVectorImage.h"
+#include "otbComputeGainLutFilter.h"
 
-#include "otbWrapperParameter.h"
-
-int otbWrapperParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+int otbComputeGainLutFilterNew(int itkNotUsed(argc), char * itkNotUsed(argv) [])
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
+  typedef double InputPixelType;
+  typedef double OutputPixelType;
+  const unsigned int Dimension = 2;
 
-  //std::cout << parameter << std::endl;
+  typedef otb::VectorImage< InputPixelType , Dimension > HistoImageType;
+  typedef otb::VectorImage< OutputPixelType , Dimension > LutImageType;
+  typedef otb::ComputeGainLutFilter< HistoImageType , LutImageType > FilterType;
 
-  return EXIT_SUCCESS;
-}
 
-int otbWrapperParameterTest1(int itkNotUsed(argc), char* argv[])
-{
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
+  FilterType::Pointer computeGainLut ( FilterType::New() );
 
-  const std::string name = argv[1];
+  std::cout << computeGainLut << std::endl;
 
-  parameter->SetName(name);
-
-  if (name == parameter->GetName())
-    {
-    return EXIT_SUCCESS;
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
-}
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/Modules/Filtering/Contrast/test/otbComputeHistoFilter.cxx b/Modules/Filtering/Contrast/test/otbComputeHistoFilter.cxx
new file mode 100644
index 0000000..f8407be
--- /dev/null
+++ b/Modules/Filtering/Contrast/test/otbComputeHistoFilter.cxx
@@ -0,0 +1,59 @@
+/*
+ * 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 "otbImage.h"
+#include "otbImageFileWriter.h"
+#include "otbImageFileReader.h"
+#include "otbVectorImage.h"
+#include "otbComputeHistoFilter.h"
+
+int otbComputeHistoFilter(int itkNotUsed(argc), char * argv [])
+{
+  typedef int InputPixelType;
+  typedef int OutputPixelType;
+  const unsigned int Dimension = 2;
+
+  typedef otb::Image< InputPixelType ,  Dimension > InputImageType;
+  typedef otb::VectorImage< OutputPixelType , Dimension > HistoImageType;
+  typedef otb::ComputeHistoFilter< InputImageType , HistoImageType > FilterType;
+
+  typedef otb::ImageFileReader< InputImageType > ReaderType; 
+  typedef otb::ImageFileWriter< HistoImageType > WriterType;
+  ReaderType::Pointer reader ( ReaderType::New() );
+  WriterType::Pointer writer ( WriterType::New() );
+  reader->SetFileName( argv[1] );
+  writer->SetFileName( argv[2] );
+  reader->UpdateOutputInformation();
+
+  FilterType::Pointer computeHisto ( FilterType::New() );
+  
+  computeHisto->SetInput( reader->GetOutput() );
+  computeHisto->SetMin(0);
+  computeHisto->SetMax(255);
+  computeHisto->SetNbBin(256);
+  auto size = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
+  size[0] /= 4;
+  size[1] /= 4;
+  computeHisto->SetThumbSize( size );
+
+  writer->SetInput( computeHisto->GetHistoOutput() );
+  writer->Update();
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx b/Modules/Filtering/Contrast/test/otbComputeHistoFilterNew.cxx
similarity index 51%
copy from Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
copy to Modules/Filtering/Contrast/test/otbComputeHistoFilterNew.cxx
index e4104cd..4dd79d4 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
+++ b/Modules/Filtering/Contrast/test/otbComputeHistoFilterNew.cxx
@@ -18,37 +18,26 @@
  * limitations under the License.
  */
 
-#if defined(_MSC_VER)
-#pragma warning ( disable : 4786 )
-#endif
 
-#include "otbWrapperParameter.h"
 
-int otbWrapperParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbComputeHistoFilter.h"
+
+int otbComputeHistoFilterNew(int itkNotUsed(argc), char * itkNotUsed(argv) [])
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
+  typedef double InputPixelType;
+  typedef double OutputPixelType;
+  const unsigned int Dimension = 2;
 
-  //std::cout << parameter << std::endl;
+  typedef otb::Image< InputPixelType ,  Dimension > InputImageType;
+  typedef otb::VectorImage< OutputPixelType , Dimension > HistoImageType;
+  typedef otb::ComputeHistoFilter< InputImageType , HistoImageType > FilterType;
 
-  return EXIT_SUCCESS;
-}
 
-int otbWrapperParameterTest1(int itkNotUsed(argc), char* argv[])
-{
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
-
-  const std::string name = argv[1];
-
-  parameter->SetName(name);
-
-  if (name == parameter->GetName())
-    {
-    return EXIT_SUCCESS;
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
-}
+  FilterType::Pointer computeHisto ( FilterType::New() );
+
+  std::cout << computeHisto << std::endl;
+
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/Modules/Filtering/Contrast/test/otbContrastTestDriver.cxx b/Modules/Filtering/Contrast/test/otbContrastTestDriver.cxx
new file mode 100644
index 0000000..213bb72
--- /dev/null
+++ b/Modules/Filtering/Contrast/test/otbContrastTestDriver.cxx
@@ -0,0 +1,34 @@
+/*
+ * 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 "otbTestMain.h"
+
+void RegisterTests()
+{
+  REGISTER_TEST(otbComputeHistoFilterNew);
+  REGISTER_TEST(otbComputeHistoFilter);
+  REGISTER_TEST(otbComputeGainLutFilterNew);
+  REGISTER_TEST(otbComputeGainLutFilter);
+  REGISTER_TEST(otbApplyGainFilterNew);
+  REGISTER_TEST(otbApplyGainFilter);
+  REGISTER_TEST(otbCLHistogramEqualizationFilterNew);
+  REGISTER_TEST(otbCLHistogramEqualizationFilter);
+  REGISTER_TEST(otbHelperCLAHE);
+}
diff --git a/Modules/Filtering/Contrast/test/otbHelperCLAHE.cxx b/Modules/Filtering/Contrast/test/otbHelperCLAHE.cxx
new file mode 100644
index 0000000..b1fc895
--- /dev/null
+++ b/Modules/Filtering/Contrast/test/otbHelperCLAHE.cxx
@@ -0,0 +1,92 @@
+/*
+ * 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 "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "itkImageRegionIterator.h"
+#include "otbCLHistogramEqualizationFilter.h"
+
+int otbHelperCLAHE(int itkNotUsed(argc), char * argv [])
+{
+  typedef int InputPixelType;
+  const unsigned int Dimension = 2;
+
+  typedef otb::Image< InputPixelType ,  Dimension > InputImageType;
+  typedef otb::ImageFileReader< InputImageType > ReaderType; 
+  typedef otb::ImageFileWriter< InputImageType > WriterType;
+  ReaderType::Pointer reader ( ReaderType::New() );
+  WriterType::Pointer writer ( WriterType::New() );
+  reader->SetFileName( argv[1] );
+  writer->SetFileName( argv[2] );
+  reader->UpdateOutputInformation();
+
+  typedef otb::VectorImage< int , 2 > HistogramType;
+  typedef otb::VectorImage< double , 2 > LutType;
+
+  typedef itk::StreamingImageFilter< LutType , LutType >
+    StreamingImageFilter;
+
+  typedef otb::InPlacePassFilter < InputImageType > BufferFilter;
+
+  typedef otb::ComputeHistoFilter< InputImageType , HistogramType >
+    HistoFilter;
+
+  typedef otb::ComputeGainLutFilter< HistogramType , LutType >
+    GainLutFilter;
+
+  typedef otb::ApplyGainFilter< InputImageType , LutType , InputImageType >
+    ApplyGainFilter;
+
+  HistoFilter::Pointer histoFilter( HistoFilter::New() );
+  GainLutFilter::Pointer lutFilter( GainLutFilter::New() );
+  ApplyGainFilter::Pointer applyFilter( ApplyGainFilter::New() );
+  BufferFilter::Pointer buffer( BufferFilter::New() );
+  StreamingImageFilter::Pointer streamFilter( StreamingImageFilter::New() );
+  InputImageType::SizeType size;
+  size = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
+  // histoEqualize->SetThreshold(100);
+
+  histoFilter->SetInput( reader->GetOutput() );
+  buffer->SetInput( reader->GetOutput() );
+  lutFilter->SetInput( histoFilter->GetHistoOutput() );
+  streamFilter->SetInput( lutFilter->GetOutput() );
+  applyFilter->SetInputLut( streamFilter->GetOutput() );
+  applyFilter->SetInputImage( buffer->GetOutput() );
+
+  histoFilter->SetMin(0);
+  histoFilter->SetMax(255);
+  lutFilter->SetMin(0);
+  lutFilter->SetMax(255);
+  applyFilter->SetMin(0);
+  applyFilter->SetMax(255);
+
+  histoFilter->SetThumbSize(size);
+  applyFilter->SetThumbSize(size);
+  lutFilter->SetNbPixel(size[0]*size[1]);
+
+
+
+  writer->SetInput(applyFilter->GetOutput());
+  writer->Update();
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/Convolution/test/otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter.cxx b/Modules/Filtering/Convolution/test/otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter.cxx
index 1096ec6..6b47d1c 100644
--- a/Modules/Filtering/Convolution/test/otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter.cxx
+++ b/Modules/Filtering/Convolution/test/otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter.cxx
@@ -25,11 +25,11 @@
 #include "otbImage.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
+#include "otbStopwatch.h"
 #include "otbConvolutionImageFilter.h"
 #include "otbOverlapSaveConvolutionImageFilter.h"
 #include "otbGaborFilterGenerator.h"
 #include "itkConstantBoundaryCondition.h"
-#include "itkTimeProbe.h"
 
 int otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter(int argc, char *argv[])
 {
@@ -82,8 +82,6 @@ int otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter(int argc, char *
   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileName(infname);
 
-  itk::TimeProbe probe1, probe2;
-
   ConvolutionFilterType::Pointer convolution = ConvolutionFilterType::New();
   convolution->SetRadius(radius);
   convolution->SetFilter(filter);
@@ -93,11 +91,10 @@ int otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter(int argc, char *
   writer1->SetInput(convolution->GetOutput());
   writer1->SetFileName(outfname1);
 
-  probe1.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   writer1->Update();
-  probe1.Stop();
 
-  std::cout << "Classical convolution algorithm took " << probe1.GetMean() << " seconds." << std::endl;
+  std::cout << "Classical convolution algorithm took " << chrono.GetElapsedMilliseconds() << " ms." << std::endl;
 
   OSConvolutionFilterType::Pointer osconvolution = OSConvolutionFilterType::New();
   osconvolution->SetRadius(radius);
@@ -108,11 +105,10 @@ int otbCompareOverlapSaveAndClassicalConvolutionWithGaborFilter(int argc, char *
   writer2->SetInput(osconvolution->GetOutput());
   writer2->SetFileName(outfname2);
 
-  probe2.Start();
+  chrono.Restart();
   writer2->Update();
-  probe2.Stop();
 
-  std::cout << "Overlap-save convolution algorithm took " << probe2.GetMean() << " seconds." << std::endl;
+  std::cout << "Overlap-save convolution algorithm took " << chrono.GetElapsedMilliseconds() << " ms." << std::endl;
 
   return EXIT_SUCCESS;
 }
diff --git a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h
index 04ad637..26464e3 100644
--- a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h
+++ b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h
@@ -165,7 +165,7 @@ public:
   template <class TImageType> void SetOutputParametersFromImage(const TImageType * image)
     {
     this->SetOutputOrigin ( image->GetOrigin() );
-    this->SetOutputSpacing ( image->GetSpacing() );
+    this->SetOutputSpacing ( image->GetSignedSpacing() );
     //this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() );
     this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() );
     this->SetOutputProjectionRef(image->GetProjectionRef());
diff --git a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.txx b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.txx
index c87816b..140fd20 100644
--- a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.txx
+++ b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.txx
@@ -63,7 +63,7 @@ void DEMToImageGenerator<TDEMImage>
   largestPossibleRegion.SetIndex(start);
 
   output->SetLargestPossibleRegion(largestPossibleRegion);
-  output->SetSpacing(m_OutputSpacing);
+  output->SetSignedSpacing(m_OutputSpacing);
   output->SetOrigin(m_OutputOrigin);
 
 
diff --git a/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx
index 423b57c..dced764 100644
--- a/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx
+++ b/Modules/Filtering/ImageManipulation/include/otbGridResampleImageFilter.txx
@@ -24,6 +24,7 @@
 #include "otbGridResampleImageFilter.h"
 
 #include "otbStreamingTraits.h"
+#include "otbImage.h"
 
 #include "itkNumericTraits.h"
 #include "itkProgressReporter.h"
@@ -68,7 +69,7 @@ GridResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecision>
 ::SetOutputParametersFromImage(const ImageBaseType * image)
 {
   this->SetOutputOrigin ( image->GetOrigin() );
-  this->SetOutputSpacing ( image->GetSpacing() );
+  this->SetOutputSpacing ( internal::GetSignedSpacing( image ) );
   this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() );
   this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() );
 }
@@ -95,7 +96,7 @@ GridResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecision>
   outputLargestPossibleRegion.SetIndex(m_OutputStartIndex);
   
   outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
-  outputPtr->SetSpacing(m_OutputSpacing);
+  outputPtr->SetSignedSpacing(m_OutputSpacing);
   outputPtr->SetOrigin(m_OutputOrigin);
 
   // TODO: Report no data value here
@@ -266,8 +267,8 @@ GridResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecision>
   this->GetInput()->TransformIndexToPhysicalPoint(inUL,inULp);
   this->GetInput()->TransformIndexToPhysicalPoint(inLR,inLRp);
 
-  inULp-=0.5*this->GetInput()->GetSpacing();
-  inLRp+=0.5*this->GetInput()->GetSpacing();
+  inULp-=0.5*this->GetInput()->GetSignedSpacing();
+  inLRp+=0.5*this->GetInput()->GetSignedSpacing();
 
   ContinuousInputIndexType outUL;
   ContinuousInputIndexType outLR;
@@ -340,9 +341,9 @@ GridResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecision>
   InterpolatorOutputType interpolatorValue; //(this->GetOutput()->GetNumberOfComponentsPerPixel());
   OutputPixelType outputValue; //(this->GetOutput()->GetNumberOfComponentsPerPixel());
 
-  // TODO: assert outputPtr->GetSpacing() != 0 here
-  assert(outputPtr->GetSpacing()[0]!=0&&"Null spacing will cause division by zero.");
-  const double delta = outputPtr->GetSpacing()[0]/inputPtr->GetSpacing()[0];
+  // TODO: assert outputPtr->GetSignedSpacing() != 0 here
+  assert(outputPtr->GetSignedSpacing()[0]!=0&&"Null spacing will cause division by zero.");
+  const double delta = outputPtr->GetSignedSpacing()[0]/inputPtr->GetSignedSpacing()[0];
   
   // Iterate through the output region
   outIt.GoToBegin();
diff --git a/Modules/Filtering/ImageManipulation/include/otbInPlacePassFilter.h b/Modules/Filtering/ImageManipulation/include/otbInPlacePassFilter.h
new file mode 100644
index 0000000..22085dd
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbInPlacePassFilter.h
@@ -0,0 +1,99 @@
+/*
+ * 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 otbInPlacePassFilter_h
+#define otbInPlacePassFilter_h
+
+#include "itkInPlaceImageFilter.h"
+#include "otbImage.h"
+#include "itkImageRegionIterator.h"
+
+namespace otb
+{
+
+/** \class InPlacePassFilter
+ *  \brief This filter has the only purpose to recall regions
+ *
+ *  This class is implemented to recall regions. Due to ITK implementation 
+ *  if the pipeline of the algorithm has branch (diamond) one might have 
+ *  an input with two requested regions : one from branch 1 (A) and one from 
+ *  branch 2 (B). Problem is after updating and generating data on branch 1 
+ *  branch 2 will not propagate its region B again,and will use region A 
+ *  instead. By memorizing the region this buffer filter can be placed in 
+ *  in front of each branch so that the requested region will be saved.v
+ *
+ * \ingroup OTBImageManipulation
+ */
+
+template < class TInputImage >
+class ITK_EXPORT InPlacePassFilter :
+  public itk::InPlaceImageFilter < TInputImage , TInputImage >
+{
+public:
+  /** typedef for standard classes. */
+  typedef TInputImage InputImageType;
+
+  typedef InPlacePassFilter Self;
+  typedef itk::InPlaceImageFilter< InputImageType, InputImageType > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self)
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(InPlacePassFilter, InPlaceImageFilter)
+
+protected:
+  InPlacePassFilter() {
+    this->InPlaceOn();
+  }
+
+  ~InPlacePassFilter() override {}
+
+  void ThreadedGenerateData(
+      const typename InputImageType::RegionType & 
+        outputRegionForThread ,
+      itk::ThreadIdType itkNotUsed(threadId) ) override
+  {
+    typename InputImageType::ConstPointer input ( this->GetInput() );
+    typename InputImageType::Pointer output ( this->GetOutput() );
+    itk::ImageRegionConstIterator < InputImageType > it ( input , 
+                                                          outputRegionForThread );
+    itk::ImageRegionIterator < InputImageType > oit ( output ,
+                                                      outputRegionForThread );
+    for ( oit.GoToBegin() , it.GoToBegin() ; !oit.IsAtEnd() || !it.IsAtEnd() ;
+      ++it , ++oit )
+      {
+      oit.Set(it.Get());
+      }
+  }
+private:
+  InPlacePassFilter(const Self &) = delete ;
+  void operator =(const Self&) = delete ;
+
+};
+
+}  // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#endif
+  
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h
index b5c5870..d42cea9 100644
--- a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h
@@ -117,15 +117,12 @@ public:
   otbGetObjectMemberConstMacro(DisplacementFilter, Transform, const TransformType*);
 
   /** The Displacement field spacing & size */
-  void SetDisplacementFieldSpacing(const SpacingType & spacing)
-  {
-    m_DisplacementFilter->SetOutputSpacing(spacing);
-    this->Modified();
-  }
+  void SetDisplacementFieldSpacing( SpacingType spacing);
+
   const SpacingType & GetDisplacementFieldSpacing() const
   {
-   return m_DisplacementFilter->GetOutputSpacing();
-  }
+    return m_SignedOutputSpacing;
+  };
 
   /** The resampled image parameters */
   // Output Origin
@@ -193,6 +190,10 @@ private:
   StreamingResampleImageFilter(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
 
+  //We need this to respect ConstRef macro and to be compliant with itk positive 
+  //spacing
+  SpacingType m_SignedOutputSpacing;
+
   typename DisplacementFieldGeneratorType::Pointer   m_DisplacementFilter;
   typename WarpImageFilterType::Pointer             m_WarpFilter;
 };
diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx
index 71b4327..003425a 100644
--- a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx
+++ b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx
@@ -23,6 +23,7 @@
 
 #include "otbStreamingResampleImageFilter.h"
 #include "itkProgressAccumulator.h"
+#include "otbImage.h"
 
 namespace otb
 {
@@ -34,7 +35,7 @@ StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionTy
   // internal filters instantiation
   m_DisplacementFilter = DisplacementFieldGeneratorType::New();
   m_WarpFilter        = WarpImageFilterType::New();
-
+  m_SignedOutputSpacing = m_DisplacementFilter->GetOutputSpacing();
   // Initialize the displacement field spacing to zero : inconsistent
   // value
   this->SetDisplacementFieldSpacing(itk::NumericTraits<SpacingType>::ZeroValue());
@@ -121,11 +122,36 @@ StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionTy
 ::SetOutputParametersFromImage(const ImageBaseType * image)
 {
   this->SetOutputOrigin ( image->GetOrigin() );
-  this->SetOutputSpacing ( image->GetSpacing() );
+  this->SetOutputSpacing ( internal::GetSignedSpacing( image ) );
   this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() );
   this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() );
 }
 
+template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
+void
+StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionType>
+::SetDisplacementFieldSpacing( SpacingType outputSpacing )
+{
+  m_SignedOutputSpacing = outputSpacing;
+  typename TInputImage::DirectionType direction = this->m_DisplacementFilter->GetOutputDirection();
+  for(unsigned int i = 0; i < TInputImage::ImageDimension; ++i)
+    {
+    if ( outputSpacing[i] < 0 )
+      {
+      if ( direction[i][i] > 0 )
+        {
+        for(unsigned int j = 0; j < TInputImage::ImageDimension; ++j)
+          {
+          direction[j][i] = - direction[j][i];
+          }
+        }
+      outputSpacing[i] = - outputSpacing[i];
+      }
+    }
+  this->m_DisplacementFilter->SetOutputSpacing( outputSpacing );
+  this->m_DisplacementFilter->SetOutputDirection( direction );
+  this->Modified();
+}
 
 template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
 void
diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingShrinkImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbStreamingShrinkImageFilter.txx
index 68a55f3..124f20e 100644
--- a/Modules/Filtering/ImageManipulation/include/otbStreamingShrinkImageFilter.txx
+++ b/Modules/Filtering/ImageManipulation/include/otbStreamingShrinkImageFilter.txx
@@ -125,7 +125,7 @@ PersistentShrinkImageFilter<TInputImage, TOutputImage>
   m_ShrunkOutput->CopyInformation(inputPtr);
 
   const typename InputImageType::SpacingType&
-                                           inputSpacing = inputPtr->GetSpacing();
+                                           inputSpacing = inputPtr->GetSignedSpacing();
   const typename InputImageType::SizeType& inputSize
     = inputPtr->GetLargestPossibleRegion().GetSize();
   const typename InputImageType::IndexType& inputIndex
@@ -154,7 +154,7 @@ PersistentShrinkImageFilter<TInputImage, TOutputImage>
     shrunkOutputStartIndex[i] = 0;
     }
 
-  m_ShrunkOutput->SetSpacing(shrunkOutputSpacing);
+  m_ShrunkOutput->SetSignedSpacing(shrunkOutputSpacing);
   m_ShrunkOutput->SetOrigin(shrunkOutputOrigin);
 
   shrunkOutputLargestPossibleRegion.SetSize(shrunkOutputSize);
diff --git a/Modules/Filtering/ImageManipulation/include/otbTileImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbTileImageFilter.txx
index 4159907..3a67aa4 100644
--- a/Modules/Filtering/ImageManipulation/include/otbTileImageFilter.txx
+++ b/Modules/Filtering/ImageManipulation/include/otbTileImageFilter.txx
@@ -62,7 +62,7 @@ TileImageFilter<TImage>
     itkExceptionMacro(<<"Layout has "<<numberOfImages<<" tiles, but only "<<this->GetNumberOfInputs()<<" inputs are found.");
     }
 
-  typename ImageType::SpacingType spacing = this->GetInput()->GetSpacing();
+  typename ImageType::SpacingType spacing = this->GetInput()->GetSignedSpacing();
   unsigned int nbComp = this->GetInput()->GetNumberOfComponentsPerPixel();
 
   m_ColumnsSizes.clear();
@@ -94,7 +94,7 @@ TileImageFilter<TImage>
         itkExceptionMacro(<<"Inconsistent sizes in layout detected!");
         }
 
-      if(spacing != currentTile->GetSpacing())
+      if(spacing != currentTile->GetSignedSpacing())
         {
         itkExceptionMacro(<<"Inconsistent spacings in layout detected!");
         }
diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
index 48bf5e6..032074b 100644
--- a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
+++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
@@ -52,18 +52,17 @@ TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>
 ::GenerateOutputInformation(void)
 {
   Superclass::GenerateOutputInformation();
-  
+
   unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
-  
+
   if ( (nbCompo % 2) != 0 )
-  {
-	itkExceptionMacro("Number of bands of the input images must be an even number");
-  }
+    {
+    itkExceptionMacro("Number of bands of the input images must be an even number");
+    }
   else
-	this->GetOutput()->SetNumberOfComponentsPerPixel(nbCompo/2);
-	
-	std::cout << "GenerateOutputInformation : " << this->GetOutput()->GetNumberOfComponentsPerPixel() << std::endl;
-  
+    {
+    this->GetOutput()->SetNumberOfComponentsPerPixel(nbCompo/2);
+    }
 }
 
 /**
@@ -75,10 +74,10 @@ TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>
 ::BeforeThreadedGenerateData(void)
 {
 	unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
-			
+
 	if ( (nbCompo % 2) != 0 )
 	  itkExceptionMacro("Number of bands of the input images must be an even number");
-		
+
 }
 
 /**
diff --git a/Modules/Filtering/ImageManipulation/test/otbGridResampleImageFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbGridResampleImageFilter.cxx
index 8dbe679..c18e6cf 100644
--- a/Modules/Filtering/ImageManipulation/test/otbGridResampleImageFilter.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbGridResampleImageFilter.cxx
@@ -88,6 +88,22 @@ int otbGridResampleImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv)[])
   origin[1]=17;
   ImageType::SizeType outSize;
   outSize.Fill(103);
+  ImageType::DirectionType direction;
+  direction.SetIdentity();
+  ImageType::SpacingType uspacing;
+  for ( unsigned int i = 0 ; i < ImageType::ImageDimension ; i++ )
+    {
+    if (  spacing[i] < 0 )
+      {
+      uspacing[i] = -spacing[i];
+      for (unsigned int j = 0 ; j < ImageType::ImageDimension ; j++)
+        {
+        direction[j][i] = -direction[j][i];
+        }
+      }
+      else
+        uspacing[i] = spacing[i];
+    }
 
   filter->SetOutputSize(outSize);
   filter->SetOutputOrigin(origin);
@@ -95,7 +111,8 @@ int otbGridResampleImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv)[])
 
   refFilter->SetSize(outSize);
   refFilter->SetOutputOrigin(origin);
-  refFilter->SetOutputSpacing(spacing);
+  refFilter->SetOutputSpacing(uspacing);
+  refFilter->SetOutputDirection(direction);
 
   typedef otb::DifferenceImageFilter<ImageType,ImageType> ComparisonFilterType;
   typedef itk::StreamingImageFilter<ImageType,ImageType> StreamingFilterType;
diff --git a/Modules/Filtering/MathParser/include/otbBandMathImageFilter.txx b/Modules/Filtering/MathParser/include/otbBandMathImageFilter.txx
index 0a03bc5..919894c 100644
--- a/Modules/Filtering/MathParser/include/otbBandMathImageFilter.txx
+++ b/Modules/Filtering/MathParser/include/otbBandMathImageFilter.txx
@@ -181,7 +181,7 @@ void BandMathImageFilter<TImage>
     }
 
   // Store images specs
-  m_Spacing = this->GetNthInput(0)->GetSpacing();
+  m_Spacing = this->GetNthInput(0)->GetSignedSpacing();
   m_Origin = this->GetNthInput(0)->GetOrigin();
 
   // Allocate and initialize the thread temporaries
diff --git a/Modules/Filtering/MathParser/test/otbBandMathImageFilter.cxx b/Modules/Filtering/MathParser/test/otbBandMathImageFilter.cxx
index b1ebc4d..366e84b 100644
--- a/Modules/Filtering/MathParser/test/otbBandMathImageFilter.cxx
+++ b/Modules/Filtering/MathParser/test/otbBandMathImageFilter.cxx
@@ -237,11 +237,11 @@ int otbBandMathImageFilterWithIdx( int itkNotUsed(argc), char* argv[])
   IteratorType it3(image3, region);
 
   image1->SetOrigin(origin);
-  image1->SetSpacing(spacing);
+  image1->SetSignedSpacing(spacing);
   image2->SetOrigin(origin);
-  image2->SetSpacing(spacing);
+  image2->SetSignedSpacing(spacing);
   image3->SetOrigin(origin);
-  image3->SetSpacing(spacing);
+  image3->SetSignedSpacing(spacing);
 
   for (it1.GoToBegin(), it2.GoToBegin(), it3.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2, ++it3)
   {
diff --git a/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.txx b/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.txx
index 9407dba..11da024 100644
--- a/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.txx
+++ b/Modules/Filtering/MathParserX/include/otbBandMathXImageFilter.txx
@@ -665,13 +665,13 @@ void BandMathXImageFilter<TImage>
 
         if (m_AImage[i][j].type == 2) //imiPhyX
         {
-          SpacingType spacing = this->GetNthInput(m_AImage[i][j].info[0])->GetSpacing();
+          SpacingType spacing = this->GetNthInput(m_AImage[i][j].info[0])->GetSignedSpacing();
           m_AImage[i][j].value = ValueType(static_cast<double>(spacing[0]));
         }
 
         if (m_AImage[i][j].type == 3) //imiPhyY
         {
-          SpacingType spacing = this->GetNthInput(m_AImage[i][j].info[0])->GetSpacing();
+          SpacingType spacing = this->GetNthInput(m_AImage[i][j].info[0])->GetSignedSpacing();
           m_AImage[i][j].value = ValueType(static_cast<double>(spacing[1]));
         }
 
diff --git a/Modules/Filtering/MathParserX/test/otbBandMathXImageFilter.cxx b/Modules/Filtering/MathParserX/test/otbBandMathXImageFilter.cxx
index d48b558..111441b 100644
--- a/Modules/Filtering/MathParserX/test/otbBandMathXImageFilter.cxx
+++ b/Modules/Filtering/MathParserX/test/otbBandMathXImageFilter.cxx
@@ -520,11 +520,11 @@ int otbBandMathXImageFilterWithIdx( int itkNotUsed(argc), char* argv[])
   IteratorType it3(image3, region);
 
   image1->SetOrigin(origin);
-  image1->SetSpacing(spacing);
+  image1->SetSignedSpacing(spacing);
   image2->SetOrigin(origin);
-  image2->SetSpacing(spacing);
+  image2->SetSignedSpacing(spacing);
   image3->SetOrigin(origin);
-  image3->SetSpacing(spacing);
+  image3->SetSignedSpacing(spacing);
 
   for (it1.GoToBegin(), it2.GoToBegin(), it3.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2, ++it3)
   {
diff --git a/Modules/Filtering/MorphologicalPyramid/include/otbMorphologicalPyramidResampler.txx b/Modules/Filtering/MorphologicalPyramid/include/otbMorphologicalPyramidResampler.txx
index 2146f7b..b1fad67 100644
--- a/Modules/Filtering/MorphologicalPyramid/include/otbMorphologicalPyramidResampler.txx
+++ b/Modules/Filtering/MorphologicalPyramid/include/otbMorphologicalPyramidResampler.txx
@@ -96,7 +96,7 @@ Resampler<TInputImage, TOutputImage>
     }
   unsigned int i;
   // Computing output spacing, size and index from input data
-  const typename InputImageType::SpacingType& inputSpacing    = inputPtr->GetSpacing();
+  const typename InputImageType::SpacingType& inputSpacing    = inputPtr->GetSignedSpacing();
   const typename InputImageType::IndexType&   inputStartIndex = inputPtr->GetLargestPossibleRegion().GetIndex();
   typename OutputImageType::IndexType         outputStartIndex;
   typename OutputImageType::SpacingType       spacing;
@@ -105,7 +105,7 @@ Resampler<TInputImage, TOutputImage>
     outputStartIndex[i] =  inputStartIndex[i];
     }
 
-  outputPtr->SetSpacing(inputSpacing);
+  outputPtr->SetSignedSpacing(inputSpacing);
   typename OutputImageType::RegionType outputLargestPossibleRegion;
   outputLargestPossibleRegion.SetSize(this->GetSize());
   outputLargestPossibleRegion.SetIndex(outputStartIndex);
@@ -134,7 +134,7 @@ Resampler<TInputImage, TOutputImage>
   // Scale parameters computation
   typename TransformType::InputVectorType scales;
   typename InputImageType::SizeType    inputSize = this->GetInput()->GetLargestPossibleRegion().GetSize();
-  typename InputImageType::SpacingType inputSpacing = this->GetInput()->GetSpacing();
+  typename InputImageType::SpacingType inputSpacing = this->GetInput()->GetSignedSpacing();
   scales[0] = static_cast<double>(inputSize[0]) / static_cast<double>(m_Size[0]);
   scales[1] = static_cast<double>(inputSize[1]) / static_cast<double>(m_Size[1]);
   transform->SetScale(scales);
@@ -150,7 +150,8 @@ Resampler<TInputImage, TOutputImage>
   resampler->SetInterpolator(interpolator);
   resampler->SetOutputOrigin(this->GetInput()->GetOrigin());
   resampler->SetSize(this->GetSize());
-  resampler->SetOutputSpacing(inputSpacing);
+  resampler->SetOutputSpacing( this->GetInput()->GetSpacing() );
+  resampler->SetOutputDirection( this->GetInput()->GetDirection() );
   resampler->ReleaseDataFlagOn();
 
   // Progress accumulator
diff --git a/Modules/Filtering/Path/include/otbRegionImageToRectangularPathListFilter.txx b/Modules/Filtering/Path/include/otbRegionImageToRectangularPathListFilter.txx
index 4b32e9d..abb678b 100644
--- a/Modules/Filtering/Path/include/otbRegionImageToRectangularPathListFilter.txx
+++ b/Modules/Filtering/Path/include/otbRegionImageToRectangularPathListFilter.txx
@@ -82,7 +82,7 @@ RegionImageToRectangularPathListFilter<TInputImage, TOutputPath>
   typename InputImageType::PointType   origin;
   typename InputImageType::SpacingType spacing;
   origin = InputImage->GetOrigin();
-  spacing = InputImage->GetSpacing();
+  spacing = InputImage->GetSignedSpacing();
   std::cout << "Image origin : " << origin << std::endl;
   std::cout << "Image spacing : " << spacing << std::endl;
 
diff --git a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx
index 4a5c0ed..923a07f 100644
--- a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx
+++ b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx
@@ -87,7 +87,7 @@ MultiChannelsPolarimetricSynthesisFilter<TInputImage, TOutputImage, TFunction>
     // dimensions to copy
     unsigned int i, j;
     const typename InputImageType::SpacingType&
-    inputSpacing = inputPtr->GetSpacing();
+    inputSpacing = inputPtr->GetSignedSpacing();
     const typename InputImageType::PointType&
     inputOrigin = inputPtr->GetOrigin();
     const typename InputImageType::DirectionType&
@@ -133,7 +133,7 @@ MultiChannelsPolarimetricSynthesisFilter<TInputImage, TOutputImage, TFunction>
       }
 
     // set the spacing and origin
-    outputPtr->SetSpacing(outputSpacing);
+    outputPtr->SetSignedSpacing(outputSpacing);
     outputPtr->SetOrigin(outputOrigin);
     outputPtr->SetDirection(outputDirection);
 
diff --git a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx
index ac6c362..7635cdc 100644
--- a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx
+++ b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx
@@ -225,7 +225,7 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage>
   const InputImageType * src = dynamic_cast<const InputImageType*>(image);
 
   this->SetOutputOrigin ( src->GetOrigin() );
-  this->SetOutputSpacing ( src->GetSpacing() );
+  this->SetOutputSpacing ( src->GetSignedSpacing() );
   this->SetOutputStartIndex ( src->GetLargestPossibleRegion().GetIndex() );
   this->SetOutputSize ( src->GetLargestPossibleRegion().GetSize() );
   this->SetOutputProjectionRef(src->GetProjectionRef());
@@ -243,7 +243,7 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage>
 ::SetOutputParametersFromImage(const TImageType * image)
 {
   this->SetOutputOrigin ( image->GetOrigin() );
-  this->SetOutputSpacing ( image->GetSpacing() );
+  this->SetOutputSpacing ( image->GetSignedSpacing() );
   this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() );
   this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() );
   this->SetOutputProjectionRef(image->GetProjectionRef());
diff --git a/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.txx b/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.txx
index bd152c5..acc9210 100644
--- a/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.txx
+++ b/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.txx
@@ -131,7 +131,7 @@ GroundSpacingImageFunction<TInputImage, TCoordRep>
   const itk::MetaDataDictionary& inputDict = this->GetInputImage()->GetMetaDataDictionary();
   transform->SetInputDictionary(inputDict);
   transform->SetInputOrigin(this->GetInputImage()->GetOrigin());
-  transform->SetInputSpacing(this->GetInputImage()->GetSpacing());
+  transform->SetInputSpacing(this->GetInputImage()->GetSignedSpacing());
 
   transform->InstantiateTransform();
   return transform->TransformPoint(inputPoint);
diff --git a/Modules/Filtering/Projection/include/otbImportGeoInformationImageFilter.txx b/Modules/Filtering/Projection/include/otbImportGeoInformationImageFilter.txx
index 1b0cf01..35e9ba8 100644
--- a/Modules/Filtering/Projection/include/otbImportGeoInformationImageFilter.txx
+++ b/Modules/Filtering/Projection/include/otbImportGeoInformationImageFilter.txx
@@ -102,7 +102,7 @@ ImportGeoInformationImageFilter<TImage, TSourceImage>
 //   outputPtr->CopyInformation(sourcePtr);
 //   // Don't forget to copy also the origin and spacing, not handled by the CopyInformation method.
 //   outputPtr->SetOrigin(sourcePtr->GetOrigin());
-//   outputPtr->SetSpacing(sourcePtr->GetSpacing());
+//   outputPtr->SetSignedSpacing(sourcePtr->GetSignedSpacing());
 // }
 
 /**
diff --git a/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.txx b/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.txx
index 2f8e542..01c1048 100644
--- a/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.txx
+++ b/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.txx
@@ -81,8 +81,8 @@ PhysicalToRPCSensorModelImageFilter<TImage>
       for(unsigned int py = 0; py<m_GridSize[1]; ++py)
         {
         PointType inputPoint =  input->GetOrigin();
-        inputPoint[0] += (px * gridSpacingX + 0.5) * input->GetSpacing()[0];
-        inputPoint[1] += (py * gridSpacingY + 0.5) * input->GetSpacing()[1];
+        inputPoint[0] += (px * gridSpacingX + 0.5) * input->GetSignedSpacing()[0];
+        inputPoint[1] += (py * gridSpacingY + 0.5) * input->GetSignedSpacing()[1];
         PointType outputPoint = rsTransform->TransformPoint(inputPoint);
         m_GCPsToSensorModelFilter->AddGCP(inputPoint, outputPoint);
         }
diff --git a/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.h b/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.h
index b55573f..b86c9c7 100644
--- a/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.h
+++ b/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.h
@@ -93,7 +93,7 @@ public:
   itkGetConstReferenceMacro(OutputOrigin, OriginType);
 
   /** Set the spacing (size of a pixel) of the output vector data.
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   virtual void SetOutputSpacing(const SpacingType& spacing);
   virtual void SetOutputSpacing(const double spacing[2]);
   virtual void SetOutputSpacing(const float spacing[2]);
diff --git a/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.txx b/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.txx
index b38ec9f..ccf2dc4 100644
--- a/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.txx
+++ b/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.txx
@@ -128,7 +128,7 @@ VectorDataIntoImageProjectionFilter<TInputVectorData, TInputImage>
     itkExceptionMacro("Invalid input image.");
     }
 
-  /*std::cout << "Spacing of the input image: "<< m_InputImage->GetSpacing() << std::endl;
+  /*std::cout << "Spacing of the input image: "<< m_InputImage->GetSignedSpacing() << std::endl;
   std::cout << "Origin of the input image: "<< m_InputImage->GetOrigin() << std::endl;
   std::cout << "Size of the input image: "<< m_InputImage->GetLargestPossibleRegion() << std::endl;
   std::cout << "ProjRef of the input image: "<< m_InputImage->GetProjectionRef() << std::endl;
@@ -203,7 +203,7 @@ VectorDataIntoImageProjectionFilter<TInputVectorData, TInputImage>
   if (m_UseOutputSpacingAndOriginFromImage)
     {
     m_VdProjFilter->SetOutputOrigin(m_InputImage->GetOrigin());
-    m_VdProjFilter->SetOutputSpacing(m_InputImage->GetSpacing());
+    m_VdProjFilter->SetOutputSpacing(m_InputImage->GetSignedSpacing());
     }
   else
     {
diff --git a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h
index 18fc934..3178d4c 100644
--- a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h
+++ b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h
@@ -150,7 +150,7 @@ public:
   itkGetConstReferenceMacro(InputOrigin, OriginType);
 
   /** Set the spacing (size of a pixel) of the vector data.
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   virtual void SetInputSpacing(const SpacingType& spacing);
   virtual void SetInputSpacing(const double spacing[2]);
   virtual void SetInputSpacing(const float spacing[2]);
@@ -166,7 +166,7 @@ public:
   itkGetConstReferenceMacro(OutputOrigin, OriginType);
 
   /** Set the spacing (size of a pixel) of the vector data.
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   virtual void SetOutputSpacing(const SpacingType& spacing);
   virtual void SetOutputSpacing(const double spacing[2]);
   virtual void SetOutputSpacing(const float spacing[2]);
diff --git a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.txx b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.txx
index 613de9a..1cc7ddc 100644
--- a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.txx
+++ b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.txx
@@ -25,7 +25,7 @@
 #include "itkProgressReporter.h"
 #include "itkMetaDataObject.h"
 #include "otbMetaDataKey.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 namespace otb
 {
@@ -358,11 +358,10 @@ VectorDataProjectionFilter<TInputVectorData, TOutputVectorData>
   tree->SetRoot(outputRoot);
 
   // Start recursive processing
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   this->ProcessNode(inputRoot, outputRoot);
   chrono.Stop();
-  otbMsgDevMacro(<< "VectoDataProjectionFilter: features Processed in " << chrono.GetMean() << " seconds.");
+  otbMsgDevMacro(<< "VectoDataProjectionFilter: features processed in " << chrono.GetElapsedMilliseconds() << " ms.");
 }
 
 } // end namespace otb
diff --git a/Modules/Filtering/Projection/include/otbVectorDataTransformFilter.txx b/Modules/Filtering/Projection/include/otbVectorDataTransformFilter.txx
index 223f498..2ab6aac 100644
--- a/Modules/Filtering/Projection/include/otbVectorDataTransformFilter.txx
+++ b/Modules/Filtering/Projection/include/otbVectorDataTransformFilter.txx
@@ -24,7 +24,7 @@
 #include "otbVectorDataTransformFilter.h"
 #include "itkProgressReporter.h"
 #include <itkContinuousIndex.h>
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 namespace otb
 {
@@ -163,10 +163,10 @@ VectorDataTransformFilter<TInputVectorData, TOutputVectorData>
   tree->SetRoot(outputRoot);
 
   // Start recursive processing
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   this->ProcessNode(inputRoot, outputRoot);
   chrono.Stop();
+  otbMsgDevMacro(<< "VectorDataTransformFilter: features processed in " << chrono.GetElapsedMilliseconds() << " ms.");
 }
 
 } // end namespace otb
diff --git a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromGeoToMap.cxx b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromGeoToMap.cxx
index decd1d3..b4ea5eb 100644
--- a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromGeoToMap.cxx
+++ b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromGeoToMap.cxx
@@ -65,7 +65,7 @@ int otbGeometriesProjectionFilterFromGeoToMap(int argc, char * argv[])
   filter->SetOutput(out_set);
   filter->SetOutputProjectionRef(imageReader->GetOutput()->GetProjectionRef());
   filter->SetOutputOrigin(imageReader->GetOutput()->GetOrigin());
-  filter->SetOutputSpacing(imageReader->GetOutput()->GetSpacing());
+  filter->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing());
 
   filter->Update();
 
diff --git a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToImage.cxx b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToImage.cxx
index bbca57f..da3833b 100644
--- a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToImage.cxx
+++ b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToImage.cxx
@@ -65,7 +65,7 @@ int otbGeometriesProjectionFilterFromMapToImage(int argc, char * argv[])
   filter->SetOutput(out_set);
   filter->SetOutputProjectionRef(imageReader->GetOutput()->GetProjectionRef());
   filter->SetOutputOrigin(imageReader->GetOutput()->GetOrigin());
-  filter->SetOutputSpacing(imageReader->GetOutput()->GetSpacing());
+  filter->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing());
 
   filter->Update();
 
diff --git a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx
index 1d86a40..ec0a201 100644
--- a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx
+++ b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx
@@ -65,7 +65,7 @@ int otbGeometriesProjectionFilterFromMapToSensor(int argc, char * argv[])
   filter->SetOutput(out_set);
   filter->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist());
   filter->SetOutputOrigin(imageReader->GetOutput()->GetOrigin());
-  filter->SetOutputSpacing(imageReader->GetOutput()->GetSpacing());
+  filter->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing());
 
   filter->Update();
 
diff --git a/Modules/Filtering/Projection/test/otbImportGeoInformationImageFilter.cxx b/Modules/Filtering/Projection/test/otbImportGeoInformationImageFilter.cxx
index ea687e9..a8d11a8 100644
--- a/Modules/Filtering/Projection/test/otbImportGeoInformationImageFilter.cxx
+++ b/Modules/Filtering/Projection/test/otbImportGeoInformationImageFilter.cxx
@@ -56,7 +56,7 @@ int otbImportGeoInformationImageFilter(int itkNotUsed(argc), char * argv[])
   std::cout << "black: " << black->GetLargestPossibleRegion() << std::endl;
 
   black->SetOrigin(reader->GetOutput()->GetOrigin());
-  black->SetSpacing(reader->GetOutput()->GetSpacing());
+  black->SetSignedSpacing(reader->GetOutput()->GetSignedSpacing());
 
   import->SetInput(black);
   import->SetSource(reader->GetOutput());
diff --git a/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx b/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx
index 13d39b4..9e2a16f 100644
--- a/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx
+++ b/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx
@@ -67,9 +67,9 @@ int otbTileImageFilterRSTransformTest(int argc, char * argv[])
 
     // Compute tile center
     PointType center = reader->GetOutput()->GetOrigin();
-    center[0] += reader->GetOutput()->GetSpacing()[0]
+    center[0] += reader->GetOutput()->GetSignedSpacing()[0]
                 * reader->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2;
-    center[1] += reader->GetOutput()->GetSpacing()[1]
+    center[1] += reader->GetOutput()->GetSignedSpacing()[1]
                 * reader->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2;
     points.push_back(center);
 
diff --git a/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx b/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx
index e7efcbf..be39753 100644
--- a/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx
+++ b/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx
@@ -227,7 +227,7 @@ int otbVectorDataIntoImageProjectionFilterCompareImplTest(int itkNotUsed(argc),
   vproj->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist());
   vproj->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef());
   vproj->SetOutputOrigin(reader->GetOutput()->GetOrigin());
-  vproj->SetOutputSpacing(reader->GetOutput()->GetSpacing());
+  vproj->SetOutputSpacing(reader->GetOutput()->GetSignedSpacing());
 
   //----------
   // WRITE
diff --git a/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToImage.cxx b/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToImage.cxx
index 6f4946b..6971f7f 100644
--- a/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToImage.cxx
+++ b/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToImage.cxx
@@ -60,7 +60,7 @@ int otbVectorDataProjectionFilterFromMapToImage(int argc, char * argv[])
 
   vectorDataProjection->SetOutputProjectionRef(imageReader->GetOutput()->GetProjectionRef());
   vectorDataProjection->SetOutputOrigin(imageReader->GetOutput()->GetOrigin());
-  vectorDataProjection->SetOutputSpacing(imageReader->GetOutput()->GetSpacing());
+  vectorDataProjection->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing());
 
   typedef otb::VectorDataFileWriter<OutputVectorDataType> VectorDataFileWriterType;
   VectorDataFileWriterType::Pointer writer = VectorDataFileWriterType::New();
diff --git a/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx b/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx
index 888f096..299a14d 100644
--- a/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx
+++ b/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx
@@ -60,7 +60,7 @@ int otbVectorDataProjectionFilterFromMapToSensor(int argc, char * argv[])
 
   vectorDataProjection->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist());
   vectorDataProjection->SetOutputOrigin(imageReader->GetOutput()->GetOrigin());
-  vectorDataProjection->SetOutputSpacing(imageReader->GetOutput()->GetSpacing());
+  vectorDataProjection->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing());
 
   typedef otb::VectorDataFileWriter<OutputVectorDataType> VectorDataFileWriterType;
   VectorDataFileWriterType::Pointer writer = VectorDataFileWriterType::New();
diff --git a/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx b/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx
index d4b30d1..e0f5ee5 100644
--- a/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx
+++ b/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx
@@ -75,7 +75,7 @@ int otbVectorDataTransformFilter (int itkNotUsed(argc), char * argv[])
   TransformType::Pointer transform = TransformType::New();
   TranslationParamType   translationParam;
   translationParam[0] = 0;
-  translationParam[1] = 8. * reader->GetOutput()->GetSpacing()[1];
+  translationParam[1] = 8. * reader->GetOutput()->GetSignedSpacing()[1];
   transform->SetTranslation(translationParam);
 
   VectorDataTransformType::Pointer transformFilter = VectorDataTransformType::New();
diff --git a/Modules/Filtering/Statistics/include/otbListSampleGenerator.txx b/Modules/Filtering/Statistics/include/otbListSampleGenerator.txx
index 995e109..d1fc246 100644
--- a/Modules/Filtering/Statistics/include/otbListSampleGenerator.txx
+++ b/Modules/Filtering/Statistics/include/otbListSampleGenerator.txx
@@ -435,7 +435,7 @@ double
 ListSampleGenerator<TImage, TVectorData>
 ::GetPolygonAreaInPixelsUnits(DataNodeType* polygonDataNode, ImageType* image)
 {
-  const double pixelArea = vcl_abs(image->GetSpacing()[0] * image->GetSpacing()[1]);
+  const double pixelArea = vcl_abs(image->GetSignedSpacing()[0] * image->GetSignedSpacing()[1]);
 
   // Compute area of exterior ring in pixels
   PolygonPointerType exteriorRing = polygonDataNode->GetPolygonExteriorRing();
diff --git a/Modules/Filtering/Statistics/test/otbContinuousMinimumMaximumImageCalculatorTest.cxx b/Modules/Filtering/Statistics/test/otbContinuousMinimumMaximumImageCalculatorTest.cxx
index bd2431c..d8ab360 100644
--- a/Modules/Filtering/Statistics/test/otbContinuousMinimumMaximumImageCalculatorTest.cxx
+++ b/Modules/Filtering/Statistics/test/otbContinuousMinimumMaximumImageCalculatorTest.cxx
@@ -54,7 +54,7 @@ otbContinuousMinimumMaximumImageCalculatorTest(int, char *[])
 
   // Set origin and spacing of physical coordinates
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   PixelType minimum = -52;
   PixelType maximum = 103;
diff --git a/Modules/Filtering/VectorDataManipulation/include/otbConcatenateVectorDataFilter.txx b/Modules/Filtering/VectorDataManipulation/include/otbConcatenateVectorDataFilter.txx
index a9de4ed..ac33263 100644
--- a/Modules/Filtering/VectorDataManipulation/include/otbConcatenateVectorDataFilter.txx
+++ b/Modules/Filtering/VectorDataManipulation/include/otbConcatenateVectorDataFilter.txx
@@ -24,7 +24,6 @@
 #include "otbConcatenateVectorDataFilter.h"
 
 #include "otbMath.h"
-#include "itkTimeProbe.h"
 
 namespace otb
 {
diff --git a/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.txx b/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.txx
index abaa183..4a80723 100644
--- a/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.txx
+++ b/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.txx
@@ -31,7 +31,7 @@
 #include "otbMacro.h"
 
 #include "itkProgressReporter.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 namespace otb
 {
@@ -110,12 +110,11 @@ VectorDataExtractROI<TVectorData>
   m_Kept  = 0;
 
   // Start recursive processing
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   ProcessNode(inputRoot, outputRoot);
   chrono.Stop();
   otbMsgDevMacro(
-    << "VectorDataExtractROI: " << m_Kept << " Features processed in " << chrono.GetMean() << " seconds.");
+    << "VectorDataExtractROI: " << m_Kept << " features processed in " << chrono.GetElapsedMilliseconds() << " ms.");
 } /*End GenerateData()*/
 
 template <class TVectorData>
diff --git a/Modules/Filtering/VectorDataManipulation/include/otbVectorDataToVectorDataFilter.txx b/Modules/Filtering/VectorDataManipulation/include/otbVectorDataToVectorDataFilter.txx
index 0007ac1..6c0c5da 100644
--- a/Modules/Filtering/VectorDataManipulation/include/otbVectorDataToVectorDataFilter.txx
+++ b/Modules/Filtering/VectorDataManipulation/include/otbVectorDataToVectorDataFilter.txx
@@ -24,7 +24,7 @@
 #include "otbVectorDataToVectorDataFilter.h"
 #include "itkProgressReporter.h"
 #include "otbDataNode.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 namespace otb
 {
@@ -104,11 +104,10 @@ VectorDataToVectorDataFilter<TInputVectorData, TOutputVectorData>
   tree->SetRoot(outputRoot);
 
   // Start recursive processing
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   this->ProcessNode(inputRoot, outputRoot);
   chrono.Stop();
-  otbMsgDevMacro(<< "VectoDataProjectionFilter: features Processed in " << chrono.GetMean() << " seconds.");
+  otbMsgDevMacro(<< "VectoDataProjectionFilter: features processed in " << chrono.GetElapsedMilliseconds() << " ms.");
 }
 
 template <class TInputVectorData, class TOutputVectorData>
diff --git a/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.h b/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.h
index 976b041..57beb9e 100644
--- a/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.h
+++ b/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.h
@@ -152,7 +152,7 @@ public:
   itkGetConstReferenceMacro(Origin, OriginType);
 
   /** Set the spacing (size of a pixel) of the vector data.
-  * \sa GetSpacing() */
+  * \sa GetSignedSpacing() */
   virtual void SetSpacing(const SpacingType& spacing);
   virtual void SetSpacing(const double spacing[2]);
   virtual void SetSpacing(const float spacing[2]);
diff --git a/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.txx b/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.txx
index 62a651e..24e660e 100644
--- a/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.txx
+++ b/Modules/Filtering/VectorDataRendering/include/otbVectorDataToMapFilter.txx
@@ -182,9 +182,12 @@ VectorDataToMapFilter<TVectorData, TImage>
   outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
 
   // Set spacing and origin
-  outputPtr->SetSpacing(m_Spacing);
+  outputPtr->SetSignedSpacing(m_Spacing);
   outputPtr->SetOrigin(m_Origin);
-  outputPtr->SetDirection(m_Direction);
+  // outputPtr->SetDirection(m_Direction);
+  // As the direction cannot be changed in this filter there is no need to set
+  // the direction in the output image. Moreover, setting the direction to
+  // identity no that we enforce positive spacing leads to incoherences 
 
   itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
   itk::EncapsulateMetaData<std::string> (dict, MetaDataKey::ProjectionRefKey,
diff --git a/Modules/Filtering/VectorDataRendering/test/otbVectorDataToMapFilterSensorModel.cxx b/Modules/Filtering/VectorDataRendering/test/otbVectorDataToMapFilterSensorModel.cxx
index 845c394..bbe6a7a 100644
--- a/Modules/Filtering/VectorDataRendering/test/otbVectorDataToMapFilterSensorModel.cxx
+++ b/Modules/Filtering/VectorDataRendering/test/otbVectorDataToMapFilterSensorModel.cxx
@@ -65,7 +65,7 @@ int otbVectorDataToMapFilterSensorModel(int argc, char * argv [])
 
   projection->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist());
   projection->SetOutputOrigin(imageReader->GetOutput()->GetOrigin());
-  projection->SetOutputSpacing(imageReader->GetOutput()->GetSpacing());
+  projection->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing());
 
   //Convert the vector data into an image
   typedef itk::RGBAPixel<unsigned char> PixelType;
diff --git a/Modules/Fusion/MajorityVoting/test/otbNeighborhoodMajorityVotingImageFilterTest.cxx b/Modules/Fusion/MajorityVoting/test/otbNeighborhoodMajorityVotingImageFilterTest.cxx
index 699e352..4d8a7b7 100644
--- a/Modules/Fusion/MajorityVoting/test/otbNeighborhoodMajorityVotingImageFilterTest.cxx
+++ b/Modules/Fusion/MajorityVoting/test/otbNeighborhoodMajorityVotingImageFilterTest.cxx
@@ -28,8 +28,6 @@
 
 #include "otbNeighborhoodMajorityVotingImageFilter.h"
 
-#include "itkTimeProbe.h"
-
 
 int otbNeighborhoodMajorityVotingImageFilterTest(int argc, char* argv[])
 {
@@ -160,7 +158,7 @@ int otbNeighborhoodMajorityVotingImageFilterIsolatedTest(int itkNotUsed(argc), c
 
 
   NeighMajVotingFilter->SetKeepOriginalLabelBool(true);
-    
+
   rad[0] = 1;
   rad[1] = 1;
   NeighMajVotingFilter->SetLabelForNoDataPixels(10);
diff --git a/Modules/IO/ExtendedFilename/test/otbExtendedFilenameTest.cxx b/Modules/IO/ExtendedFilename/test/otbExtendedFilenameTest.cxx
index 137e5ee..f2e6cf1 100644
--- a/Modules/IO/ExtendedFilename/test/otbExtendedFilenameTest.cxx
+++ b/Modules/IO/ExtendedFilename/test/otbExtendedFilenameTest.cxx
@@ -55,7 +55,7 @@ int otbImageFileReaderWithExtendedFilename(int itkNotUsed(argc), char* argv[])
 
   file2 << "ProjRef: " << reader->GetOutput()->GetProjectionRef() << std::endl;
   file2 << "Origin: "  << reader->GetOutput()->GetOrigin() << std::endl;
-  file2 << "Spacing: " << reader->GetOutput()->GetSpacing() << std::endl;
+  file2 << "Spacing: " << reader->GetOutput()->GetSignedSpacing() << std::endl;
 
   return EXIT_SUCCESS;
 }
diff --git a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
index 812c938..f4cfe1e 100644
--- a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
+++ b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx
@@ -25,6 +25,7 @@
 #include "otbGDALImageIO.h"
 #include "otbMacro.h"
 #include "otbSystem.h"
+#include "otbStopwatch.h"
 #include "itksys/SystemTools.hxx"
 #include "otbImage.h"
 #include "otb_tinyxml.h"
@@ -35,7 +36,6 @@
 
 #include "itkRGBPixel.h"
 #include "itkRGBAPixel.h"
-#include "itkTimeProbe.h"
 
 #include "cpl_conv.h"
 #include "ogr_spatialref.h"
@@ -408,8 +408,7 @@ void GDALImageIO::Read(void* buffer)
                    << " lineOffset = " << lineOffset << "\n"
                    << " bandOffset = " << bandOffset );
 
-    itk::TimeProbe chrono;
-    chrono.Start();
+    otb::Stopwatch chrono = otb::Stopwatch::StartNew();
     CPLErr lCrGdal = m_Dataset->GetDataSet()->RasterIO(GF_Read,
                                                        lFirstColumn,
                                                        lFirstLine,
@@ -426,7 +425,7 @@ void GDALImageIO::Read(void* buffer)
                                                        lineOffset,
                                                        bandOffset);
     chrono.Stop();
-    otbMsgDevMacro(<< "RasterIO Read took " << chrono.GetTotal() << " sec")
+    otbMsgDevMacro(<< "RasterIO Read took " << chrono.GetElapsedMilliseconds() << " ms")
 
     // Check if gdal call succeed
     if (lCrGdal == CE_Failure)
@@ -1211,7 +1210,7 @@ void GDALImageIO::InternalReadImageInformation()
       // automatically read as a color image (using the palette). Perhaps this
       // behaviour should be restricted.  Comment color table interpretation in
       // gdalimageio
-  
+
       // FIXME: Better support of color table in OTB
       // - disable palette conversion in GDALImageIO (the comments in this part
       // of the code are rather careful)
@@ -1219,7 +1218,7 @@ void GDALImageIO::InternalReadImageInformation()
       // a kind of LUT ?).
       // - ImageFileReader should use a kind of adapter filter to convert the mono
       // image into color.
-      
+
       // Do not set indexed image attribute to true
       //m_IsIndexed = true;
 
@@ -1387,8 +1386,7 @@ void GDALImageIO::Write(const void* buffer)
                  "\n, Line offset =" << m_BytePerPixel * m_NbBands * lNbColumns << // is pixelOffset * nbColumns
                  "\n, Band offset =" <<  m_BytePerPixel) //  is BytePerPixel
 
-                 itk::TimeProbe chrono;
-    chrono.Start();
+    otb::Stopwatch chrono = otb::Stopwatch::StartNew();
     CPLErr lCrGdal = m_Dataset->GetDataSet()->RasterIO(GF_Write,
                                                        lFirstColumn,
                                                        lFirstLine,
@@ -1410,7 +1408,7 @@ void GDALImageIO::Write(const void* buffer)
                                                        // Band offset is BytePerPixel
                                                        m_BytePerPixel);
     chrono.Stop();
-    otbMsgDevMacro(<< "RasterIO Write took " << chrono.GetTotal() << " sec")
+    otbMsgDevMacro(<< "RasterIO Write took " << chrono.GetElapsedMilliseconds() << " ms")
 
     // Check if writing succeed
     if (lCrGdal == CE_Failure)
@@ -1686,8 +1684,8 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
   if (projectionRef.empty()
       &&  (vcl_abs(m_Origin[0] - 0.5) > Epsilon
            || vcl_abs(m_Origin[1] - 0.5) > Epsilon
-           || vcl_abs(m_Spacing[0] - 1.0) > Epsilon
-           || vcl_abs(m_Spacing[1] - 1.0) > Epsilon) )
+           || vcl_abs(m_Spacing[0] * m_Direction[0][0] - 1.0) > Epsilon
+           || vcl_abs(m_Spacing[1] * m_Direction[1][1] - 1.0) > Epsilon) )
     {
     // See issue #303 :
     // If there is no ProjectionRef, and the GeoTransform is not the identity,
@@ -1768,18 +1766,18 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
   /* -------------------------------------------------------------------- */
   if ( vcl_abs(m_Origin[0] - 0.5) > Epsilon
     || vcl_abs(m_Origin[1] - 0.5) > Epsilon
-    || vcl_abs(m_Spacing[0] - 1.0) > Epsilon
-    || vcl_abs(m_Spacing[1] - 1.0) > Epsilon )
+    || vcl_abs(m_Spacing[0] * m_Direction[0][0] - 1.0) > Epsilon
+    || vcl_abs(m_Spacing[1] * m_Direction[1][1] - 1.0) > Epsilon )
     {
     // Only set the geotransform if it is not identity (it may erase GCP)
     itk::VariableLengthVector<double> geoTransform(6);
     /// Reporting origin and spacing
     // Beware : GDAL origin is at the corner of the top-left pixel
     // whereas OTB/ITK origin is at the centre of the top-left pixel
-    geoTransform[0] = m_Origin[0] - 0.5*m_Spacing[0];
-    geoTransform[3] = m_Origin[1] - 0.5*m_Spacing[1];
-    geoTransform[1] = m_Spacing[0];
-    geoTransform[5] = m_Spacing[1];
+    geoTransform[0] = m_Origin[0] - 0.5 * m_Spacing[0] * m_Direction[0][0];
+    geoTransform[3] = m_Origin[1] - 0.5 * m_Spacing[1] * m_Direction[1][1];
+    geoTransform[1] = m_Spacing[0] * m_Direction[0][0];
+    geoTransform[5] = m_Spacing[1] * m_Direction[1][1];
 
     // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
     geoTransform[2] = 0.;
diff --git a/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx b/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx
index c988cc5..7b6608c 100644
--- a/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx
+++ b/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx
@@ -30,6 +30,7 @@
 #include "otbGDALImageIO.h"
 #include "otbSystem.h"
 
+#include <cctype>
 
 namespace otb
 {
@@ -100,7 +101,32 @@ GDALOverviewsBuilder
 
   io->SetFileName( filename );
 
-  return !io->GetSubDatasetInfo( names, descs );
+  // no overview for containers
+  if(io->GetSubDatasetInfo( names, descs ))
+    return false;
+
+  // no overview for VSI datasets
+  if (filename.size()>8 && filename.compare(0, 4, "/vsi") == 0)
+    {
+    size_t pos = filename.find('/',4);
+    if (pos != std::string::npos)
+      {
+      bool isVSI = true;
+      for (unsigned int i=4; i<pos ; i++)
+        {
+        int c = filename[i];
+        if ( !(std::islower(c) || std::isdigit(c) || c == '_' ) )
+          {
+          isVSI = false;
+          break;
+          }
+        }
+      if (isVSI)
+        return false;
+      }
+    }
+
+  return true;
 }
 
 /***************************************************************************/
diff --git a/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx b/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
index 53b6199..2217732 100644
--- a/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
+++ b/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
@@ -23,7 +23,7 @@
 #include "otbMacro.h"
 #include "ogrsf_frmts.h"
 #include "otbOGR.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 namespace otb
 {
@@ -188,11 +188,10 @@ void OGRIOHelper
   layer->ResetReading();
 
   unsigned int   counter = 0;
-  itk::TimeProbe chrono;
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
 
   while ((feature = layer->GetNextFeature()) != ITK_NULLPTR)
     {
-    chrono.Start();
 
     // A pointer to the current multi-geometry
     InternalTreeNodeType::Pointer multiPtr;
@@ -203,7 +202,6 @@ void OGRIOHelper
     if (geometry == ITK_NULLPTR)
       {
       OGRFeature::DestroyFeature(feature);
-      chrono.Stop();
       ++counter;
       continue;
       }
@@ -642,11 +640,12 @@ void OGRIOHelper
 
 
     OGRFeature::DestroyFeature(feature);
-    chrono.Stop();
     ++counter;
     } //end While feature
+
+  chrono.Stop();
   otbMsgDevMacro(
-    << layer->GetFeatureCount() << " features read, average insertion time " << chrono.GetMean() << " s");
+    << layer->GetFeatureCount() << " features read, total processing time " << chrono.GetElapsedMilliseconds() << " ms");
 }
 
 
diff --git a/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx b/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
index f794757..b0866ee 100644
--- a/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
+++ b/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
@@ -27,7 +27,7 @@
 #include "otbMacro.h"
 #include "otbDataNode.h"
 #include "otbMetaDataKey.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include "otbOGRIOHelper.h"
 
 namespace otb
@@ -204,8 +204,7 @@ bool OGRVectorDataIO::CanWriteFile(const char* filename) const
 
 void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** /** unused */)
 {
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
 
   VectorDataConstPointerType data = dynamic_cast<const VectorDataType*>(datag);
 
@@ -298,7 +297,7 @@ void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** /** unused */)
     }
 
   chrono.Stop();
-  otbMsgDevMacro( << "OGRVectorDataIO: file saved in " << chrono.GetMean() << " seconds. (" << layerKept <<
+  otbMsgDevMacro( << "OGRVectorDataIO: file saved in " << chrono.GetElapsedMilliseconds() << " ms. (" << layerKept <<
   " elements)" );
 
   otbMsgDevMacro(<< " OGRVectorDataIO::Write()  ");
diff --git a/Modules/IO/IOKML/src/otbKMLVectorDataIO.cxx b/Modules/IO/IOKML/src/otbKMLVectorDataIO.cxx
index d6a1809..7b65796 100644
--- a/Modules/IO/IOKML/src/otbKMLVectorDataIO.cxx
+++ b/Modules/IO/IOKML/src/otbKMLVectorDataIO.cxx
@@ -38,7 +38,7 @@
 #include "otbDataNode.h"
 #include "itkPreOrderTreeIterator.h"
 #include "otbMetaDataKey.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 
 namespace otb
@@ -525,8 +525,7 @@ bool KMLVectorDataIO::CanWriteFile(const char* filename) const
 
 void KMLVectorDataIO::Write(const itk::DataObject* datag, char ** itkNotUsed(papszOptions))
 {
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   // Retrieve data required for georeferencing
 
   VectorDataConstPointerType data_in = dynamic_cast<const VectorDataType*>(datag);
@@ -600,7 +599,7 @@ void KMLVectorDataIO::Write(const itk::DataObject* datag, char ** itkNotUsed(pap
   //std::cout << xml;
 
   chrono.Stop();
-  otbMsgDevMacro(<< "KMLVectorDataIO: file saved in " << chrono.GetMean() << " seconds. (" << m_Kept << " elements)" );
+  otbMsgDevMacro(<< "KMLVectorDataIO: file saved in " << chrono.GetElapsedMilliseconds() << " ms. (" << m_Kept << " elements)" );
   otbMsgDevMacro(<< " KMLVectorDataIO::Write()  ");
 
 }
diff --git a/Modules/IO/IORAD/src/otbRADImageIO.cxx b/Modules/IO/IORAD/src/otbRADImageIO.cxx
index 9a870c9..0f7c44a 100644
--- a/Modules/IO/IORAD/src/otbRADImageIO.cxx
+++ b/Modules/IO/IORAD/src/otbRADImageIO.cxx
@@ -325,31 +325,31 @@ bool RADImageIO::InternalReadHeaderInformation(const std::string& file_name, std
   file >> lStrCodePix;
 
   lStrCodePix = itksys::SystemTools::UpperCase(lStrCodePix);
-  if (lStrCodePix == "OCT")
+  if (lStrCodePix == "OCT" || lStrCodePix == "BYT")
     {
     m_PixelType = SCALAR;
     SetComponentType(UCHAR);
     m_BytePerPixel = 1;
     }
-  if (lStrCodePix == "PHA")
+  else if (lStrCodePix == "PHA")
     {
     m_PixelType = SCALAR;
     SetComponentType(CHAR);
     m_BytePerPixel = 1;
     }
-  if (lStrCodePix == "I2")
+  else if (lStrCodePix == "I2")
     {
     m_PixelType = SCALAR;
     SetComponentType(SHORT);
     m_BytePerPixel = 2;
     }
-  if (lStrCodePix == "I4")
+  else if (lStrCodePix == "I4")
     {
     m_PixelType = SCALAR;
     SetComponentType(INT);
     m_BytePerPixel = 4;
     }
-  if (lStrCodePix == "R4")
+  else if (lStrCodePix == "R4")
     {
     m_PixelType = SCALAR;
     SetComponentType(FLOAT);
diff --git a/Modules/IO/IOTileMap/src/otbTileMapImageIO.cxx b/Modules/IO/IOTileMap/src/otbTileMapImageIO.cxx
index 8ee180f..3c781f7 100644
--- a/Modules/IO/IOTileMap/src/otbTileMapImageIO.cxx
+++ b/Modules/IO/IOTileMap/src/otbTileMapImageIO.cxx
@@ -33,7 +33,6 @@
 
 #include "otbGDALImageIO.h"
 
-#include "itkTimeProbe.h"
 #include "otbCurlHelper.h"
 
 #include "otbImageKeywordlist.h"
@@ -514,7 +513,7 @@ void TileMapImageIO::ReadImageInformation()
   this->SetNumberOfDimensions(2);
   this->SetFileTypeToBinary();
   this->SetComponentType(UCHAR);
-  
+
   ImageKeywordlist otb_kwl;
   itk::MetaDataDictionary& dict = this->GetMetaDataDictionary();
   itk::ExposeMetaData<ImageKeywordlist>(dict,
diff --git a/Modules/IO/ImageIO/include/otbImageFileReader.txx b/Modules/IO/ImageIO/include/otbImageFileReader.txx
index 966fe43..98a37bf 100644
--- a/Modules/IO/ImageIO/include/otbImageFileReader.txx
+++ b/Modules/IO/ImageIO/include/otbImageFileReader.txx
@@ -324,13 +324,18 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
   double                               origin[TOutputImage::ImageDimension];
   typename TOutputImage::DirectionType direction;
   std::vector<double>                  axis;
+  int spacing_sign (0);
 
   for (unsigned int i = 0; i < TOutputImage::ImageDimension; ++i)
     {
     if (i < this->m_ImageIO->GetNumberOfDimensions())
       {
       dimSize[i] = this->m_ImageIO->GetDimensions(i);
-      spacing[i] = this->m_ImageIO->GetSpacing(i);
+      if ( this->m_ImageIO->GetSpacing(i) < 0 )
+        spacing_sign = -1;
+      else
+        spacing_sign = 1;
+      spacing[i] = spacing_sign * this->m_ImageIO->GetSpacing(i);
       origin[i]  = this->m_ImageIO->GetOrigin(i);
 // Please note: direction cosines are stored as columns of the
 // direction matrix
@@ -339,7 +344,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
         {
         if (j < this->m_ImageIO->GetNumberOfDimensions())
           {
-          direction[j][i] = axis[j];
+          direction[j][i] = spacing_sign * axis[j];
           }
         else
           {
@@ -385,10 +390,10 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
       }
     }
 
-  output->SetSpacing(spacing);       // Set the image spacing
   output->SetOrigin(origin);         // Set the image origin
   output->SetDirection(direction);   // Set the image direction cosines
-
+  output->SetSpacing(spacing); // Set the image spacing
+  
   if(!m_KeywordListUpToDate && !m_FilenameHelper->GetSkipGeom())
     {
 
diff --git a/Modules/IO/ImageIO/include/otbImageFileWriter.txx b/Modules/IO/ImageIO/include/otbImageFileWriter.txx
index 37bb644..b147229 100644
--- a/Modules/IO/ImageIO/include/otbImageFileWriter.txx
+++ b/Modules/IO/ImageIO/include/otbImageFileWriter.txx
@@ -557,12 +557,16 @@ ImageFileWriter<TInputImage>
   const typename TInputImage::SpacingType&   spacing = inputPtr->GetSpacing();
   const typename TInputImage::PointType&     origin = inputPtr->GetOrigin();
   const typename TInputImage::DirectionType& direction = inputPtr->GetDirection();
-
+  int direction_sign(0);
   for (unsigned int i = 0; i < TInputImage::ImageDimension; ++i)
     {
+    if ( direction[i][i] < 0 )
+      direction_sign = -1;
+    else
+      direction_sign = 1;
     // Final image size
     m_ImageIO->SetDimensions(i, inputRegion.GetSize(i));
-    m_ImageIO->SetSpacing(i, spacing[i]);
+    m_ImageIO->SetSpacing(i, direction_sign * spacing[i]);
     m_ImageIO->SetOrigin(i, origin[i] + static_cast<double>(inputRegion.GetIndex()[i]) * spacing[i]);
 
     vnl_vector<double> axisDirection(TInputImage::ImageDimension);
@@ -570,7 +574,7 @@ ImageFileWriter<TInputImage>
     // direction matrix
     for (unsigned int j = 0; j < TInputImage::ImageDimension; ++j)
       {
-      axisDirection[j] = direction[j][i];
+      axisDirection[j] = direction_sign * direction[j][i];
       }
     m_ImageIO->SetDirection(i, axisDirection);
     }
diff --git a/Modules/IO/ImageIO/test/negativespacing.cxx b/Modules/IO/ImageIO/test/negativespacing.cxx
new file mode 100644
index 0000000..0bd4b75
--- /dev/null
+++ b/Modules/IO/ImageIO/test/negativespacing.cxx
@@ -0,0 +1,61 @@
+/*
+ * 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 "otbImageIOFactory.h"
+#include "itkMacro.h"
+#include <iostream>
+
+#include "otbImageFileWriter.h"
+#include "otbImageFileReader.h"
+#include "otbImage.h"
+#include "otbVectorImage.h"
+
+
+int negativespacing(int itkNotUsed(argc), char * itkNotUsed(argv) [])
+{
+  typedef float InputPixelType;
+  const unsigned int Dimension = 2;
+
+  typedef otb::Image< InputPixelType ,  Dimension > OTBInputImageType;
+
+  typedef otb::ImageFileReader< OTBInputImageType > OTBReaderType;
+  typedef otb::ImageFileWriter< OTBInputImageType > OTBWriterType;
+
+  OTBReaderType::Pointer otbReader ( OTBReaderType::New() );
+  OTBWriterType::Pointer otbWriter ( OTBWriterType::New() );
+  otbReader->SetFileName( "/home/antoine/dev/my_data/spacing/input_negat_spacing.tif" );
+  otbWriter->SetFileName( "/home/antoine/dev/my_data/spacing/input_negat_spacing_result.tif" );
+  otbReader->UpdateOutputInformation();
+
+  otbReader->Update();
+  OTBInputImageType::Pointer otbinput = otbReader->GetOutput();
+
+  std::cout<<otbinput->GetSpacing()<<std::endl;
+  auto spacing = otbinput->GetSpacing();
+  // spacing[0] = -spacing[0];
+  otbinput->SetSignedSpacing(spacing);
+  std::cout<<otbinput->GetSpacing()<<std::endl;
+  std::cout<<otbinput->GetSignedSpacing()<<std::endl;
+  otbWriter->SetInput( otbReader->GetOutput() );
+  otbWriter->Update();
+  std::cout<<"OTBWriter"<<std::endl;
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/IO/ImageIO/test/otbImageFileReaderMSTAR.cxx b/Modules/IO/ImageIO/test/otbImageFileReaderMSTAR.cxx
index ad55108..b44e4c4 100644
--- a/Modules/IO/ImageIO/test/otbImageFileReaderMSTAR.cxx
+++ b/Modules/IO/ImageIO/test/otbImageFileReaderMSTAR.cxx
@@ -74,7 +74,7 @@ int otbImageFileReaderMSTAR(int itkNotUsed(argc), char* argv[])
 
   InternalImageType::Pointer magnitude = InternalImageType::New();
   magnitude->SetRegions(inputRegion);
-  const InternalImageType::SpacingType& spacing = reader->GetOutput()->GetSpacing();
+  const InternalImageType::SpacingType& spacing = reader->GetOutput()->GetSignedSpacing();
   const InternalImageType::PointType&   inputOrigin = reader->GetOutput()->GetOrigin();
   double                                outputOrigin[InputDimension];
 
@@ -83,7 +83,7 @@ int otbImageFileReaderMSTAR(int itkNotUsed(argc), char* argv[])
     outputOrigin[i] = inputOrigin[i] + spacing[i] * inputStart[i];
     }
 
-  magnitude->SetSpacing(spacing);
+  magnitude->SetSignedSpacing(spacing);
   magnitude->SetOrigin(outputOrigin);
   magnitude->Allocate();
 
diff --git a/Modules/IO/ImageIO/test/otbImageFileWriterTestWithoutInput.cxx b/Modules/IO/ImageIO/test/otbImageFileWriterTestWithoutInput.cxx
index 8d67754..cca2bf2 100644
--- a/Modules/IO/ImageIO/test/otbImageFileWriterTestWithoutInput.cxx
+++ b/Modules/IO/ImageIO/test/otbImageFileWriterTestWithoutInput.cxx
@@ -68,7 +68,7 @@ int otbImageScalarFileWriterTestWithoutInputGeneric(int itkNotUsed(argc), char*
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->Allocate();
@@ -146,7 +146,7 @@ int otbImageComplexFileWriterTestWithoutInputGeneric(int itkNotUsed(argc), char*
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->Allocate();
diff --git a/Modules/IO/ImageIO/test/otbImageStreamingFileWriterTestWithoutInput.cxx b/Modules/IO/ImageIO/test/otbImageStreamingFileWriterTestWithoutInput.cxx
index 822c710..8581414 100644
--- a/Modules/IO/ImageIO/test/otbImageStreamingFileWriterTestWithoutInput.cxx
+++ b/Modules/IO/ImageIO/test/otbImageStreamingFileWriterTestWithoutInput.cxx
@@ -69,7 +69,7 @@ int otbImageScalarStreamingFileWriterTestWithoutInputGeneric(int itkNotUsed(argc
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->Allocate();
@@ -148,7 +148,7 @@ int otbImageComplexStreamingFileWriterTestWithoutInputGeneric(int itkNotUsed(arg
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->Allocate();
diff --git a/Modules/IO/ImageIO/test/otbVectorImageFileWriterTestWithoutInput.cxx b/Modules/IO/ImageIO/test/otbVectorImageFileWriterTestWithoutInput.cxx
index 6c822d2..7c9fa1b 100644
--- a/Modules/IO/ImageIO/test/otbVectorImageFileWriterTestWithoutInput.cxx
+++ b/Modules/IO/ImageIO/test/otbVectorImageFileWriterTestWithoutInput.cxx
@@ -77,7 +77,7 @@ int otbVectorImageFileWriterScalarTestWithoutInputGeneric(int argc, char* argv[]
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->SetNumberOfComponentsPerPixel(atoi(argv[3]));
@@ -180,7 +180,7 @@ int otbVectorImageFileWriterComplexTestWithoutInputGeneric(int argc, char* argv[
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->SetNumberOfComponentsPerPixel(atoi(argv[3]));
diff --git a/Modules/IO/ImageIO/test/otbVectorImageStreamingFileWriterTestWithoutInput.cxx b/Modules/IO/ImageIO/test/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
index b4623bc..e95ba58 100644
--- a/Modules/IO/ImageIO/test/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
+++ b/Modules/IO/ImageIO/test/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
@@ -77,7 +77,7 @@ int otbVectorImageStreamingFileWriterScalarTestWithoutInputGeneric(int argc, cha
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->SetNumberOfComponentsPerPixel(atoi(argv[3]));
@@ -180,7 +180,7 @@ int otbVectorImageStreamingFileWriterComplexTestWithoutInputGeneric(int argc, ch
   SpacingType spacing;
   spacing.Fill(1.0);
   image->SetOrigin(origin);
-  image->SetSpacing(spacing);
+  image->SetSignedSpacing(spacing);
 
   image->SetRegions(region);
   image->SetNumberOfComponentsPerPixel(atoi(argv[3]));
diff --git a/Modules/IO/TestKernel/src/otbTestHelper.cxx b/Modules/IO/TestKernel/src/otbTestHelper.cxx
index 9c1559a..a7c84de 100644
--- a/Modules/IO/TestKernel/src/otbTestHelper.cxx
+++ b/Modules/IO/TestKernel/src/otbTestHelper.cxx
@@ -1529,11 +1529,11 @@ int TestHelper::RegressionTestMetaData(const char *testImageFilename, const char
     }
 
   // test spacing
-  if (blImPtr->GetSpacing() != testImPtr->GetSpacing())
+  if (blImPtr->GetSignedSpacing() != testImPtr->GetSignedSpacing())
     {
     std::cerr << "The spacing of the baseline image and Test image do not match!" << std::endl;
-    std::cerr << "baseline image: " << baselineImageFilename << " has spacing " << blImPtr->GetSpacing() << std::endl;
-    std::cerr << "Test image:     " << testImageFilename << " has spacing " << testImPtr->GetSpacing() << std::endl;
+    std::cerr << "baseline image: " << baselineImageFilename << " has spacing " << blImPtr->GetSignedSpacing() << std::endl;
+    std::cerr << "Test image:     " << testImageFilename << " has spacing " << testImPtr->GetSignedSpacing() << std::endl;
     errcount++;
     }
 
diff --git a/Modules/IO/VectorDataIO/test/otbVectorDataFileGeoReaderWriter.cxx b/Modules/IO/VectorDataIO/test/otbVectorDataFileGeoReaderWriter.cxx
index 5f3cc1c..77b1f26 100644
--- a/Modules/IO/VectorDataIO/test/otbVectorDataFileGeoReaderWriter.cxx
+++ b/Modules/IO/VectorDataIO/test/otbVectorDataFileGeoReaderWriter.cxx
@@ -42,7 +42,7 @@ int otbVectorDataFileGeoReaderWriter(int itkNotUsed(argc), char * argv[])
   vectorDataReader->SetFileName(argv[1]);
 
 //      vectorData->SetOrigin(m_Reader->GetOutput()->GetOrigin());
-//       vectorData->SetSpacing(m_Reader->GetOutput()->GetSpacing());
+//       vectorData->SetSignedSpacing(m_Reader->GetOutput()->GetSignedSpacing());
 
   std::string projectionRef;
   itk::ExposeMetaData<std::string>(
diff --git a/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx b/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx
index 678974e..00da041 100644
--- a/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx
+++ b/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx
@@ -109,7 +109,7 @@ MachineLearningModel<TInputValue,TOutputValue,TConfidenceValue>
     nb_threads = omp_get_num_threads();
     threadId = omp_get_thread_num();
     nb_batches = std::min(nb_threads,(unsigned int)input->Size());
-    // Ensure that we do not spawn unncessary threads
+    // Ensure that we do not spawn unnecessary threads
     if(threadId<nb_batches)
       {
       unsigned int batch_size = ((unsigned int)input->Size()/nb_batches);
diff --git a/Modules/Learning/SOM/test/otbSOMClassifier.cxx b/Modules/Learning/SOM/test/otbSOMClassifier.cxx
index 4e0e7ef..9e72e42 100644
--- a/Modules/Learning/SOM/test/otbSOMClassifier.cxx
+++ b/Modules/Learning/SOM/test/otbSOMClassifier.cxx
@@ -90,7 +90,7 @@ int otbSOMClassifier(int argc, char* argv[])
   OutputImageType::Pointer outputImage = OutputImageType::New();
   outputImage->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());
   outputImage->SetOrigin(reader->GetOutput()->GetOrigin());
-  outputImage->SetSpacing(reader->GetOutput()->GetSpacing());
+  outputImage->SetSignedSpacing(reader->GetOutput()->GetSignedSpacing());
   outputImage->Allocate();
 
   ClassifierType::OutputType*               membershipSample = classifier->GetOutput();
diff --git a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx
index 5fd03e3..e2d8a40 100644
--- a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx
+++ b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx
@@ -22,7 +22,6 @@
 #define otbOGRDataToSamplePositionFilter_txx
 
 #include "otbOGRDataToSamplePositionFilter.h"
-#include "itkTimeProbe.h"
 
 namespace otb
 {
@@ -272,7 +271,7 @@ PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler>
   typedef std::vector<unsigned long> LoadVectorType;
   LoadVectorType currentLoad;
   currentLoad.resize(numberOfThreads, 0UL);
-  
+
   ClassCountMapType::iterator largestClass;
   unsigned long minLoad;
   unsigned int destThread;
diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
index 7fa8822..f10ace9 100644
--- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
+++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
@@ -26,7 +26,7 @@
 #include "itkImageRegionConstIteratorWithOnlyIndex.h"
 #include "itkImageRegionConstIterator.h"
 #include "otbMacro.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include "itkProgressReporter.h"
 
 namespace otb
@@ -36,7 +36,7 @@ template<class TInputImage, class TMaskImage>
 PersistentSamplingFilterBase<TInputImage,TMaskImage>
 ::PersistentSamplingFilterBase()
   : m_FieldName(std::string("class"))
-  , m_FieldIndex(0)  
+  , m_FieldIndex(0)
   , m_LayerIndex(0)
   , m_OutLayerName(std::string("output"))
   , m_OGRLayerCreationOptions()
@@ -135,7 +135,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
       {
       itkGenericExceptionMacro("Mask and input image have a different origin!");
       }
-    if (mask->GetSpacing() != input->GetSpacing())
+    if (mask->GetSignedSpacing() != input->GetSignedSpacing())
       {
       itkGenericExceptionMacro("Mask and input image have a different spacing!");
       }
@@ -276,11 +276,10 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
   this->m_InMemoryInputs.clear();
 
   unsigned int numberOfThreads = this->GetNumberOfThreads();
-  
+
   // gather temporary outputs and write to output
   const otb::ogr::DataSource* vectors = this->GetOGRData();
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   unsigned int count = 0;
   for (unsigned int k=0 ; k < this->GetNumberOfOutputs() ; k++)
     {
@@ -297,7 +296,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
         {
         itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
         }
-  
+
       for (unsigned int thread=0 ; thread < numberOfThreads ; thread++)
         {
         ogr::Layer inLayer = this->m_InMemoryOutputs[thread][count]->GetLayerChecked(0);
@@ -305,7 +304,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
           {
           continue;
           }
-  
+
         ogr::Layer::const_iterator tmpIt = inLayer.begin();
         // This test only uses 1 input, not compatible with multiple OGRData inputs
         if (vectors == realOutput)
@@ -327,7 +326,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
             }
           }
         }
-  
+
       err = outLayer.ogr().CommitTransaction();
       if (err != OGRERR_NONE)
         {
@@ -336,8 +335,9 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
       count++;
       }
     }
+
   chrono.Stop();
-  otbMsgDebugMacro(<< "write ogr points took " << chrono.GetTotal() << " sec");
+  otbMsgDebugMacro(<< "Writing OGR points took " << chrono.GetElapsedMilliseconds() << " ms");
   this->m_InMemoryOutputs.clear();
 }
 
@@ -380,7 +380,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
 {
   typename TInputImage::PointType imgPoint;
   typename TInputImage::IndexType imgIndex;
-  
+
   switch (geom->getGeometryType())
     {
     case wkbPoint:
@@ -388,11 +388,11 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
       {
       OGRPoint* castPoint = dynamic_cast<OGRPoint*>(geom);
       if (castPoint == ITK_NULLPTR) break;
-      
+
       imgPoint[0] = castPoint->getX();
       imgPoint[1] = castPoint->getY();
       const TInputImage* img = this->GetInput();
-      const TMaskImage* mask = this->GetMask(); 
+      const TMaskImage* mask = this->GetMask();
       img->TransformPhysicalPointToIndex(imgPoint,imgIndex);
       if ((mask == ITK_NULLPTR) || mask->GetPixel(imgIndex))
         {
@@ -472,7 +472,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
   TMaskImage* mask = const_cast<TMaskImage*>(this->GetMask());
   typename TInputImage::IndexType imgIndex;
   typename TInputImage::PointType imgPoint;
-  typename TInputImage::SpacingType imgAbsSpacing = img->GetSpacing();
+  typename TInputImage::SpacingType imgAbsSpacing = img->GetSignedSpacing();
   if (imgAbsSpacing[0] < 0) imgAbsSpacing[0] = -imgAbsSpacing[0];
   if (imgAbsSpacing[1] < 0) imgAbsSpacing[1] = -imgAbsSpacing[1];
 
@@ -569,7 +569,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
         }
       ++it;
       }
-    }  
+    }
 }
 
 template <class TInputImage, class TMaskImage>
@@ -740,7 +740,11 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
     dstFeature.SetFID(featIt->GetFID());
     tmpLayers[counter].CreateFeature( dstFeature );
     cptFeat++;
-    if (cptFeat > nbFeatThread) counter++; cptFeat=0;
+    if (cptFeat > nbFeatThread && (counter + 1) < numberOfThreads)
+      {
+      counter++;
+      cptFeat=0;
+      }
     }
 
   inLayer.SetSpatialFilter(ITK_NULLPTR);
@@ -753,14 +757,14 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
 {
   TInputImage *inputImage = const_cast<TInputImage*>(this->GetInput());
   inputImage->UpdateOutputInformation();
-  
+
   ogr::Layer inLayer = inputDS->GetLayer(this->GetLayerIndex());
 
   bool updateMode = false;
   if (inputDS == outputDS)
     {
     updateMode = true;
-    // Check m_OutLayerName is same as input layer name 
+    // Check m_OutLayerName is same as input layer name
     m_OutLayerName = inLayer.GetName();
     }
 
diff --git a/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx b/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx
index 8de51ca..138032e 100644
--- a/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx
+++ b/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx
@@ -22,8 +22,8 @@
 #include "otbImageSampleExtractorFilter.h"
 #include "otbVectorImage.h"
 #include "otbImage.h"
+#include "otbStopwatch.h"
 #include "itkPhysicalPointImageSource.h"
-#include "itkTimeProbe.h"
 #include <fstream>
 
 int otbImageSampleExtractorFilterNew(int itkNotUsed(argc), char* itkNotUsed(argv) [])
@@ -44,6 +44,7 @@ int otbImageSampleExtractorFilter(int argc, char* argv[])
   if (argc < 3)
     {
     std::cout << "Usage : "<<argv[0]<< "  input_vector  output" << std::endl;
+    return EXIT_FAILURE;
     }
 
   std::string vectorPath(argv[1]);
@@ -81,13 +82,11 @@ int otbImageSampleExtractorFilter(int argc, char* argv[])
   filter->SetClassFieldName(classFieldName);
   filter->SetOutputFieldPrefix(outputPrefix);
 
-  itk::TimeProbe chrono;
-  chrono.Start();
-
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   filter->Update();
-
   chrono.Stop();
-  std::cout << "Extraction took "<< chrono.GetTotal() << " sec" << std::endl;
+
+  std::cout << "Extraction took "<< chrono.GetElapsedMilliseconds() << " ms" << std::endl;
 
   return EXIT_SUCCESS;
 }
@@ -100,6 +99,7 @@ int otbImageSampleExtractorFilterUpdate(int argc, char* argv[])
   if (argc < 3)
     {
     std::cout << "Usage : "<<argv[0]<< "  input_vector  output" << std::endl;
+    return EXIT_FAILURE;
     }
 
   std::string vectorPath(argv[1]);
@@ -134,57 +134,55 @@ int otbImageSampleExtractorFilterUpdate(int argc, char* argv[])
   dstLayer.CreateField(labelField, true);
   const  OGRErr err = dstLayer.ogr().StartTransaction();
 
-  if (err == OGRERR_NONE) {
-
-  otb::ogr::Layer::const_iterator featIt = inLayer.begin();
-  for(; featIt!=inLayer.end(); ++featIt)
+  if (err == OGRERR_NONE)
     {
-    otb::ogr::Feature dstFeature(dstLayer.GetLayerDefn());
-    dstFeature.SetFrom( *featIt, TRUE );
-    dstLayer.CreateFeature( dstFeature );
+    otb::ogr::Layer::const_iterator featIt = inLayer.begin();
+    for(; featIt!=inLayer.end(); ++featIt)
+      {
+      otb::ogr::Feature dstFeature(dstLayer.GetLayerDefn());
+      dstFeature.SetFrom( *featIt, TRUE );
+      dstLayer.CreateFeature( dstFeature );
+      }
+
+    const OGRErr err2 = dstLayer.ogr().CommitTransaction();
+    if (err2 == OGRERR_NONE)
+      {
+      output->Clear();
+
+      otb::ogr::DataSource::Pointer outputUpdate =
+        otb::ogr::DataSource::New(outputPath,otb::ogr::DataSource::Modes::Update_LayerUpdate);
+
+      typedef itk::PhysicalPointImageSource<InputImageType> ImageSourceType;
+      ImageSourceType::Pointer imgSource = ImageSourceType::New();
+      imgSource->SetSize(region.GetSize());
+      imgSource->SetSpacing(spacing);
+      imgSource->SetOrigin(origin);
+
+      FilterType::Pointer filter = FilterType::New();
+      filter->SetInput(imgSource->GetOutput());
+      filter->SetLayerIndex(0);
+      filter->SetSamplePositions(outputUpdate);
+      filter->SetOutputSamples(outputUpdate);
+      filter->SetClassFieldName(classFieldName);
+      filter->SetOutputFieldPrefix(outputPrefix);
+
+      otb::Stopwatch chrono = otb::Stopwatch::StartNew();
+      filter->Update();
+      chrono.Stop();
+
+      std::cout << "Extraction took "<< chrono.GetElapsedMilliseconds() << " ms" << std::endl;
+      }
+    else
+      {
+      std::cout<< "Unable to commit transaction for OGR layer " << dstLayer.ogr().GetName() << "." << std::endl;
+      return EXIT_FAILURE;
+      }
     }
-
-  const OGRErr err2 = dstLayer.ogr().CommitTransaction();
-  if (err2 == OGRERR_NONE)
+  else
     {
-
-  output->Clear();
-
-  otb::ogr::DataSource::Pointer outputUpdate =
-    otb::ogr::DataSource::New(outputPath,otb::ogr::DataSource::Modes::Update_LayerUpdate);
-
-  typedef itk::PhysicalPointImageSource<InputImageType> ImageSourceType;
-  ImageSourceType::Pointer imgSource = ImageSourceType::New();
-  imgSource->SetSize(region.GetSize());
-  imgSource->SetSpacing(spacing);
-  imgSource->SetOrigin(origin);
-
-  FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(imgSource->GetOutput());
-  filter->SetLayerIndex(0);
-  filter->SetSamplePositions(outputUpdate);
-  filter->SetOutputSamples(outputUpdate);
-  filter->SetClassFieldName(classFieldName);
-  filter->SetOutputFieldPrefix(outputPrefix);
-
-  itk::TimeProbe chrono;
-  chrono.Start();
-
-  filter->Update();
-
-  chrono.Stop();
-  std::cout << "Extraction took "<< chrono.GetTotal() << " sec" << std::endl;
-    }
-  else {
-    std::cout<< "Unable to commit transaction for OGR layer " << dstLayer.ogr().GetName() << "." << std::endl;
-    return EXIT_FAILURE;
-  }
-
-  }
-  else {
     std::cout << "Unable to start transaction for OGR layer " << dstLayer.ogr().GetName() << "." << std::endl;
     return EXIT_FAILURE;
-  }
+    }
 
   return EXIT_SUCCESS;
 }
diff --git a/Modules/Learning/Sampling/test/otbOGRDataToClassStatisticsFilterTest.cxx b/Modules/Learning/Sampling/test/otbOGRDataToClassStatisticsFilterTest.cxx
index 1785857..47da4c0 100644
--- a/Modules/Learning/Sampling/test/otbOGRDataToClassStatisticsFilterTest.cxx
+++ b/Modules/Learning/Sampling/test/otbOGRDataToClassStatisticsFilterTest.cxx
@@ -69,7 +69,7 @@ int otbOGRDataToClassStatisticsFilter(int argc, char* argv[])
   inputImage->SetNumberOfComponentsPerPixel(3);
   inputImage->SetLargestPossibleRegion(region);
   inputImage->SetOrigin(origin);
-  inputImage->SetSpacing(spacing);
+  inputImage->SetSignedSpacing(spacing);
   // Don't allocate the input image, the filter should not need it
   //inputImage->Allocate();
   //inputImage->FillBuffer(pixel);
@@ -77,7 +77,7 @@ int otbOGRDataToClassStatisticsFilter(int argc, char* argv[])
   MaskImageType::Pointer mask = MaskImageType::New();
   mask->SetRegions(region);
   mask->SetOrigin(origin);
-  mask->SetSpacing(spacing);
+  mask->SetSignedSpacing(spacing);
   mask->Allocate();
   itk::ImageRegionIterator<MaskImageType> it(mask,region);
   unsigned int count = 0;
diff --git a/Modules/Learning/Sampling/test/otbOGRDataToSamplePositionFilterTest.cxx b/Modules/Learning/Sampling/test/otbOGRDataToSamplePositionFilterTest.cxx
index 68403ff..9199433 100644
--- a/Modules/Learning/Sampling/test/otbOGRDataToSamplePositionFilterTest.cxx
+++ b/Modules/Learning/Sampling/test/otbOGRDataToSamplePositionFilterTest.cxx
@@ -179,7 +179,7 @@ int otbOGRDataToSamplePositionFilter(int argc, char* argv[])
   inputImage->SetNumberOfComponentsPerPixel(3);
   inputImage->SetLargestPossibleRegion(region);
   inputImage->SetOrigin(origin);
-  inputImage->SetSpacing(spacing);
+  inputImage->SetSignedSpacing(spacing);
   // Don't allocate the input image, the filter should not need it
   //inputImage->Allocate();
   //inputImage->FillBuffer(pixel);
@@ -187,7 +187,7 @@ int otbOGRDataToSamplePositionFilter(int argc, char* argv[])
   MaskImageType::Pointer mask = MaskImageType::New();
   mask->SetRegions(region);
   mask->SetOrigin(origin);
-  mask->SetSpacing(spacing);
+  mask->SetSignedSpacing(spacing);
   mask->Allocate();
   itk::ImageRegionIterator<MaskImageType> it(mask,region);
   unsigned int count = 0;
@@ -263,7 +263,7 @@ int otbOGRDataToSamplePositionFilterPattern(int argc, char* argv[])
   inputImage->SetNumberOfComponentsPerPixel(3);
   inputImage->SetLargestPossibleRegion(region);
   inputImage->SetOrigin(origin);
-  inputImage->SetSpacing(spacing);
+  inputImage->SetSignedSpacing(spacing);
   // Don't allocate the input image, the filter should not need it
   //inputImage->Allocate();
   //inputImage->FillBuffer(pixel);
@@ -271,7 +271,7 @@ int otbOGRDataToSamplePositionFilterPattern(int argc, char* argv[])
   MaskImageType::Pointer mask = MaskImageType::New();
   mask->SetRegions(region);
   mask->SetOrigin(origin);
-  mask->SetSpacing(spacing);
+  mask->SetSignedSpacing(spacing);
   mask->Allocate();
   itk::ImageRegionIterator<MaskImageType> it(mask,region);
   unsigned int count = 0;
diff --git a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h
index f4935c0..c404d25 100644
--- a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h
+++ b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h
@@ -28,10 +28,6 @@
 #include "otbExtendedFilenameToWriterOptions.h"
 #include "otbMPIConfig.h"
 
-// Time probe
-#include "itkTimeProbe.h"
-
-
 #include "itkImageFileWriter.h"
 
 #include "itkObjectFactoryBase.h"
diff --git a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
index 5895959..96cbf71 100644
--- a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
+++ b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
@@ -22,7 +22,7 @@
 #define otbSimpleParallelTiffWriter_txx
 
 #include "otbSimpleParallelTiffWriter.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 
 using std::vector;
 
@@ -546,29 +546,47 @@ SimpleParallelTiffWriter<TInputImage>
     {
     // Set geotransform
     double geotransform[6];
-    geotransform[0] = inputPtr->GetOrigin()[0] - 0.5*inputPtr->GetSpacing()[0];
-    geotransform[1] = inputPtr->GetSpacing()[0];
+    geotransform[0] = inputPtr->GetOrigin()[0] - 0.5*inputPtr->GetSignedSpacing()[0];
+    geotransform[1] = inputPtr->GetSignedSpacing()[0];
     geotransform[2] = 0.0;
-    geotransform[3] = inputPtr->GetOrigin()[1] - 0.5*inputPtr->GetSpacing()[1];
+    geotransform[3] = inputPtr->GetOrigin()[1] - 0.5*inputPtr->GetSignedSpacing()[1];
     geotransform[4] = 0.0;
-    geotransform[5] = inputPtr->GetSpacing()[1];
+    geotransform[5] = inputPtr->GetSignedSpacing()[1];
 
     // Call SPTW routine that creates the output raster
-    SPTW_ERROR sperr = create_generic_raster(m_FileName,
-        inputPtr->GetLargestPossibleRegion().GetSize()[0],
-        inputPtr->GetLargestPossibleRegion().GetSize()[1],
-        nBands,
-        dataType,
-        geotransform,
-        inputPtr->GetProjectionRef(),
-        block_size_x,
-        m_TiffTiledMode);
-
-    if (sperr != sptw::SP_None)
+    if(!m_TiffTiledMode)
       {
-      itkExceptionMacro(<<"Error creating raster");
-      otb::MPIConfig::Instance()->abort(EXIT_FAILURE);
+      SPTW_ERROR sperr = sptw::create_raster(m_FileName,
+                                             inputPtr->GetLargestPossibleRegion().GetSize()[0],
+                                             inputPtr->GetLargestPossibleRegion().GetSize()[1],
+                                             nBands,
+                                             dataType,
+                                             geotransform,
+                                             inputPtr->GetProjectionRef());
+      if (sperr != sptw::SP_None)
+        {
+        itkExceptionMacro(<<"Error creating raster");
+        otb::MPIConfig::Instance()->abort(EXIT_FAILURE);
+        }
+
+      }
+    else
+      {
+      SPTW_ERROR sperr = sptw::create_tiled_raster(m_FileName,
+                                                   inputPtr->GetLargestPossibleRegion().GetSize()[0],
+                                                   inputPtr->GetLargestPossibleRegion().GetSize()[1],
+                                                   nBands,
+                                                   dataType,
+                                                   geotransform,
+                                                   inputPtr->GetProjectionRef(),
+                                                   block_size_x);
+      if (sperr != sptw::SP_None)
+        {
+        itkExceptionMacro(<<"Error creating raster");
+        otb::MPIConfig::Instance()->abort(EXIT_FAILURE);
+        }
       }
+    
     }
 
   // Wait for rank 0 to finish creating the output raster
@@ -617,7 +635,7 @@ SimpleParallelTiffWriter<TInputImage>
    ************************************************************************/
 
   // Time probe for overall process time
-  itk::TimeProbe overallTime;
+  otb::Stopwatch overallTime;
   overallTime.Start();
 
   // Check that streaming is relevant
@@ -674,19 +692,16 @@ SimpleParallelTiffWriter<TInputImage>
       /*
        * Processing
        */
-      itk::TimeProbe processingTime;
-      processingTime.Start();
+      otb::Stopwatch processingTime = otb::Stopwatch::StartNew();
       inputPtr->SetRequestedRegion(streamRegion);
       inputPtr->PropagateRequestedRegion();
       inputPtr->UpdateOutputData();
-      processingTime.Stop();
-      processDuration += processingTime.GetTotal();
+      processDuration += processingTime.GetElapsedMilliseconds();
 
       /*
        * Writing using SPTW
        */
-      itk::TimeProbe writingTime;
-      writingTime.Start();
+      otb::Stopwatch writingTime = otb::Stopwatch::StartNew();
       if (!m_VirtualMode)
         {
         sptw::write_area(output_raster,
@@ -696,8 +711,7 @@ SimpleParallelTiffWriter<TInputImage>
             streamRegion.GetIndex()[0] + streamRegion.GetSize()[0] -1,
             streamRegion.GetIndex()[1] + streamRegion.GetSize()[1] -1);
         }
-      writingTime.Stop();
-      writeDuration += writingTime.GetTotal();
+      writeDuration += writingTime.GetElapsedMilliseconds();
       numberOfProcessedRegions += 1;
       }
     }
@@ -731,12 +745,12 @@ SimpleParallelTiffWriter<TInputImage>
       itkDebugMacro( "Process Id\tProcessing\tWriting" );
 	  for (unsigned int i = 0; i < process_runtimes.size(); i+=nValues)
 	    {
-      itkDebugMacro( <<(int (i/nValues)) << 
+      itkDebugMacro( <<(int (i/nValues)) <<
 	        "\t" << process_runtimes[i] <<
 	        "\t" << process_runtimes[i+1] <<
 	        "\t("<< process_runtimes[i+2] << " regions)" );
 	    }
-	  itkDebugMacro( "Overall time:" << overallTime.GetTotal() );
+	  itkDebugMacro( "Overall time: " << overallTime.GetElapsedMilliseconds() / 1000 << " s" );
 	  }
    */
 
diff --git a/Modules/MPI/MPIVrtWriter/include/otbMPIVrtWriter.h b/Modules/MPI/MPIVrtWriter/include/otbMPIVrtWriter.h
index 899c56a..ecec379 100644
--- a/Modules/MPI/MPIVrtWriter/include/otbMPIVrtWriter.h
+++ b/Modules/MPI/MPIVrtWriter/include/otbMPIVrtWriter.h
@@ -210,12 +210,12 @@ template <typename TImage> void WriteMPI(TImage *img, const std::string &output,
 
       // Set GeoTransform
       double gt[6];
-      gt[0] = img->GetOrigin()[0] - 0.5*img->GetSpacing()[0];
-      gt[1] = img->GetSpacing()[0];
+      gt[0] = img->GetOrigin()[0] - 0.5*img->GetSignedSpacing()[0];
+      gt[1] = img->GetSignedSpacing()[0];
       gt[2] = 0.0;
-      gt[3] = img->GetOrigin()[1] - 0.5*img->GetSpacing()[1];
+      gt[3] = img->GetOrigin()[1] - 0.5*img->GetSignedSpacing()[1];
       gt[4] = 0.0;
-      gt[5] = img->GetSpacing()[1];
+      gt[5] = img->GetSignedSpacing()[1];
       VRTOutput->SetGeoTransform(gt);
 
       // Set projection
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.txx b/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.txx
index ef9c163..372bc8a 100644
--- a/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.txx
+++ b/Modules/Radiometry/SARCalibration/include/otbSarDeburstImageFilter.txx
@@ -48,7 +48,7 @@ SarDeburstImageFilter<TImage>::GenerateOutputInformation()
   ImageType * outputPtr = this->GetOutput();
 
   // Check that azimuth spacing has not been modified
-  if(vcl_abs(inputPtr->GetSpacing()[1]-1.)>=std::numeric_limits<double>::epsilon())
+  if(vcl_abs(inputPtr->GetSignedSpacing()[1]-1.)>=std::numeric_limits<double>::epsilon())
     itkExceptionMacro("Can not perform deburst if input image azimuth spacing is not 1.");
   
   // Check that the azimuth sampling grid has not been modified
diff --git a/Modules/Radiometry/SARCalibration/test/otbSarDeburstFilterTest.cxx b/Modules/Radiometry/SARCalibration/test/otbSarDeburstFilterTest.cxx
index 5d0f320..d221088 100644
--- a/Modules/Radiometry/SARCalibration/test/otbSarDeburstFilterTest.cxx
+++ b/Modules/Radiometry/SARCalibration/test/otbSarDeburstFilterTest.cxx
@@ -40,7 +40,23 @@ int otbSarDeburstFilterTest(int itkNotUsed(argc), char * argv[])
   writer->SetInput(filter->GetOutput());
   writer->SetFileName(argv[2]);
   writer->Update();
-  
+
+  // check that there is now a single burst in data
+  reader = ReaderType::New();
+  reader->SetFileName(argv[2]);
+  reader->UpdateOutputInformation();
+
+  unsigned int nb_bursts = atoi(reader->GetOutput()->GetImageKeywordlist().GetMetadataByKey("support_data.geom.bursts.number").c_str());
+
+  if(nb_bursts != 1)
+    {
+    std::cerr<<"Error: more than 1 burst ("<<nb_bursts<<" bursts) found in output metadata."<<std::endl;
+    }
+  else
+    {
+    std::cout<<"Metadata have a single burst as expected."<<std::endl;
+    }
+
   return EXIT_SUCCESS;
 }
 
diff --git a/Modules/Radiometry/Simulation/include/otbImageSimulationMethod.txx b/Modules/Radiometry/Simulation/include/otbImageSimulationMethod.txx
index d42b05f..60a23d1 100644
--- a/Modules/Radiometry/Simulation/include/otbImageSimulationMethod.txx
+++ b/Modules/Radiometry/Simulation/include/otbImageSimulationMethod.txx
@@ -185,7 +185,7 @@ ImageSimulationMethod< TInputVectorData, TSpatialisation, TSimulationStep1, TSim
     FTMFilter->SetInterpolator(interpolator);
     //       FTMFilter->SetOutputSize(multiToMonoChannelFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
     FTMFilter->SetSize(multiToMonoChannelFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
-    FTMFilter->SetOutputSpacing(multiToMonoChannelFilter->GetOutput()->GetSpacing());
+    FTMFilter->SetOutputSpacing(multiToMonoChannelFilter->GetOutput()->GetSignedSpacing());
     FTMFilter->SetOutputOrigin(multiToMonoChannelFilter->GetOutput()->GetOrigin());
     FTMFilter->SetInput(multiToMonoChannelFilter->GetOutput());
     FTMFilter->Update();
@@ -246,7 +246,7 @@ ImageSimulationMethod< TInputVectorData, TSpatialisation, TSimulationStep1, TSim
 //       FTMFilter->SetInterpolator(interpolator);
 // //       FTMFilter->SetOutputSize(multiToMonoChannelFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
 //       FTMFilter->SetSize(multiToMonoChannelFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
-//       FTMFilter->SetOutputSpacing(multiToMonoChannelFilter->GetOutput()->GetSpacing());
+//       FTMFilter->SetOutputSpacing(multiToMonoChannelFilter->GetOutput()->GetSignedSpacing());
 //       FTMFilter->SetOutputOrigin(multiToMonoChannelFilter->GetOutput()->GetOrigin());
 //       FTMFilter->SetInput(multiToMonoChannelFilter->GetOutput());
 //       FTMFilter->Update();
diff --git a/Modules/Registration/DisparityMap/include/otbDisparityMapEstimationMethod.txx b/Modules/Registration/DisparityMap/include/otbDisparityMapEstimationMethod.txx
index cadaf1c..0f18582 100644
--- a/Modules/Registration/DisparityMap/include/otbDisparityMapEstimationMethod.txx
+++ b/Modules/Registration/DisparityMap/include/otbDisparityMapEstimationMethod.txx
@@ -189,9 +189,9 @@ DisparityMapEstimationMethod<TFixedImage, TMovingImage, TPointSet>
     movingExtractor->Update();
 
 //     std::cout<<"Fixed extract origin: "<<fixedExtractor->GetOutput()->GetOrigin()<<std::endl;
-//     std::cout<<"Fixed extract spacing: "<<fixedExtractor->GetOutput()->GetSpacing()<<std::endl;
+//     std::cout<<"Fixed extract spacing: "<<fixedExtractor->GetOutput()->GetSignedSpacing()<<std::endl;
 //     std::cout<<"Moving extract origin: "<<movingExtractor->GetOutput()->GetOrigin()<<std::endl;
-//     std::cout<<"Moving extract spacing: "<<movingExtractor->GetOutput()->GetSpacing()<<std::endl;
+//     std::cout<<"Moving extract spacing: "<<movingExtractor->GetOutput()->GetSignedSpacing()<<std::endl;
 
 //     typedef otb::ImageFileWriter<FixedImageType> FixedWriterType;
 //      typedef otb::ImageFileWriter<MovingImageType> MovingWriterType;
diff --git a/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.txx b/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.txx
index b974232..8a90738 100644
--- a/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.txx
+++ b/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.txx
@@ -177,7 +177,7 @@ DisparityMapTo3DFilter<TDisparityImage,TOutputImage,TEpipolarGridImage,TMaskImag
 
   // copy also origin and spacing
   outputPtr->SetOrigin(horizDisp->GetOrigin());
-  outputPtr->SetSpacing(horizDisp->GetSpacing());
+  outputPtr->SetSignedSpacing(horizDisp->GetSignedSpacing());
 }
 
 template <class TDisparityImage, class TOutputImage,
diff --git a/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.txx b/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.txx
index 3bdf6bc..9696507 100644
--- a/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.txx
+++ b/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.txx
@@ -339,7 +339,7 @@ DisparityMapToDEMFilter<TDisparityImage,TInputImage,TOutputDEMImage,TEpipolarGri
   typename TOutputDEMImage::SpacingType outSpacing;
   outSpacing[0] = 57.295779513 * m_DEMGridStep / (6378137.0 * vcl_cos((box_ymin + box_ymax) * 0.5 * 0.01745329251));
   outSpacing[1] = -57.295779513 * m_DEMGridStep / 6378137.0;
-  outputPtr->SetSpacing(outSpacing);
+  outputPtr->SetSignedSpacing(outSpacing);
 
   // Choose origin
   typename TOutputDEMImage::PointType outOrigin;
@@ -381,7 +381,7 @@ DisparityMapToDEMFilter<TDisparityImage,TInputImage,TOutputDEMImage,TEpipolarGri
 
   typename DEMImageType::RegionType outRegion = outputDEM->GetRequestedRegion();
   typename DEMImageType::PointType outOrigin = outputDEM->GetOrigin();
-  typename DEMImageType::SpacingType outSpacing = outputDEM->GetSpacing();
+  typename DEMImageType::SpacingType outSpacing = outputDEM->GetSignedSpacing();
 
   RSTransformType::Pointer groundToLeftTransform = RSTransformType::New();
   groundToLeftTransform->SetOutputKeywordList(leftSensor->GetImageKeywordlist());
diff --git a/Modules/Registration/DisparityMap/include/otbFineRegistrationImageFilter.txx b/Modules/Registration/DisparityMap/include/otbFineRegistrationImageFilter.txx
index 1261e6b..b19bced 100644
--- a/Modules/Registration/DisparityMap/include/otbFineRegistrationImageFilter.txx
+++ b/Modules/Registration/DisparityMap/include/otbFineRegistrationImageFilter.txx
@@ -145,7 +145,7 @@ FineRegistrationImageFilter<TInputImage, TOutputCorrelation, TOutputDisplacement
   // Update size and spacing according to grid step
   InputImageRegionType largestRegion  = outputPtr->GetLargestPossibleRegion();
   SizeType outputSize       = largestRegion.GetSize();
-  SpacingType outputSpacing = outputPtr->GetSpacing();
+  SpacingType outputSpacing = outputPtr->GetSignedSpacing();
 
   for(unsigned int dim = 0; dim < TOutputCorrelation::ImageDimension; ++dim)
     {
@@ -154,8 +154,8 @@ FineRegistrationImageFilter<TInputImage, TOutputCorrelation, TOutputDisplacement
     }
 
   // Set spacing
-  outputPtr->SetSpacing(outputSpacing);
-  outputFieldPtr->SetSpacing(outputSpacing);
+  outputPtr->SetSignedSpacing(outputSpacing);
+  outputFieldPtr->SetSignedSpacing(outputSpacing);
 
   // Set largest region size
   largestRegion.SetSize(outputSize);
@@ -406,7 +406,7 @@ FineRegistrationImageFilter<TInputImage, TOutputCorrelation, TOutputDisplacement
   SpacingType localOffset = m_InitialOffset;
 
   // Get fixed image spacing
-  SpacingType fixedSpacing = fixedPtr->GetSpacing();
+  SpacingType fixedSpacing = fixedPtr->GetSignedSpacing();
 
 
   // Walk the images
diff --git a/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.txx b/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.txx
index 125285d..5115388 100644
--- a/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.txx
+++ b/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.txx
@@ -216,10 +216,10 @@ MultiDisparityMapTo3DFilter<TDisparityImage,TOutputImage,TMaskImage,TResidueImag
 
     // copy also origin and spacing
     outputPtr->SetOrigin(horizDisp->GetOrigin());
-    outputPtr->SetSpacing(horizDisp->GetSpacing());
+    outputPtr->SetSignedSpacing(horizDisp->GetSignedSpacing());
 
     residuePtr->SetOrigin(horizDisp->GetOrigin());
-    residuePtr->SetSpacing(horizDisp->GetSpacing());
+    residuePtr->SetSignedSpacing(horizDisp->GetSignedSpacing());
 
     if (this->m_ReferenceKeywordList.GetSize() > 0)
       {
diff --git a/Modules/Registration/DisparityMap/include/otbNCCRegistrationFunction.txx b/Modules/Registration/DisparityMap/include/otbNCCRegistrationFunction.txx
index 893eba2..eb5f109 100644
--- a/Modules/Registration/DisparityMap/include/otbNCCRegistrationFunction.txx
+++ b/Modules/Registration/DisparityMap/include/otbNCCRegistrationFunction.txx
@@ -101,7 +101,7 @@ NCCRegistrationFunction<TFixedImage, TMovingImage, TDisplacementField>
     }
 
   // cache fixed image information
-  m_FixedImageSpacing    = this->m_FixedImage->GetSpacing();
+  m_FixedImageSpacing    = this->m_FixedImage->GetSignedSpacing();
   m_FixedImageOrigin     = this->m_FixedImage->GetOrigin();
 
   // setup gradient calculator
diff --git a/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.txx b/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.txx
index fd1333e..69041e4 100644
--- a/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.txx
+++ b/Modules/Registration/DisparityMap/include/otbPixelWiseBlockMatchingImageFilter.txx
@@ -343,17 +343,17 @@ TOutputDisparityImage,TMaskImage,TBlockMatchingFunctor>
   outVDispPtr->SetLargestPossibleRegion(outputLargest);
 
   // Adapt spacing
-  SpacingType outSpacing = inLeftPtr->GetSpacing();
+  SpacingType outSpacing = inLeftPtr->GetSignedSpacing();
   outSpacing[0] *= static_cast<double>(this->m_Step);
   outSpacing[1] *= static_cast<double>(this->m_Step);
 
-  outMetricPtr->SetSpacing(outSpacing);
-  outHDispPtr->SetSpacing(outSpacing);
-  outVDispPtr->SetSpacing(outSpacing);
+  outMetricPtr->SetSignedSpacing(outSpacing);
+  outHDispPtr->SetSignedSpacing(outSpacing);
+  outVDispPtr->SetSignedSpacing(outSpacing);
 
   // Adapt origin
   PointType outOrigin = inLeftPtr->GetOrigin();
-  SpacingType inSpacing = inLeftPtr->GetSpacing();
+  SpacingType inSpacing = inLeftPtr->GetSignedSpacing();
   outOrigin[0] += inSpacing[0] * static_cast<double>(this->m_GridIndex[0]);
   outOrigin[1] += inSpacing[1] * static_cast<double>(this->m_GridIndex[1]);
 
diff --git a/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.txx b/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.txx
index 7234628..a8b9426 100644
--- a/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.txx
+++ b/Modules/Registration/DisparityMap/include/otbSubPixelDisparityImageFilter.txx
@@ -429,8 +429,8 @@ TDisparityImage,TMaskImage,TBlockMatchingFunctor>
   outVDispPtr->CopyInformation(inHDispPtr);
 
   // Check the size of the input disparity maps (possible subsampled grid)
-  SpacingType leftSpacing = inLeftPtr->GetSpacing();
-  SpacingType dispSpacing = inHDispPtr->GetSpacing();
+  SpacingType leftSpacing = inLeftPtr->GetSignedSpacing();
+  SpacingType dispSpacing = inHDispPtr->GetSignedSpacing();
   PointType   leftOrigin  = inLeftPtr->GetOrigin();
   PointType   dispOrigin  = inHDispPtr->GetOrigin();
 
diff --git a/Modules/Registration/DisparityMap/test/otbFineRegistrationImageFilterTest.cxx b/Modules/Registration/DisparityMap/test/otbFineRegistrationImageFilterTest.cxx
index f8b3acb..9309cc7 100644
--- a/Modules/Registration/DisparityMap/test/otbFineRegistrationImageFilterTest.cxx
+++ b/Modules/Registration/DisparityMap/test/otbFineRegistrationImageFilterTest.cxx
@@ -25,7 +25,7 @@
 #include "otbImageFileWriter.h"
 #include "otbFineRegistrationImageFilter.h"
 #include "otbStandardFilterWatcher.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include "otbExtractROI.h"
 
 
@@ -154,11 +154,10 @@ int otbFineRegistrationImageFilterTest( int argc, char * argv[] )
   }
 
   //otb::StandardFilterWatcher watcher(registration,"Registration");
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   registration->Update();
-  chrono.Stop();
-  std::cout<<chrono.GetMean()<<"\t";
+
+  std::cout << "Processing time was " << chrono.GetElapsedMilliseconds() << " ms\n";
 
   CorrelWriterType::Pointer correlWriter = CorrelWriterType::New();
   correlWriter->SetFileName(correlFileName);
diff --git a/Modules/Registration/DisplacementField/include/otbPointSetToDisplacementFieldGenerator.txx b/Modules/Registration/DisplacementField/include/otbPointSetToDisplacementFieldGenerator.txx
index 75c8376..66009e3 100644
--- a/Modules/Registration/DisplacementField/include/otbPointSetToDisplacementFieldGenerator.txx
+++ b/Modules/Registration/DisplacementField/include/otbPointSetToDisplacementFieldGenerator.txx
@@ -76,7 +76,7 @@ PointSetToDisplacementFieldGenerator<TPointSet, TDisplacementField>
   index.Fill(0);
   largest.SetIndex(index);
   outputPtr->SetRegions(largest);
-  outputPtr->SetSpacing(m_OutputSpacing);
+  outputPtr->SetSignedSpacing(m_OutputSpacing);
   outputPtr->SetOrigin(m_OutputOrigin);
   // Force the displacement field to have vector pixel of size 2.
   outputPtr->SetNumberOfComponentsPerPixel(2);
diff --git a/Modules/Registration/Stereo/include/otbAdhesionCorrectionFilter.txx b/Modules/Registration/Stereo/include/otbAdhesionCorrectionFilter.txx
index 488826d..fca8ff2 100644
--- a/Modules/Registration/Stereo/include/otbAdhesionCorrectionFilter.txx
+++ b/Modules/Registration/Stereo/include/otbAdhesionCorrectionFilter.txx
@@ -182,12 +182,12 @@ AdhesionCorrectionFilter<TImage, TMask>
   ImageRegionType largestRegion  = outputPtr->GetLargestPossibleRegion();
   SizeType outputSize       = largestRegion.GetSize();
   m_ImageSize = outputSize;
-  SpacingType outputSpacing = outputPtr->GetSpacing();
+  SpacingType outputSpacing = outputPtr->GetSignedSpacing();
 
   // Set spacing
-  outputPtr->SetSpacing(outputSpacing);
-  outputMaskPtr->SetSpacing(outputSpacing);
-  outputriskedgesPtr->SetSpacing(outputSpacing);
+  outputPtr->SetSignedSpacing(outputSpacing);
+  outputMaskPtr->SetSignedSpacing(outputSpacing);
+  outputriskedgesPtr->SetSignedSpacing(outputSpacing);
 
   // Set largest region size
   largestRegion.SetSize(outputSize);
diff --git a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx
index 4d0a45c..811a24f 100644
--- a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx
+++ b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx
@@ -242,7 +242,7 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::SetOutputPara
   //std::cout<<" GrisStep "<<m_DEMGridStep<<std::endl;
   outSpacing[0] = 57.295779513 * m_DEMGridStep / (6378137.0 * vcl_cos((box_ymin + box_ymax) * 0.5 * 0.01745329251));
   outSpacing[1] = -57.295779513 * m_DEMGridStep / 6378137.0;
-  outputPtr->SetSpacing(outSpacing);
+  outputPtr->SetSignedSpacing(outSpacing);
 
   // Choose origin
   typename TOutputDEMImage::PointType outOrigin;
@@ -278,7 +278,7 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::SetOutputPara
   // genericRSEstimator->SetInputProjectionRef( static_cast<std::string>(otb::GeoInformationConversion::ToWKT(4326)));
    genericRSEstimator->SetOutputProjectionRef(m_ProjectionRef);
    genericRSEstimator->Compute();
-   outputPtr->SetSpacing(genericRSEstimator->GetOutputSpacing());
+   outputPtr->SetSignedSpacing(genericRSEstimator->GetOutputSpacing());
    outputPtr->SetOrigin(genericRSEstimator->GetOutputOrigin());
 
     // Compute output size
@@ -311,7 +311,7 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::GenerateOutpu
   if (this->m_OutputParametersFrom3DMap == -2)
     {
     outputPtr->SetOrigin(m_OutputOrigin);
-    outputPtr->SetSpacing(m_OutputSpacing);
+    outputPtr->SetSignedSpacing(m_OutputSpacing);
 
     typename TOutputDEMImage::RegionType outRegion;
     outRegion.SetIndex(m_OutputStartIndex);
@@ -357,7 +357,7 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::GenerateInput
 
   typename TOutputDEMImage::RegionType outRegion = outputDEM->GetRequestedRegion();
   typename TOutputDEMImage::PointType outOrigin = outputDEM->GetOrigin();
-  typename TOutputDEMImage::SpacingType outSpacing = outputDEM->GetSpacing();
+  typename TOutputDEMImage::SpacingType outSpacing = outputDEM->GetSignedSpacing();
 
   // up left at elevation min
   TDPointType corners[8];
@@ -402,12 +402,12 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::GenerateInput
     RSTransformType::Pointer groundToSensorTransform = RSTransformType::New();
     //groundToSensorTransform->SetInputKeywordList(outputDEM->GetImageKeywordlist());
     //groundToSensorTransform->SetInputOrigin(outputDEM->GetOrigin());
-    //groundToSensorTransform->SetInputSpacing(outputDEM->GetSpacing());
+    //groundToSensorTransform->SetInputSpacing(outputDEM->GetSignedSpacing());
     groundToSensorTransform->SetInputProjectionRef(m_ProjectionRef);
 
     groundToSensorTransform->SetOutputKeywordList(imgPtr->GetImageKeywordlist());
     groundToSensorTransform->SetOutputOrigin(imgPtr->GetOrigin());
-    groundToSensorTransform->SetOutputSpacing(imgPtr->GetSpacing());
+    groundToSensorTransform->SetOutputSpacing(imgPtr->GetSignedSpacing());
     groundToSensorTransform->InstantiateTransform();
 
     typename T3DImage::RegionType mapRegion = imgPtr->GetLargestPossibleRegion();
@@ -568,7 +568,7 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::ThreadedGener
   typename OutputImageType::PointType pointRefStep;
   typename OutputImageType::RegionType requestedRegion = outputPtr->GetRequestedRegion();
 
-//  typename TOutputDEMImage::SpacingType step = outputPtr->GetSpacing();
+//  typename TOutputDEMImage::SpacingType step = outputPtr->GetSignedSpacing();
 
   //convert requested region to Long/Lat
 
@@ -606,7 +606,7 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::ThreadedGener
       typename InputMapType::PointType origin;
       origin = imgPtr->GetOrigin();
       typename InputMapType::SpacingType spacing;
-      spacing = imgPtr->GetSpacing();
+      spacing = imgPtr->GetSignedSpacing();
 
       if (static_cast<unsigned int> (threadId) < m_NumberOfSplit[k])
         {
diff --git a/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.txx b/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.txx
index 94c7c43..3806958 100644
--- a/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.txx
+++ b/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.txx
@@ -159,9 +159,9 @@ StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>
   // First, spacing : choose a square spacing,
   SpacingType outputSpacing;
   outputSpacing.Fill(m_Scale * m_GridStep);
-  double mean_spacing=0.5*(vcl_abs(m_LeftImage->GetSpacing()[0])+vcl_abs(m_LeftImage->GetSpacing()[1]));
-  //double ratio_x = mean_spacing / vcl_abs(m_LeftImage->GetSpacing()[0]);
-  //double ratio_y = mean_spacing / vcl_abs(m_LeftImage->GetSpacing()[1]);
+  double mean_spacing=0.5*(vcl_abs(m_LeftImage->GetSignedSpacing()[0])+vcl_abs(m_LeftImage->GetSignedSpacing()[1]));
+  //double ratio_x = mean_spacing / vcl_abs(m_LeftImage->GetSignedSpacing()[0]);
+  //double ratio_y = mean_spacing / vcl_abs(m_LeftImage->GetSignedSpacing()[1]);
 
   outputSpacing[0]*=mean_spacing;
   outputSpacing[1]*=mean_spacing;
@@ -240,14 +240,14 @@ StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>
 
   // First we compute coordinates of the 4 corners (we omit ulx which
   // coordinates are {0,0})
-  double urx = ux * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0];
-  double ury = vx * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0];
-  double llx = uy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
-  double lly = vy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
-  double lrx = ux * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0]
-             + uy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
-  double lry = vx * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSpacing()[0]
-             + vy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSpacing()[1];
+  double urx = ux * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSignedSpacing()[0];
+  double ury = vx * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSignedSpacing()[0];
+  double llx = uy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSignedSpacing()[1];
+  double lly = vy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSignedSpacing()[1];
+  double lrx = ux * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSignedSpacing()[0]
+             + uy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSignedSpacing()[1];
+  double lry = vx * m_LeftImage->GetLargestPossibleRegion().GetSize()[0] * m_LeftImage->GetSignedSpacing()[0]
+             + vy * m_LeftImage->GetLargestPossibleRegion().GetSize()[1] * m_LeftImage->GetSignedSpacing()[1];
 
   // Bounding box (this time we do not omit ulx)
   double minx = std::min(std::min(std::min(urx,llx),lrx),0.);
@@ -279,8 +279,8 @@ StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>
   leftDFPtr->SetLargestPossibleRegion(outputLargestRegion);
   rightDFPtr->SetLargestPossibleRegion(outputLargestRegion);
 
-  leftDFPtr->SetSpacing(outputSpacing);
-  rightDFPtr->SetSpacing(outputSpacing);
+  leftDFPtr->SetSignedSpacing(outputSpacing);
+  rightDFPtr->SetSignedSpacing(outputSpacing);
 
   leftDFPtr->SetNumberOfComponentsPerPixel(2);
   rightDFPtr->SetNumberOfComponentsPerPixel(2);
@@ -333,7 +333,7 @@ StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>
   double localElevation = otb::DEMHandler::Instance()->GetDefaultHeightAboveEllipsoid();
 
   // Use the mean spacing as before
-  double mean_spacing=0.5*(vcl_abs(m_LeftImage->GetSpacing()[0])+vcl_abs(m_LeftImage->GetSpacing()[1]));
+  double mean_spacing=0.5*(vcl_abs(m_LeftImage->GetSignedSpacing()[0])+vcl_abs(m_LeftImage->GetSignedSpacing()[1]));
 
   // Initialize
   currentPoint1 = m_OutputOriginInLeftImage;
diff --git a/Modules/Remote/Mosaic.remote.cmake b/Modules/Remote/Mosaic.remote.cmake
index 035a5bc..d26b730 100644
--- a/Modules/Remote/Mosaic.remote.cmake
+++ b/Modules/Remote/Mosaic.remote.cmake
@@ -5,5 +5,5 @@ A more detailed description can be found on the project website:
 https://github.com/remicres/otb-mosaic
 "
   GIT_REPOSITORY https://github.com/remicres/otb-mosaic.git
-  GIT_TAG 56426908db01f33a5b96311e2a7eaac30ecd8e5d
+  GIT_TAG 1d557e3c69cb11428f5dbf7c7039dc966dd8c51e
 )
diff --git a/Modules/Remote/SertitObject.remote.cmake b/Modules/Remote/SertitObject.remote.cmake
index e424926..cabe632 100644
--- a/Modules/Remote/SertitObject.remote.cmake
+++ b/Modules/Remote/SertitObject.remote.cmake
@@ -25,6 +25,8 @@ attributes are for each band of the input image : mean, standard-deviation,
 median, variance, kurtosis, skewness. The result could be use to perform further
 object-oriented image analysis.
 "
-  GIT_REPOSITORY https://github.com/sertit/SertitObject.git
-  GIT_TAG 49b6540c774ddb7c2d56e39f6f118c4dfb9b8bd3
+  GIT_REPOSITORY https://github.com/gpo-geo/SertitObject
+  GIT_TAG 4e6c46b239760b206d4cee379c0e90ee33abf613
 )
+
+# use a temporary fork because pull request #8 not merged yet
diff --git a/Modules/Remote/otbFFSforGMM.remote.cmake b/Modules/Remote/otbFFSforGMM.remote.cmake
index edd80d7..b75c04c 100644
--- a/Modules/Remote/otbFFSforGMM.remote.cmake
+++ b/Modules/Remote/otbFFSforGMM.remote.cmake
@@ -25,5 +25,5 @@ A more detailed description can be found on the project website:
 https://github.com/Laadr/otbFFSforGMM
 "
   GIT_REPOSITORY https://github.com/Laadr/otbFFSforGMM.git
-  GIT_TAG 1164391d09b9987f7f7ea6718347c772e31a396a
+  GIT_TAG f9aa7988fc399d8713f9e28fac15e637a783be6e
   )
diff --git a/Modules/Remote/temporal-gapfilling.remote.cmake b/Modules/Remote/temporal-gapfilling.remote.cmake
index a33a9e0..469a857 100644
--- a/Modules/Remote/temporal-gapfilling.remote.cmake
+++ b/Modules/Remote/temporal-gapfilling.remote.cmake
@@ -26,5 +26,6 @@ A more detailed description can be found on the project website:
 http://tully.ups-tlse.fr/jordi/temporalgapfilling
 "
   GIT_REPOSITORY http://tully.ups-tlse.fr/jordi/temporalgapfilling.git
-  GIT_TAG 4180f28091fb10029860ada2dcf9c9526d3a55d2
+  # Commit on develop branch which includes patches for Windows support
+  GIT_TAG 4fc4a71acf7b9b051cda5a3b950de2cdb9d26287
 )
diff --git a/Modules/Segmentation/CCOBIA/include/otbStreamingConnectedComponentSegmentationOBIAToVectorDataFilter.txx b/Modules/Segmentation/CCOBIA/include/otbStreamingConnectedComponentSegmentationOBIAToVectorDataFilter.txx
index 1990174..1556cc7 100644
--- a/Modules/Segmentation/CCOBIA/include/otbStreamingConnectedComponentSegmentationOBIAToVectorDataFilter.txx
+++ b/Modules/Segmentation/CCOBIA/include/otbStreamingConnectedComponentSegmentationOBIAToVectorDataFilter.txx
@@ -138,10 +138,10 @@ PersistentConnectedComponentSegmentationOBIAToVectorDataFilter<TVImage, TLabelIm
 
   typename TransformType::ParametersType params;
   params.SetSize(6);
-  params[0] = this->GetInput()->GetSpacing()[0];
+  params[0] = this->GetInput()->GetSignedSpacing()[0];
   params[1] = 0;
   params[2] = 0;
-  params[3] = this->GetInput()->GetSpacing()[1];
+  params[3] = this->GetInput()->GetSignedSpacing()[1];
   params[4] = this->GetInput()->GetOrigin()[0];
   params[5] = this->GetInput()->GetOrigin()[1];
 
diff --git a/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx b/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx
index 8bce44f..0d41eba 100644
--- a/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx
@@ -187,10 +187,10 @@ LabelImageToOGRDataSourceFilter<TInputImage>
     IndexType  bufferIndexOrigin = this->GetInput()->GetBufferedRegion().GetIndex();
     OriginType  bufferOrigin;
     this->GetInput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
-    geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInput()->GetSpacing()[0];
-    geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInput()->GetSpacing()[1];
-    geoTransform[1] = this->GetInput()->GetSpacing()[0];
-    geoTransform[5] = this->GetInput()->GetSpacing()[1];
+    geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInput()->GetSignedSpacing()[0];
+    geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInput()->GetSignedSpacing()[1];
+    geoTransform[1] = this->GetInput()->GetSignedSpacing()[0];
+    geoTransform[5] = this->GetInput()->GetSignedSpacing()[1];
     // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
     if (projSize == 0)
     {
@@ -215,7 +215,7 @@ LabelImageToOGRDataSourceFilter<TInputImage>
     //Call GDALPolygonize()
     char ** options;
     options = ITK_NULLPTR;
-    char * option[1];
+    char * option[2]= { nullptr , nullptr } ;
     if (m_Use8Connected == true)
     {
       std::string opt("8CONNECTED:8");
@@ -257,10 +257,10 @@ LabelImageToOGRDataSourceFilter<TInputImage>
       // the spacing is unchanged, the origin is relative to the buffered region
       bufferIndexOrigin = this->GetInputMask()->GetBufferedRegion().GetIndex();
       this->GetInputMask()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
-      geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInputMask()->GetSpacing()[0];
-      geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInputMask()->GetSpacing()[1];
-      geoTransform[1] = this->GetInputMask()->GetSpacing()[0];
-      geoTransform[5] = this->GetInputMask()->GetSpacing()[1];
+      geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInputMask()->GetSignedSpacing()[0];
+      geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInputMask()->GetSignedSpacing()[1];
+      geoTransform[1] = this->GetInputMask()->GetSignedSpacing()[0];
+      geoTransform[5] = this->GetInputMask()->GetSignedSpacing()[1];
       // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
       if (projSize == 0)
       {
diff --git a/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.txx b/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.txx
index 7374c85..698b326 100644
--- a/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbLabelImageToVectorDataFilter.txx
@@ -167,10 +167,10 @@ LabelImageToVectorDataFilter<TInputImage, TPrecision>
     IndexType  bufferIndexOrigin = this->GetInput()->GetBufferedRegion().GetIndex();
     OriginType  bufferOrigin;
     this->GetInput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
-    geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInput()->GetSpacing()[0];
-    geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInput()->GetSpacing()[1];
-    geoTransform[1] = this->GetInput()->GetSpacing()[0];
-    geoTransform[5] = this->GetInput()->GetSpacing()[1];
+    geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInput()->GetSignedSpacing()[0];
+    geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInput()->GetSignedSpacing()[1];
+    geoTransform[1] = this->GetInput()->GetSignedSpacing()[0];
+    geoTransform[5] = this->GetInput()->GetSignedSpacing()[1];
     // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
     if (projSize == 0)
     {
@@ -237,10 +237,10 @@ LabelImageToVectorDataFilter<TInputImage, TPrecision>
       // the spacing is unchanged, the origin is relative to the buffered region
       bufferIndexOrigin = this->GetInputMask()->GetBufferedRegion().GetIndex();
       this->GetInputMask()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
-      geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInputMask()->GetSpacing()[0];
-      geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInputMask()->GetSpacing()[1];
-      geoTransform[1] = this->GetInputMask()->GetSpacing()[0];
-      geoTransform[5] = this->GetInputMask()->GetSpacing()[1];
+      geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetInputMask()->GetSignedSpacing()[0];
+      geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetInputMask()->GetSignedSpacing()[1];
+      geoTransform[1] = this->GetInputMask()->GetSignedSpacing()[0];
+      geoTransform[5] = this->GetInputMask()->GetSignedSpacing()[1];
       // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
       if (projSize == 0)
       {
diff --git a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.h b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.h
index d6dff7d..4210753 100644
--- a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.h
+++ b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.h
@@ -109,7 +109,7 @@ public:
   itkGetConstReferenceMacro(OutputOrigin, OutputOriginType);
 
   /** Set the spacing (size of a pixel) of the output image.
-  * \sa GetSpacing()
+  * \sa GetSignedSpacing()
   */
   virtual void SetOutputSpacing(const OutputSpacingType& spacing);
   virtual void SetOutputSpacing(const double spacing[2]);
diff --git a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx
index 6dbb4b8..ef069d7 100644
--- a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx
@@ -27,6 +27,7 @@
 #include "otbImageMetadataInterfaceFactory.h"
 #include "itkMetaDataObject.h"
 #include "otbMetaDataKey.h"
+#include "otbImage.h"
 
 #include "gdal_alg.h"
 #include "stdint.h" //needed for uintptr_t
@@ -126,7 +127,7 @@ OGRDataSourceToLabelImageFilter<TOutputImage>
 ::SetOutputParametersFromImage(const ImageBaseType * image)
 {
     this->SetOutputOrigin ( image->GetOrigin() );
-    this->SetOutputSpacing ( image->GetSpacing() );
+    this->SetOutputSpacing ( internal::GetSignedSpacing( image ) );
     this->SetOutputSize ( image->GetLargestPossibleRegion().GetSize() );
     
     ImageMetadataInterfaceBase::Pointer imi = ImageMetadataInterfaceFactory::CreateIMI(image->GetMetaDataDictionary());
@@ -153,7 +154,7 @@ OGRDataSourceToLabelImageFilter<TOutputImage>
   outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
 
   // Set spacing and origin
-  outputPtr->SetSpacing(m_OutputSpacing);
+  outputPtr->SetSignedSpacing(m_OutputSpacing);
   outputPtr->SetOrigin(m_OutputOrigin);
 
   itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
@@ -229,10 +230,10 @@ OGRDataSourceToLabelImageFilter<TOutputImage>::GenerateData()
   OutputIndexType  bufferIndexOrigin = bufferedRegion.GetIndex();
   OutputOriginType bufferOrigin;
   this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
-  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSpacing()[0];
-  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSpacing()[1];
-  geoTransform[1] = this->GetOutput()->GetSpacing()[0];
-  geoTransform[5] = this->GetOutput()->GetSpacing()[1];
+  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSignedSpacing()[0];
+  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSignedSpacing()[1];
+  geoTransform[1] = this->GetOutput()->GetSignedSpacing()[0];
+  geoTransform[5] = this->GetOutput()->GetSignedSpacing()[1];
 
   // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
   geoTransform[2] = 0.;
diff --git a/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRDataFilter.txx b/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRDataFilter.txx
index 83a255e..598033e 100644
--- a/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRDataFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRDataFilter.txx
@@ -23,7 +23,7 @@
 #define otbPersistentImageToOGRDataFilter_txx
 
 #include "otbPersistentImageToOGRDataFilter.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include <boost/foreach.hpp>
 #include <stdio.h>
 #include "otbMacro.h"
@@ -166,11 +166,9 @@ PersistentImageToOGRDataFilter<TImage>
 
 
   //Copy features contained in the memory layer (srcLayer) in the output layer
-  itk::TimeProbe chrono;
-  chrono.Start();
-  
-  OGRErr err = dstLayer.ogr().StartTransaction();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
 
+  OGRErr err = dstLayer.ogr().StartTransaction();
   if (err != OGRERR_NONE)
     {
     itkExceptionMacro(<< "Unable to start transaction for OGR layer " << dstLayer.ogr().GetName() << ".");
@@ -192,7 +190,7 @@ PersistentImageToOGRDataFilter<TImage>
     }
 
   chrono.Stop();
-  otbMsgDebugMacro(<< "write ogr tile took " << chrono.GetTotal() << " sec");
+  otbMsgDebugMacro(<< "Writing OGR tile took " << chrono.GetElapsedMilliseconds() << " ms");
 }
 
 template<class TImage>
diff --git a/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRLayerFilter.txx b/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRLayerFilter.txx
index a31aaae..730dd18 100644
--- a/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRLayerFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbPersistentImageToOGRLayerFilter.txx
@@ -23,7 +23,7 @@
 #define otbPersistentImageToOGRLayerFilter_txx
 
 #include "otbPersistentImageToOGRLayerFilter.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include <boost/foreach.hpp>
 #include <stdio.h>
 #include "otbMacro.h"
@@ -143,11 +143,9 @@ PersistentImageToOGRLayerFilter<TImage>
      }
 
   //Copy features contained in the memory layer (srcLayer) in the output layer
-  itk::TimeProbe chrono;
-  chrono.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
 
   OGRErr err = m_OGRLayer.ogr().StartTransaction();
-
   if (err != OGRERR_NONE)
     {
     itkExceptionMacro(<< "Unable to start transaction for OGR layer " << m_OGRLayer.ogr().GetName() << ".");
@@ -162,14 +160,14 @@ PersistentImageToOGRLayerFilter<TImage>
     }
 
   err = m_OGRLayer.ogr().CommitTransaction();
-  
+
   if (err != OGRERR_NONE)
     {
     itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << m_OGRLayer.ogr().GetName() << ".");
     }
 
   chrono.Stop();
-  otbMsgDebugMacro(<< "write ogr tile took " << chrono.GetTotal() << " sec");
+  otbMsgDebugMacro(<< "Writing OGR tile took " << chrono.GetElapsedMilliseconds() << " ms");
 
 }
 
diff --git a/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.txx b/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.txx
index 69752f7..58f817c 100644
--- a/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.txx
@@ -178,10 +178,10 @@ RasterizeVectorDataFilter<TVectorData, TInputImage, TOutputImage>::GenerateData(
   InputIndexType  bufferIndexOrigin = bufferedRegion.GetIndex();
   InputPointType  bufferOrigin;
   this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
-  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSpacing()[0];
-  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSpacing()[1];
-  geoTransform[1] = this->GetOutput()->GetSpacing()[0];
-  geoTransform[5] = this->GetOutput()->GetSpacing()[1];
+  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSignedSpacing()[0];
+  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSignedSpacing()[1];
+  geoTransform[1] = this->GetOutput()->GetSignedSpacing()[0];
+  geoTransform[5] = this->GetOutput()->GetSignedSpacing()[1];
 
   // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
   geoTransform[2] = 0.;
diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h
index e8b7b0d..c7a0627 100644
--- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h
+++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h
@@ -107,7 +107,7 @@ public:
   itkGetConstReferenceMacro(OutputOrigin, OutputOriginType);
 
   /** Set the spacing (size of a pixel) of the output image.
-  * \sa GetSpacing()
+  * \sa GetSignedSpacing()
   */
   virtual void SetOutputSpacing(const OutputSpacingType& spacing);
   virtual void SetOutputSpacing(const double spacing[2]);
diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx
index 20ce77a..f874cd6 100644
--- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.txx
@@ -29,6 +29,7 @@
 #include "otbGdalDataTypeBridge.h"
 #include "otbImageMetadataInterfaceBase.h"
 #include "otbImageMetadataInterfaceFactory.h"
+#include "otbImage.h"
 
 namespace otb
 {
@@ -127,7 +128,7 @@ VectorDataToLabelImageFilter<TVectorData, TOutputImage>
 ::SetOutputParametersFromImage(const ImageBaseType * src)
 {
   this->SetOutputOrigin ( src->GetOrigin() );
-  this->SetOutputSpacing ( src->GetSpacing() );
+  this->SetOutputSpacing ( internal::GetSignedSpacing(src) );
   this->SetOutputSize ( src->GetLargestPossibleRegion().GetSize() );
   ImageMetadataInterfaceBase::Pointer imi = ImageMetadataInterfaceFactory::CreateIMI(src->GetMetaDataDictionary());
   this->SetOutputProjectionRef(imi->GetProjectionRef());
@@ -152,7 +153,7 @@ VectorDataToLabelImageFilter<TVectorData, TOutputImage>
   outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
 
   // Set spacing and origin
-  outputPtr->SetSpacing(m_OutputSpacing);
+  outputPtr->SetSignedSpacing(m_OutputSpacing);
   outputPtr->SetOrigin(m_OutputOrigin);
 
   itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
@@ -301,10 +302,10 @@ VectorDataToLabelImageFilter<TVectorData, TOutputImage>::GenerateData()
   OutputIndexType  bufferIndexOrigin = bufferedRegion.GetIndex();
   OutputOriginType bufferOrigin;
   this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
-  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSpacing()[0];
-  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSpacing()[1];
-  geoTransform[1] = this->GetOutput()->GetSpacing()[0];
-  geoTransform[5] = this->GetOutput()->GetSpacing()[1];
+  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSignedSpacing()[0];
+  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSignedSpacing()[1];
+  geoTransform[1] = this->GetOutput()->GetSignedSpacing()[0];
+  geoTransform[5] = this->GetOutput()->GetSignedSpacing()[1];
 
   // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
   geoTransform[2] = 0.;
diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.h b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.h
index 8048c31..924b6ff 100644
--- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.h
+++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapFilter.h
@@ -147,7 +147,7 @@ public:
   itkGetConstReferenceMacro(StartIndex, IndexType);
   itkSetMacro(StartIndex, IndexType);
   /** Set the spacing (size of a pixel) of the vector data.
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   virtual void SetSpacing(const SpacingType& spacing);
   virtual void SetSpacing(const double spacing[2]);
   virtual void SetSpacing(const float spacing[2]);
diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.h b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.h
index 8bf4d55..acedfce 100644
--- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.h
+++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelMapWithAttributesFilter.h
@@ -162,7 +162,7 @@ public:
 ; itkSetMacro(StartIndex, IndexType)
 ;
   /** Set the spacing (size of a pixel) of the vector data.
-   * \sa GetSpacing() */
+   * \sa GetSignedSpacing() */
   virtual void SetSpacing(const SpacingType& spacing);
   virtual void SetSpacing(const double spacing[2]);
   virtual void SetSpacing(const float spacing[2]);
diff --git a/Modules/Segmentation/Conversion/test/otbLabelMapToVectorDataFilter.cxx b/Modules/Segmentation/Conversion/test/otbLabelMapToVectorDataFilter.cxx
index df1429d..f32a91e 100644
--- a/Modules/Segmentation/Conversion/test/otbLabelMapToVectorDataFilter.cxx
+++ b/Modules/Segmentation/Conversion/test/otbLabelMapToVectorDataFilter.cxx
@@ -79,7 +79,7 @@ int otbLabelMapToVectorDataFilter(int argc, char * argv[])
 
   VectorDataFilterType::Pointer vectorDataProjection = VectorDataFilterType::New();
   vectorDataProjection->SetInputOrigin(lreader->GetOutput()->GetOrigin());
-  vectorDataProjection->SetInputSpacing(lreader->GetOutput()->GetSpacing());
+  vectorDataProjection->SetInputSpacing(lreader->GetOutput()->GetSignedSpacing());
   vectorDataProjection->SetInput(MyFilter->GetOutput());
 
   writer->SetFileName(outfname);
diff --git a/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx b/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx
index 94c7ab5..54621ce 100644
--- a/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx
+++ b/Modules/Segmentation/Conversion/test/otbVectorDataToLabelMapFilter.cxx
@@ -20,7 +20,6 @@
 
 #include "itkLabelMapToLabelImageFilter.h"
 
-#include "itkTimeProbe.h"
 #include "otbMacro.h"
 #include "otbImage.h"
 //#include "otbImageFileReader.h"
diff --git a/Modules/Segmentation/OGRProcessing/include/otbOGRLayerStreamStitchingFilter.txx b/Modules/Segmentation/OGRProcessing/include/otbOGRLayerStreamStitchingFilter.txx
index b078914..53a3717 100644
--- a/Modules/Segmentation/OGRProcessing/include/otbOGRLayerStreamStitchingFilter.txx
+++ b/Modules/Segmentation/OGRProcessing/include/otbOGRLayerStreamStitchingFilter.txx
@@ -26,7 +26,6 @@
 
 #include <iomanip>
 #include "ogrsf_frmts.h"
-#include "itkTimeProbe.h"
 #include <set>
 
 namespace otb
@@ -363,7 +362,7 @@ OGRLayerStreamStitchingFilter<TInputImage>
 
       if(m_OGRLayer.ogr().TestCapability("Transactions"))
         {
-      
+
         OGRErr errCommitX = m_OGRLayer.ogr().CommitTransaction();
         if (errCommitX != OGRERR_NONE)
           {
@@ -371,11 +370,11 @@ OGRLayerStreamStitchingFilter<TInputImage>
           }
         }
    } //end for y
-      
+
    if(m_OGRLayer.ogr().TestCapability("Transactions"))
      {
      const OGRErr errCommitY = m_OGRLayer.ogr().CommitTransaction();
-     
+
      if (errCommitY != OGRERR_NONE)
        {
        itkWarningMacro(<< "Unable to commit transaction for OGR layer " << m_OGRLayer.ogr().GetName() << ". Gdal error code " << errCommitY << "." << std::endl);
diff --git a/Modules/Segmentation/OGRProcessing/include/otbStreamingImageToOGRLayerSegmentationFilter.txx b/Modules/Segmentation/OGRProcessing/include/otbStreamingImageToOGRLayerSegmentationFilter.txx
index 7c8db05..86e702c 100644
--- a/Modules/Segmentation/OGRProcessing/include/otbStreamingImageToOGRLayerSegmentationFilter.txx
+++ b/Modules/Segmentation/OGRProcessing/include/otbStreamingImageToOGRLayerSegmentationFilter.txx
@@ -27,7 +27,7 @@
 #include "otbVectorDataTransformFilter.h"
 #include "itkAffineTransform.h"
 
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include "otbMacro.h"
 #include <cassert>
 
@@ -76,8 +76,6 @@ PersistentImageToOGRLayerSegmentationFilter<TImageType, TSegmentationFilter>
 {
   otbMsgDebugMacro(<< "tile number : " << m_TileNumber);
   ++m_TileNumber;
-  itk::TimeProbe tileChrono;
-  tileChrono.Start();
 
   // Apply an ExtractImageFilter to avoid problems with filters asking for the LargestPossibleRegion
   typedef itk::ExtractImageFilter<InputImageType, InputImageType> ExtractImageFilterType;
@@ -94,16 +92,13 @@ PersistentImageToOGRLayerSegmentationFilter<TImageType, TSegmentationFilter>
   typename LabelImageToOGRDataSourceFilterType::Pointer labelImageToOGRDataFilter =
                                               LabelImageToOGRDataSourceFilterType::New();
 
-  itk::TimeProbe chrono1;
-  chrono1.Start();
+  otb::Stopwatch chrono = otb::Stopwatch::StartNew();
   m_SegmentationFilter->SetInput(extract->GetOutput());
   m_SegmentationFilter->UpdateLargestPossibleRegion();
 
-  chrono1.Stop();
-  otbMsgDebugMacro(<<"segmentation took " << chrono1.GetTotal() << " sec");
+  otbMsgDebugMacro(<<"segmentation took " << chrono.GetElapsedMilliseconds() / 1000 << " sec");
 
-  itk::TimeProbe chrono2;
-  chrono2.Start();
+  chrono.Restart();
   typename LabelImageType::ConstPointer inputMask = this->GetInputMask();
   if (!inputMask.IsNull())
   {
@@ -124,16 +119,14 @@ PersistentImageToOGRLayerSegmentationFilter<TImageType, TSegmentationFilter>
   labelImageToOGRDataFilter->SetUse8Connected(m_Use8Connected);
   labelImageToOGRDataFilter->Update();
 
-  chrono2.Stop();
-  otbMsgDebugMacro(<< "vectorization took " << chrono2.GetTotal() << " sec");
+  otbMsgDebugMacro(<< "vectorization took " << chrono.GetElapsedMilliseconds() / 1000 << " sec");
 
   //Relabeling & simplication of geometries & filtering small objects
-  itk::TimeProbe chrono3;
-  chrono3.Start();
+  chrono.Restart();
   OGRDataSourcePointerType tmpDS = const_cast<OGRDataSourceType *>(labelImageToOGRDataFilter->GetOutput());
   OGRLayerType tmpLayer = tmpDS->GetLayer(0);
 
-  const typename InputImageType::SpacingType inSpacing = this->GetInput()->GetSpacing();
+  const typename InputImageType::SpacingType inSpacing = this->GetInput()->GetSignedSpacing();
   const double tol = m_SimplificationTolerance * std::max(vcl_abs(inSpacing[0]),vcl_abs(inSpacing[1]));
 
   typename OGRLayerType::iterator featIt = tmpLayer.begin();
@@ -160,7 +153,7 @@ PersistentImageToOGRLayerSegmentationFilter<TImageType, TSegmentationFilter>
      {
         double area = static_cast<const OGRPolygon *>((*featIt).GetGeometry())->get_Area();
         //convert into pixel coordinates
-        typename InputImageType::SpacingType spacing = this->GetInput()->GetSpacing();
+        typename InputImageType::SpacingType spacing = this->GetInput()->GetSignedSpacing();
         double pixelsArea = area / (vcl_abs(spacing[0]*spacing[1]));
         otbMsgDebugMacro(<<"DN = "<<field.GetValue<int>()<<", area = "<<pixelsArea);
         if( pixelsArea < m_MinimumObjectSize )
@@ -169,8 +162,8 @@ PersistentImageToOGRLayerSegmentationFilter<TImageType, TSegmentationFilter>
         }
      }
   }
-  chrono3.Stop();
-  otbMsgDebugMacro(<< "relabeling, filtering small objects and simplifying geometries took " << chrono3.GetTotal() << " sec");
+  chrono.Stop();
+  otbMsgDebugMacro(<< "relabeling, filtering small objects and simplifying geometries took " << chrono.GetElapsedMilliseconds() / 1000 << " sec");
 
   return tmpDS;
 }
diff --git a/Modules/Wrappers/QtWidget/CMakeLists.txt b/Modules/ThirdParty/GSL/CMakeLists.txt
similarity index 84%
copy from Modules/Wrappers/QtWidget/CMakeLists.txt
copy to Modules/ThirdParty/GSL/CMakeLists.txt
index 4162b8d..0fe382c 100644
--- a/Modules/Wrappers/QtWidget/CMakeLists.txt
+++ b/Modules/ThirdParty/GSL/CMakeLists.txt
@@ -18,7 +18,10 @@
 # limitations under the License.
 #
 
-project(OTBQtWidget)
+project(OTBGSL)
+set(OTBGSL_THIRD_PARTY 1)
+
+set(OTBGSL_SYSTEM_INCLUDE_DIRS ${GSL_INCLUDE_DIR})
+set(OTBGSL_LIBRARIES ${GSL_LIBRARY})
 
-set(OTBQtWidget_LIBRARIES OTBQtWidget)
 otb_module_impl()
diff --git a/Packaging/install_python_bindings.cmake b/Modules/ThirdParty/GSL/otb-module-init.cmake
similarity index 71%
copy from Packaging/install_python_bindings.cmake
copy to Modules/ThirdParty/GSL/otb-module-init.cmake
index 451894b..c584f58 100644
--- a/Packaging/install_python_bindings.cmake
+++ b/Modules/ThirdParty/GSL/otb-module-init.cmake
@@ -17,11 +17,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-function(install_python_bindings)
-  if(HAVE_PYTHON)
-    install(DIRECTORY ${SUPERBUILD_INSTALL_DIR}/lib/otb/python
-      DESTINATION ${PKG_STAGE_DIR}/lib
-      PATTERN "*.pyc" EXCLUDE
-      )
+
+find_package(GSL REQUIRED)
+
+# On Windows system, if you will be using one of the dynamic libraries, add GSL_DLL to the list of predefined macros
+if (BUILD_SHARED_LIBS)
+  if (WIN32)
+    add_definitions(-DGSL_DLL)
   endif()
-endfunction()
+endif()
+
+mark_as_advanced(GSL_INCLUDE_DIR)
+mark_as_advanced(GSL_LIBRARY)
diff --git a/Modules/Applications/AppFiltering/otb-module.cmake b/Modules/ThirdParty/GSL/otb-module.cmake
similarity index 76%
copy from Modules/Applications/AppFiltering/otb-module.cmake
copy to Modules/ThirdParty/GSL/otb-module.cmake
index 5e8fc45..39f25c7 100644
--- a/Modules/Applications/AppFiltering/otb-module.cmake
+++ b/Modules/ThirdParty/GSL/otb-module.cmake
@@ -18,19 +18,16 @@
 # limitations under the License.
 #
 
-set(DOCUMENTATION "Image filtering application.")
+set(DOCUMENTATION "This module imports GSL to the build system.  Note that when using the GLS
+library you must comply with the GPL license.")
 
-otb_module(OTBAppFiltering
+otb_module(OTBGSL
   DEPENDS
-    OTBImageManipulation
-    OTBITK
-    OTBApplicationEngine
-    OTBImageBase
 
   TEST_DEPENDS
-    OTBTestKernel
-    OTBCommandLine
-
+    
   DESCRIPTION
     "${DOCUMENTATION}"
-)
+  )
+
+otb_module_activation_option("Enable GSL dependent modules" OFF)
diff --git a/Modules/ThirdParty/ITK/include/itkTransformToDisplacementFieldSource.hxx b/Modules/ThirdParty/ITK/include/itkTransformToDisplacementFieldSource.hxx
index 212a0f8..c8db8c9 100644
--- a/Modules/ThirdParty/ITK/include/itkTransformToDisplacementFieldSource.hxx
+++ b/Modules/ThirdParty/ITK/include/itkTransformToDisplacementFieldSource.hxx
@@ -155,7 +155,7 @@ TransformToDisplacementFieldSource< TOutputImage, TTransformPrecisionType >
     }
 
   this->SetOutputOrigin( image->GetOrigin() );
-  this->SetOutputSpacing( image->GetSpacing() );
+  this->SetOutputSpacing( image->GetSignedSpacing() );
   this->SetOutputDirection( image->GetDirection() );
   this->SetOutputRegion( image->GetLargestPossibleRegion() );
 } // end SetOutputParametersFromImage()
@@ -352,7 +352,7 @@ TransformToDisplacementFieldSource< TOutputImage, TTransformPrecisionType >
 
   outputPtr->SetLargestPossibleRegion(m_OutputRegion);
 
-  outputPtr->SetSpacing(m_OutputSpacing);
+  outputPtr->SetSignedSpacing(m_OutputSpacing);
   outputPtr->SetOrigin(m_OutputOrigin);
   outputPtr->SetDirection(m_OutputDirection);
 } // end GenerateOutputInformation()
diff --git a/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx b/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx
index c84c6d9..e5872dd 100644
--- a/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx
+++ b/Modules/ThirdParty/ITK/include/itkUnaryFunctorImageFilter.hxx
@@ -133,7 +133,7 @@ UnaryFunctorImageFilter< TInputImage, TOutputImage, TFunction >
       }
 
     // set the spacing and origin
-    outputPtr->SetSpacing(outputSpacing);
+    outputPtr->SetSpacing( outputSpacing );
     outputPtr->SetOrigin(outputOrigin);
     outputPtr->SetDirection(outputDirection);
     outputPtr->SetNumberOfComponentsPerPixel(  // propagate vector length info
diff --git a/Modules/ThirdParty/Ossim/otb-module-init.cmake b/Modules/ThirdParty/Ossim/otb-module-init.cmake
index 12dd307..e6fbb52 100644
--- a/Modules/ThirdParty/Ossim/otb-module-init.cmake
+++ b/Modules/ThirdParty/Ossim/otb-module-init.cmake
@@ -19,3 +19,5 @@
 #
 
 find_package ( Ossim REQUIRED )
+
+set(OTB_OSSIM_VERSION ${OSSIM_VERSION_NUMBER} CACHE INTERNAL "Ossim version detected by OTB" FORCE)
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimKeyWordListUtilities.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimKeyWordListUtilities.h
similarity index 99%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimKeyWordListUtilities.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimKeyWordListUtilities.h
index 235ea89..fb665c4 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimKeyWordListUtilities.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimKeyWordListUtilities.h
@@ -26,8 +26,8 @@
 #ifndef ossimKeyWordListUtilities_h
 #define ossimKeyWordListUtilities_h
 
-#include "ossimStringUtilities.h"
-#include "ossimXmlTools.h"
+#include "ossim/ossimStringUtilities.h"
+#include "ossim/ossimXmlTools.h"
 #include <ossim/base/ossimKeywordlist.h>
 #include <ossim/base/ossimRefPtr.h>
 #include <ossim/base/ossimXmlNode.h>
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimOperatorUtilities.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimOperatorUtilities.h
similarity index 100%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimOperatorUtilities.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimOperatorUtilities.h
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRangeUtilities.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimRangeUtilities.h
similarity index 100%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimRangeUtilities.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimRangeUtilities.h
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
similarity index 97%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
index e62e774..d76968e 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
@@ -38,14 +38,14 @@
 #   pragma GCC diagnostic ignored "-Wshadow"
 #   include <ossim/projection/ossimSensorModel.h>
 #   include <ossim/elevation/ossimHgtRef.h>
-#   include "ossimTimeUtilities.h"
+#   include "ossim/ossimTimeUtilities.h"
 
 # pragma GCC diagnostic pop
 
 #else
 #   include <ossim/projection/ossimSensorModel.h>
 #   include <ossim/elevation/ossimHgtRef.h>
-#   include "ossimTimeUtilities.h"
+#   include "ossim/ossimTimeUtilities.h"
 #endif
 
 #if defined(USE_BOOST_TIME)
@@ -216,9 +216,9 @@ public:
    virtual ~ossimSarSensorModel() = default;
 #endif
 
-   virtual void lineSampleHeightToWorld(const ossimDpt& imPt, const double & heightEllipsoid, ossimGpt& worldPt) const;
+   virtual void lineSampleHeightToWorld(const ossimDpt& imPt, const double & heightEllipsoid, ossimGpt& worldPt) const override;
 
-   virtual void lineSampleToWorld(const ossimDpt& imPt, ossimGpt& worldPt) const;
+   virtual void lineSampleToWorld(const ossimDpt& imPt, ossimGpt& worldPt) const override;
 
 
    /** This method implement inverse sar geolocation using method found
@@ -229,7 +229,7 @@ public:
     * \param[in] worldPt World point to geocode
     * \param[out] imPt Corresponding estimated image point
     */
-   virtual void worldToLineSample(const ossimGpt& worldPt, ossimDpt & imPt) const;
+   virtual void worldToLineSample(const ossimGpt& worldPt, ossimDpt & imPt) const override;
 
    /**
     * Sub-routine of lineSampleToWorld that computes azimuthTime and
@@ -288,16 +288,16 @@ public:
     * \param deburstLine The output original image line
     */
    static void deburstLineToImageLine(const std::vector<std::pair<unsigned long,unsigned long> >& lines, unsigned long deburstLine, unsigned long & imageLine);
-   
+
    /**
     * Returns pointer to a new instance, copy of this.
     */
-   virtual ossimObject* dup() const;
+   virtual ossimObject* dup() const override;
 
    //TODO: Add virtual method readAnnotationFile?
 
-   virtual bool saveState(ossimKeywordlist      & kwl, const char* prefix=NULL) const;
-   virtual bool loadState(ossimKeywordlist const& kwl, const char* prefix=NULL);
+   virtual bool saveState(ossimKeywordlist      & kwl, const char* prefix=NULL) const override;
+   virtual bool loadState(ossimKeywordlist const& kwl, const char* prefix=NULL) override;
 
    bool isGRD() const {
       switch (theProductType.ToInternal()) {
@@ -311,8 +311,9 @@ public:
       }
    }
 
-   virtual std::ostream& print(std::ostream& out) const;
+   virtual std::ostream& print(std::ostream& out) const override;
 protected:
+   TYPE_DATA;
 
    /**
     * Compute range and doppler frequency from an input point, sensor
@@ -420,6 +421,9 @@ protected:
    double                                      theRangeTimeOffset; // Offset in seconds, computed
 
    static const double C;
+
+   static const unsigned int thePluginVersion; // version of the SarSensorModel plugin
+
 private:
    /** Disabled assignment operator.  */
    ossimSarSensorModel& operator=(ossimSarSensorModel const& rhs);
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModelPathsAndKeys.h
similarity index 96%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModelPathsAndKeys.h
index 841b357..49a874a 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModelPathsAndKeys.h
@@ -37,6 +37,8 @@ namespace ossimplugins {
    extern const std::string GR_PREFIX           ;
    extern const std::string BURST_PREFIX        ;
    extern const std::string BURST_NUMBER_KEY    ;
+   extern const std::string ORBIT_PREFIX        ;
+   extern const std::string ORBIT_NUMBER_KEY    ;
    extern const std::string GCP_PREFIX          ;
    extern const std::string GCP_NUMBER_KEY      ;
    extern const std::string NUMBER_KEY          ;
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimStringUtilities.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimStringUtilities.h
similarity index 100%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimStringUtilities.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimStringUtilities.h
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTimeUtilities.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimTimeUtilities.h
similarity index 99%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimTimeUtilities.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimTimeUtilities.h
index 284b18b..e566fd8 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTimeUtilities.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimTimeUtilities.h
@@ -25,8 +25,8 @@
 #ifndef ossimTimeUtilities_h
 #define ossimTimeUtilities_h
 
-#include "ossimStringUtilities.h"
-#include "ossimOperatorUtilities.h"
+#include "ossim/ossimStringUtilities.h"
+#include "ossim/ossimOperatorUtilities.h"
 #include "ossimPluginConstants.h"
 #include <cassert>
 #include <ostream>
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTraceHelpers.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimTraceHelpers.h
similarity index 100%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimTraceHelpers.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimTraceHelpers.h
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimXmlTools.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimXmlTools.h
similarity index 97%
rename from Modules/ThirdParty/OssimPlugins/src/ossim/ossimXmlTools.h
rename to Modules/ThirdParty/OssimPlugins/include/ossim/ossimXmlTools.h
index 998a1af..ab250ae 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimXmlTools.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimXmlTools.h
@@ -32,8 +32,8 @@ class ossimXmlDocument;
 #if defined(USE_BOOST_TIME)
 #   include <boost/date_time/posix_time/posix_time.hpp>
 #endif
-#include "ossimStringUtilities.h"
-#include "ossimTimeUtilities.h"
+#include "ossim/ossimStringUtilities.h"
+#include "ossim/ossimTimeUtilities.h"
 #include <ossim/base/ossimXmlNode.h>
 
 namespace ossimplugins {
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossimPluginConstants.h b/Modules/ThirdParty/OssimPlugins/include/ossimPluginConstants.h
similarity index 100%
rename from Modules/ThirdParty/OssimPlugins/src/ossimPluginConstants.h
rename to Modules/ThirdParty/OssimPlugins/include/ossimPluginConstants.h
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimPluginProjectionFactory.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimPluginProjectionFactory.cpp
index d70cbe9..6961803 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimPluginProjectionFactory.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimPluginProjectionFactory.cpp
@@ -40,8 +40,10 @@
 #include "ossimTileMapModel.h"
 #include "ossimSpot6Model.h"
 #include "ossimSentinel1Model.h"
-#include "ossimStringUtilities.h"
-#include "ossimTraceHelpers.h"
+
+#include "ossim/ossimStringUtilities.h"
+#include "ossim/ossimTraceHelpers.h"
+
 #include <ossim/base/ossimKeywordNames.h>
 #include <ossim/base/ossimRefPtr.h>
 #include <ossim/projection/ossimProjection.h>
@@ -390,6 +392,10 @@ ossimProjection* ossimPluginProjectionFactory::createProjection(
    {
      return new ossimSentinel1Model;
    }
+   else if(name == STATIC_TYPE_NAME(ossimSarSensorModel))
+   {
+     return new ossimSarSensorModel;
+   }
 
    //***
    // ADD_MODEL: (Please leave this comment for the next programmer)
@@ -465,6 +471,12 @@ ossimProjection* ossimPluginProjectionFactory::createProjection(
          result = new ossimSentinel1Model();
       }
 
+      else if (type == "ossimSarSensorModel")
+      {
+         result = new ossimSarSensorModel();
+         std::cout<<"ossiMSarSensorModel"<<std::endl;
+      }
+
    //***
    // ADD_MODEL: (Please leave this comment for the next programmer)
    //***
@@ -476,7 +488,7 @@ ossimProjection* ossimPluginProjectionFactory::createProjection(
       // Then, try to load the keyword list
       if ( result.get() && !result->loadState(kwl, prefix) )
       {
-         result = 0;
+      result = 0;
       }
    }
 
@@ -509,6 +521,7 @@ void ossimPluginProjectionFactory::getTypeNameList(std::vector<ossimString>& typ
    typeList.push_back(STATIC_TYPE_NAME(ossimTileMapModel));
    typeList.push_back(STATIC_TYPE_NAME(ossimPleiadesModel));
    typeList.push_back(STATIC_TYPE_NAME(ossimSentinel1Model));
+   typeList.push_back(STATIC_TYPE_NAME(ossimSarSensorModel));
    typeList.push_back(STATIC_TYPE_NAME(ossimSpot6Model));
 
    //***
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
index 49e06d3..ac695a2 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
@@ -23,13 +23,14 @@
  */
 
 
-#include "ossimSarSensorModel.h"
-#include "ossimKeyWordListUtilities.h"
-#include "ossimTraceHelpers.h"
-#include "ossimRangeUtilities.h"
-#include "ossimSarSensorModelPathsAndKeys.h"
+#include "ossim/ossimSarSensorModel.h"
+#include "ossim/ossimKeyWordListUtilities.h"
+#include "ossim/ossimTraceHelpers.h"
+#include "ossim/ossimRangeUtilities.h"
+#include "ossim/ossimSarSensorModelPathsAndKeys.h"
 #include <ossim/base/ossimRegExp.h>
 #include <ossim/base/ossimLsrSpace.h>
+#include <ossim/base/ossimKeywordNames.h>
 #include <boost/static_assert.hpp>
 #include <iostream>
 #include <vector>
@@ -45,7 +46,6 @@ using ossimplugins::time::seconds;
 
 namespace {// Anonymous namespace
    const bool         k_verbose = false; // global verbose constant; TODO: use an option
-   const unsigned int k_version = 2;
 
    // Sometimes, we don't need to compare the actual distance, its square value is
    // more than enough.
@@ -103,8 +103,12 @@ namespace {// Anonymous namespace
 
 namespace ossimplugins
 {
+   RTTI_DEF1(ossimSarSensorModel, "ossimSarSensorModel", ossimSensorModel);
+
    const double ossimSarSensorModel::C = 299792458;
 
+   const unsigned int ossimSarSensorModel::thePluginVersion = 2;
+
    ossimSarSensorModel::ProductType::ProductType(string_view const& s)
    {
       using ossimplugins::begin;
@@ -949,6 +953,9 @@ namespace ossimplugins
       DurationType cumulAzimuthTime(seconds(0));
       double cumulRangeTime(0);
       unsigned int count=0;
+      // reset offsets before optimisation
+      theAzimuthTimeOffset = seconds(0);
+      theRangeTimeOffset = 0.0;
 
       // First, fix the azimuth time
       for(std::vector<GCPRecordType>::const_iterator gcpIt = theGCPRecords.begin(); gcpIt!=theGCPRecords.end();++gcpIt)
@@ -1037,6 +1044,30 @@ namespace ossimplugins
       }
    }
 
+   void add(
+       ossimKeywordlist & kwl,
+       const std::vector<ossimSarSensorModel::OrbitRecordType> & orbitRecords)
+   {
+     char orbit_prefix_[256];
+
+     add(kwl,ORBIT_NUMBER_KEY,(ossim_uint32)orbitRecords.size());
+
+     for(std::size_t i = 0; i!=orbitRecords.size();++i)
+       {
+       const int pos = s_printf(orbit_prefix_, "%s[%d].", ORBIT_PREFIX.c_str(), int(i));
+       assert(pos > 0 && pos < 256);
+       const std::string orbit_prefix(orbit_prefix_, pos);
+
+       add(kwl, orbit_prefix + keyTime, orbitRecords[i].azimuthTime);
+       add(kwl, orbit_prefix + keyPosX, orbitRecords[i].position[0]);
+       add(kwl, orbit_prefix + keyPosY, orbitRecords[i].position[1]);
+       add(kwl, orbit_prefix + keyPosZ, orbitRecords[i].position[2]);
+       add(kwl, orbit_prefix + keyVelX, orbitRecords[i].velocity[0]);
+       add(kwl, orbit_prefix + keyVelY, orbitRecords[i].velocity[1]);
+       add(kwl, orbit_prefix + keyVelZ, orbitRecords[i].velocity[2]);
+       }
+   }
+
    void get(
          ossimKeywordlist                             const& kwl,
          std::vector<ossimSarSensorModel::BurstRecordType> & burstRecords)
@@ -1058,6 +1089,24 @@ namespace ossimplugins
       }
    }
 
+   void add(
+     ossimKeywordlist                                        & kwl,
+     const std::vector<ossimSarSensorModel::BurstRecordType> & burstRecords)
+   {
+     char burstPrefix_[1024];
+     add(kwl, BURST_NUMBER_KEY, (ossim_uint32)burstRecords.size());
+     for (std::size_t burstId=0; burstId!=burstRecords.size() ; ++burstId) {
+     const int pos = s_printf(burstPrefix_, "%s[%d].", BURST_PREFIX.c_str(), burstId);
+     assert(pos > 0 && pos < sizeof(burstPrefix_));
+     const std::string burstPrefix(burstPrefix_, pos);
+
+     add(kwl, burstPrefix + keyStartLine, (ossim_uint32) burstRecords[burstId].startLine);
+     add(kwl, burstPrefix + keyEndLine, (ossim_uint32) burstRecords[burstId].endLine);
+     add(kwl, burstPrefix + keyAzimuthStartTime, burstRecords[burstId].azimuthStartTime);
+     add(kwl, burstPrefix + keyAzimuthStopTime,  burstRecords[burstId].azimuthStopTime);
+     }
+   }
+
    void get(
          ossimKeywordlist                             const& kwl,
          std::vector<ossimSarSensorModel::GCPRecordType> & gcpRecords)
@@ -1082,6 +1131,28 @@ namespace ossimplugins
       }
    }
 
+   void add(
+     ossimKeywordlist                                      & kwl,
+     const std::vector<ossimSarSensorModel::GCPRecordType> & gcpRecords)
+   {
+     char prefix_[1024];
+     add(kwl, GCP_NUMBER_KEY, (ossim_uint32)gcpRecords.size());
+     for (std::size_t gcpId=0; gcpId!=gcpRecords.size() ; ++gcpId) {
+     const int pos = s_printf(prefix_, "%s[%d].", GCP_PREFIX.c_str(), gcpId);
+     assert(pos > 0 && pos < sizeof(prefix_));
+     const std::string prefix(prefix_, pos);
+
+     add(kwl, prefix, keyAzimuthTime,    gcpRecords[gcpId].azimuthTime);
+     add(kwl, prefix, keySlantRangeTime, gcpRecords[gcpId].slantRangeTime);
+     add(kwl, prefix, keyImPtX,          gcpRecords[gcpId].imPt.x);
+     add(kwl, prefix, keyImPtY,          gcpRecords[gcpId].imPt.y);
+     add(kwl, prefix, keyWorldPtLat,     gcpRecords[gcpId].worldPt.lat);
+     add(kwl, prefix, keyWorldPtLon,     gcpRecords[gcpId].worldPt.lon);
+     add(kwl, prefix, keyWorldPtHgt,     gcpRecords[gcpId].worldPt.hgt);
+     }
+   }
+
+
    void get(
          ossimKeywordlist                                            const& kwl,
          std::string                                                 const& sr_gr_prefix,
@@ -1116,12 +1187,78 @@ namespace ossimplugins
       }
    }
 
+   void add(
+     ossimKeywordlist                                                       & kwl,
+     std::string                                                       const& sr_gr_prefix,
+     std::string                                                       const& rg0,
+     const std::vector<ossimSarSensorModel::CoordinateConversionRecordType> & conversionRecords)
+   {
+     char prefix_[1024];
+     add(kwl, sr_gr_prefix +"."+ NUMBER_KEY, (ossim_uint32)conversionRecords.size());
+
+     for (std::size_t idx=0 ; idx!=conversionRecords.size() ; ++idx)
+       {
+       const int pos = s_printf(prefix_, "%s[%d].", sr_gr_prefix.c_str(), idx);
+       assert(pos >= sizeof(SR_PREFIX)+4 && pos < sizeof(prefix_));
+       std::string prefix(prefix_, pos);
+
+
+       add(kwl, prefix + keyAzimuthTime,  conversionRecords[idx].azimuthTime);
+       add(kwl, prefix + rg0,             conversionRecords[idx].rg0);
+
+       std::size_t nbCoeffs = conversionRecords[idx].coefs.size();
+       add(kwl, prefix + NUMBER_KEY,      (ossim_uint32)nbCoeffs);
+       for (std::size_t coeff_idx=0; coeff_idx!=nbCoeffs ; ++coeff_idx)
+         {
+         const int pos2 = s_printf(prefix_+pos, sizeof(prefix_)-pos, "coeff[%d]", coeff_idx);
+         assert(pos2 > 0 && pos+pos2 < sizeof(prefix_));
+         prefix.assign(prefix_, pos+pos2);
+         add(kwl, prefix, conversionRecords[idx].coefs[coeff_idx]);
+         }
+       }
+   }
    bool ossimSarSensorModel::saveState(ossimKeywordlist& kwl, const char* prefix) const
    {
-      SCOPED_LOG(traceDebug, "ossimplugins::ossimSarSensorModel::loadState");
+     static const char MODULE[] = "ossimplugins::ossimSarSensorModel::saveState";
+     SCOPED_LOG(traceDebug, MODULE);
 
-      add(kwl, HEADER_PREFIX, "version", k_version);
-      return ossimSensorModel::saveState(kwl, prefix);
+     // Prevent override of subclasses TYPE_KW
+     
+     if(!kwl.hasKey(ossimKeywordNames::TYPE_KW))
+       {
+       kwl.add(prefix,
+               ossimKeywordNames::TYPE_KW,
+               "ossimSarSensorModel",
+               true);
+       }
+
+     std::string product_type = theProductType.ToString().data();
+     add(kwl, SUPPORT_DATA_PREFIX + "product_type", product_type);
+     add(kwl, SUPPORT_DATA_PREFIX, "slant_range_to_first_pixel", theNearRangeTime      );
+     add(kwl, SUPPORT_DATA_PREFIX, "range_sampling_rate"       , theRangeSamplingRate  );
+     add(kwl, SUPPORT_DATA_PREFIX, "range_spacing"             , theRangeResolution    );
+     add(kwl, SUPPORT_DATA_PREFIX, "radar_frequency"           , theRadarFrequency     );
+     add(kwl, SUPPORT_DATA_PREFIX, "line_time_interval"        , theAzimuthTimeInterval.total_seconds());
+
+     kwl.removeKeysThatMatch(ORBIT_PREFIX+"*");
+     add(kwl, theOrbitRecords);
+
+     kwl.removeKeysThatMatch(BURST_PREFIX+"*");
+     add(kwl, theBurstRecords);
+
+     if (isGRD())
+       {
+       kwl.removeKeysThatMatch(SR_PREFIX+"*");
+       add(kwl, SR_PREFIX, keySr0, theSlantRangeToGroundRangeRecords);
+       kwl.removeKeysThatMatch(GR_PREFIX+"*");
+       add(kwl, GR_PREFIX, keyGr0, theGroundRangeToSlantRangeRecords);
+       }
+     kwl.removeKeysThatMatch(GCP_PREFIX+"*");
+     add(kwl, theGCPRecords);
+
+     add(kwl, HEADER_PREFIX, "version", thePluginVersion);
+
+     return ossimSensorModel::saveState(kwl, prefix);
    }
 
    bool ossimSarSensorModel::loadState(ossimKeywordlist const& kwl, const char* prefix)
@@ -1169,7 +1306,7 @@ namespace ossimplugins
          try {
             unsigned int version;
             get(kwl, HEADER_PREFIX, "version", version);
-            if (version < k_version) {
+            if (version < thePluginVersion) {
                throw std::runtime_error("Geom file generated with previous version of ossim plugins");
             }
          } catch (...) {
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp
index d40b6e6..ad5bcf1 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModelPathsAndKeys.cpp
@@ -23,7 +23,7 @@
  */
 
 
-#include "ossimSarSensorModelPathsAndKeys.h"
+#include "ossim/ossimSarSensorModelPathsAndKeys.h"
 
 namespace ossimplugins {
    const std::string HEADER_PREFIX       = "header.";
@@ -34,6 +34,8 @@ namespace ossimplugins {
    const std::string GR_PREFIX           = "support_data.geom.srd.coords.gr";
    const std::string BURST_PREFIX        = "support_data.geom.bursts.burst";
    const std::string BURST_NUMBER_KEY    = "support_data.geom.bursts.number";
+   const std::string ORBIT_PREFIX        = "orbitList.orbit";
+   const std::string ORBIT_NUMBER_KEY    = "orbitList.nb_orbits";
    const std::string GCP_PREFIX          = "support_data.geom.gcp";
    const std::string GCP_NUMBER_KEY      = "support_data.geom.gcp.number";
    const std::string NUMBER_KEY          = "number";
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
index 10ecc60..716e7ad 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
@@ -24,10 +24,10 @@
 
 
 #include "ossimSentinel1Model.h"
-#include "ossimTraceHelpers.h"
-#include "ossimXmlTools.h"
-#include "ossimKeyWordListUtilities.h"
-#include "ossimSarSensorModelPathsAndKeys.h"
+#include "ossim/ossimTraceHelpers.h"
+#include "ossim/ossimXmlTools.h"
+#include "ossim/ossimKeyWordListUtilities.h"
+#include "ossim/ossimSarSensorModelPathsAndKeys.h"
 #include <ossim/base/ossimDirectory.h>
 #include <ossim/base/ossimString.h>
 #include <ossim/base/ossimXmlNode.h>
@@ -150,25 +150,6 @@ namespace ossimplugins
 
       kwl.addList(theManifestKwl, true);
       kwl.addList(theProductKwl,  true);
-
-      // Rewrite burst records since model could have been debursted
-      kwl.removeKeysThatMatch(BURST_PREFIX+"*");
-      
-      add(kwl,BURST_NUMBER_KEY.c_str(),(unsigned int)theBurstRecords.size());
-
-      unsigned int burstId(0);
-      char burstPrefix[1024];
-      
-      for(std::vector<BurstRecordType>::const_iterator burstIt = theBurstRecords.begin();
-          burstIt!=theBurstRecords.end();++burstIt)
-        {
-        s_printf(burstPrefix, "%s[%d].", BURST_PREFIX.c_str(), burstId);
-        add(kwl,burstPrefix+keyStartLine,(ossim_uint32)burstIt->startLine);
-        add(kwl,burstPrefix+keyEndLine,(ossim_uint32)burstIt->endLine);
-        add(kwl,burstPrefix+keyAzimuthStartTime,burstIt->azimuthStartTime);
-        add(kwl,burstPrefix+keyAzimuthStopTime,burstIt->azimuthStopTime);
-        ++burstId;
-        }
       
       return ossimSarSensorModel::saveState(kwl, prefix);
    }
@@ -230,6 +211,8 @@ namespace ossimplugins
 
       // -----[ Read manifest file
       const ossimFilename safeFile = searchManifestFile(file);
+      ossimString sensorId;
+      ossimString imageId;
 
       if ( !safeFile.empty() )
       {
@@ -251,8 +234,8 @@ namespace ossimplugins
             ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << "Manifest file " << safeFile << " opened\n";
          }
 
-         theImageID = getImageId(manifestDoc);
-         if (theImageID.empty()) {
+         imageId = getImageId(manifestDoc);
+         if (imageId.empty()) {
             ossimNotify(ossimNotifyLevel_FATAL) << MODULE << "Image ID not found in manifest file " << safeFile << "\n";
             return false;
          }
@@ -262,8 +245,8 @@ namespace ossimplugins
             return false;
          }
 
-         theSensorID = initSensorID(manifestDoc);
-         if (theSensorID.empty()) {
+         sensorId = initSensorID(manifestDoc);
+         if (sensorId.empty()) {
             ossimNotify(ossimNotifyLevel_FATAL) << MODULE << "Cannot load sensor ID from " << safeFile << "\n";
             return false;
          }
@@ -332,6 +315,10 @@ namespace ossimplugins
          return false;
       }
 
+      // Fix sensor and image ID as they may be overriden during SensorModel::loadState()
+      theSensorID = sensorId;
+      theImageID = imageId;
+
       theImageClipRect = ossimDrect( 0, 0, theImageSize.x-1, theImageSize.y-1 );
       theSubImageOffset.x = 0.0;
       theSubImageOffset.y = 0.0;
@@ -696,6 +683,8 @@ namespace ossimplugins
       addMandatory(theProductKwl, HEADER_PREFIX, "first_line_time", adsHeader, "startTime");
       addMandatory(theProductKwl, HEADER_PREFIX, "last_line_time",  adsHeader, "stopTime");
 
+      add(theProductKwl, HEADER_PREFIX, "version", thePluginVersion);
+
       //RK maybe use this->getManifestPrefix()
 
       add(theProductKwl, SUPPORT_DATA_PREFIX, "mds1_tx_rx_polar", polarisation);
@@ -803,6 +792,10 @@ namespace ossimplugins
             numBands,
             true);
 #endif
+
+      // Ensure that superclass members are initialized
+      loadState(theProductKwl);
+      
       return true;
    }
 
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h
index 79a1c13..50816ef 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.h
@@ -38,7 +38,7 @@
 
 //#include <ossim/projection/ossimSensorModel.h>
 //#include <ossim/projection/ossimCoarseGridModel.h>
-#include "ossimSarSensorModel.h"
+#include "ossim/ossimSarSensorModel.h"
 #include "ossimPluginConstants.h" // OSSIM_PLUGINS_DLL
 
 #include <ossim/support_data/ossimSupportFilesList.h>
@@ -81,22 +81,22 @@ namespace ossimplugins
       /*!
        * Returns pointer to a new instance, copy of this.
        */
-      virtual ossimObject* dup() const;
+      virtual ossimObject* dup() const override;
 
       /*!
        * Extends base-class implementation. Dumps contents of object to ostream.
        */
-      virtual std::ostream& print(std::ostream& out) const;
+      virtual std::ostream& print(std::ostream& out) const override;
 
       /*!
        * Fulfills ossimObject base-class pure virtuals. Loads and saves geometry
        * KWL files. Returns true if successful.
        */
       virtual bool saveState(ossimKeywordlist& kwl,
-            const char* prefix=NULL) const;
+            const char* prefix=NULL) const override;
 
       virtual bool loadState(ossimKeywordlist const& kwl,
-            const char* prefix=NULL);
+            const char* prefix=NULL) override;
 
       bool checkDirectory(const ossimFilename& file, const char* d, const char *ext) const;
 
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp
index 97d0e44..99cdf4b 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.cpp
@@ -25,7 +25,7 @@
 
 #include <ossimSentinel1SarSensorModel.h>
 #include <ossim/base/ossimXmlDocument.h>
-#include <ossimXmlTools.h>
+#include "ossim/ossimXmlTools.h"
 
 namespace {// Anonymous namespace
     const ossimString attAzimuthTime      = "azimuthTime";
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.h b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.h
index ddae9ea..a3bc211 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1SarSensorModel.h
@@ -27,7 +27,7 @@
 #define ossimSentinel1SarSensorModel_HEADER
 
 #include <boost/config.hpp>
-#include "ossimSarSensorModel.h"
+#include "ossim/ossimSarSensorModel.h"
 
 class ossimXmlDocument;
 class ossimString;
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimStringUtilities.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimStringUtilities.cpp
index db4f965..73da22f 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimStringUtilities.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimStringUtilities.cpp
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 
-#include "ossimStringUtilities.h"
+#include "ossim/ossimStringUtilities.h"
 #include "ossimplugins-config.h"
 #if defined(HAVE_STD_SNPRINTF)
 #  include <cstdio>
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.cpp
index a26cf5c..c745bbe 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.cpp
@@ -25,7 +25,7 @@
 
 #include <ossimTerraSarXSarSensorModel.h>
 #include <ossim/base/ossimXmlDocument.h>
-#include <ossimXmlTools.h>
+#include "ossim/ossimXmlTools.h"
 
 
 namespace {// Anonymous namespace
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.h
index d02a10f..f2bdf75 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTerraSarXSarSensorModel.h
@@ -26,7 +26,7 @@
 #ifndef ossimTerraSarXSarSensorModel_HEADER
 #define ossimTerraSarXSarSensorModel_HEADER
 
-#include "ossimSarSensorModel.h"
+#include "ossim/ossimSarSensorModel.h"
 
 namespace ossimplugins
 {
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTimeUtilities.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTimeUtilities.cpp
index 0a49a10..5df49e4 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTimeUtilities.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimTimeUtilities.cpp
@@ -22,14 +22,14 @@
  * THE SOFTWARE.
  */
 
-#include "ossimTimeUtilities.h"
+#include "ossim/ossimTimeUtilities.h"
 #include <stdexcept>
 // #include <sstream>
 #include <typeinfo>
 #include <cmath>
 #include <cstdio>
 #include <stdexcept>
-#include "ossimStringUtilities.h"
+#include "ossim/ossimStringUtilities.h"
 #include <ossim/base/ossimDate.h>
 // #include <iostream>
 
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimWin32FindFileHandle.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimWin32FindFileHandle.cpp
index 3b5b4f0..f800c74 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimWin32FindFileHandle.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimWin32FindFileHandle.cpp
@@ -23,7 +23,7 @@
  */
 
 #include <cassert>
-#include "ossimStringUtilities.h"
+#include "ossim/ossimStringUtilities.h"
 #include "ossimWin32FindFileHandle.h"
 
 namespace ossimplugins {
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimXmlTools.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimXmlTools.cpp
index 5d03589..35322bb 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimXmlTools.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimXmlTools.cpp
@@ -23,8 +23,8 @@
  */
 
 
-#include "ossimXmlTools.h"
-#include "ossimTimeUtilities.h"
+#include "ossim/ossimXmlTools.h"
+#include "ossim/ossimTimeUtilities.h"
 #include <ossim/base/ossimString.h>
 #include <ossim/base/ossimXmlDocument.h>
 #include <ossim/base/ossimNotify.h>
diff --git a/Modules/ThirdParty/OssimPlugins/test/ossimSarSensorModelTest.cpp b/Modules/ThirdParty/OssimPlugins/test/ossimSarSensorModelTest.cpp
index f473549..11440ce 100644
--- a/Modules/ThirdParty/OssimPlugins/test/ossimSarSensorModelTest.cpp
+++ b/Modules/ThirdParty/OssimPlugins/test/ossimSarSensorModelTest.cpp
@@ -23,7 +23,7 @@
  */
 
 
-#include "ossimSarSensorModel.h"
+#include "ossim/ossimSarSensorModel.h"
 
 
 int main(int, char *[])
diff --git a/Modules/ThirdParty/OssimPlugins/test/ossimStringUtilitiesTest.cpp b/Modules/ThirdParty/OssimPlugins/test/ossimStringUtilitiesTest.cpp
index 68ee097..8dc7d7e 100644
--- a/Modules/ThirdParty/OssimPlugins/test/ossimStringUtilitiesTest.cpp
+++ b/Modules/ThirdParty/OssimPlugins/test/ossimStringUtilitiesTest.cpp
@@ -31,7 +31,7 @@
 
 #define BOOST_TEST_MODULE "ossim String Utilities unit testing"
 #define BOOST_TEST_DYN_LINK
-#include "ossimStringUtilities.h"
+#include "ossim/ossimStringUtilities.h"
 #include <boost/test/unit_test.hpp>
 #include <cstdio>
 #include <iostream>
diff --git a/Modules/ThirdParty/OssimPlugins/test/ossimTimeUtilitiesTest.cpp b/Modules/ThirdParty/OssimPlugins/test/ossimTimeUtilitiesTest.cpp
index d97224e..57efd8f 100644
--- a/Modules/ThirdParty/OssimPlugins/test/ossimTimeUtilitiesTest.cpp
+++ b/Modules/ThirdParty/OssimPlugins/test/ossimTimeUtilitiesTest.cpp
@@ -31,8 +31,8 @@
 
 #define BOOST_TEST_MODULE "ossim Time Utilities unit testing"
 #define BOOST_TEST_DYN_LINK
-#include "ossimTimeUtilities.h"
-#include "ossimStringUtilities.h"
+#include "ossim/ossimTimeUtilities.h"
+#include "ossim/ossimStringUtilities.h"
 #include <boost/test/unit_test.hpp>
 #include <iostream>
 #include <iomanip>
diff --git a/Modules/Visualization/Ice/src/otbGlImageActor.cxx b/Modules/Visualization/Ice/src/otbGlImageActor.cxx
index 5bb1f06..dc14f95 100644
--- a/Modules/Visualization/Ice/src/otbGlImageActor.cxx
+++ b/Modules/Visualization/Ice/src/otbGlImageActor.cxx
@@ -154,7 +154,7 @@ void GlImageActor::Initialize(const std::string & filename)
     }
 
   m_Origin = m_FileReader->GetOutput()->GetOrigin();
-  m_Spacing = m_FileReader->GetOutput()->GetSpacing();
+  m_Spacing = m_FileReader->GetOutput()->GetSignedSpacing();
   m_NumberOfComponents = m_FileReader->GetOutput()->GetNumberOfComponentsPerPixel();
 
   unsigned int ovrCount = m_FileReader->GetOverviewsCount();
@@ -706,7 +706,7 @@ void GlImageActor::ImageRegionToViewportQuad(const RegionType & region, PointTyp
   m_FileReader->GetOutput()->TransformContinuousIndexToPhysicalPoint(clr,ilr);
 
   // Take into account that Origin refers to center of first pixel
-  SpacingType spacing = m_FileReader->GetOutput()->GetSpacing();
+  SpacingType spacing = m_FileReader->GetOutput()->GetSignedSpacing();
   iul[0]-=0.5*spacing[0];
   iul[1]-=0.5*spacing[1];
   iur[0]+=0.5*spacing[0];
diff --git a/Modules/Visualization/Ice/src/otbNonOptGlImageActor.cxx b/Modules/Visualization/Ice/src/otbNonOptGlImageActor.cxx
index e9ac317..b1ba5e1 100644
--- a/Modules/Visualization/Ice/src/otbNonOptGlImageActor.cxx
+++ b/Modules/Visualization/Ice/src/otbNonOptGlImageActor.cxx
@@ -101,7 +101,7 @@ void NonOptGlImageActor::Initialize(const std::string & filename)
     }
 
   m_Origin = m_FileReader->GetOutput()->GetOrigin();
-  m_Spacing = m_FileReader->GetOutput()->GetSpacing();
+  m_Spacing = m_FileReader->GetOutput()->GetSignedSpacing();
   m_NumberOfComponents = m_FileReader->GetOutput()->GetNumberOfComponentsPerPixel();
 
   unsigned int ovrCount = m_FileReader->GetOverviewsCount();
diff --git a/Modules/Visualization/Mapla/src/CMakeLists.txt b/Modules/Visualization/Mapla/src/CMakeLists.txt
index ee5df87..491e268 100644
--- a/Modules/Visualization/Mapla/src/CMakeLists.txt
+++ b/Modules/Visualization/Mapla/src/CMakeLists.txt
@@ -63,7 +63,7 @@ endif()
 #############################################################################
 qt4_wrap_cpp( OTBMapla_SRC_MOC ${OTBMapla_HEADERS_MOC} )
 qt4_wrap_ui( OTBMapla_FORMS_HEADERS ${OTBMapla_FORMS}  )
-qt4_add_resources( OTBMapla_RESOURCES_RCC ${OTBMapla_RESOURCES} )
+qt4_add_resources( OTBMapla_RESOURCES_RCC ${OTBMapla_RESOURCES} OPTIONS "-no-compress")
 
 #############################################################################
 add_to_qt4_i18n_sources( ${OTBMapla_SRCS} )
diff --git a/Modules/Visualization/Mapla/src/mvdMaplaMainWindow.qrc b/Modules/Visualization/Mapla/src/mvdMaplaMainWindow.qrc
index 8344829..8bfc273 100644
--- a/Modules/Visualization/Mapla/src/mvdMaplaMainWindow.qrc
+++ b/Modules/Visualization/Mapla/src/mvdMaplaMainWindow.qrc
@@ -12,6 +12,8 @@
     <file alias="action_ZoomOut_Icon">../../../../Utilities/Data/Icons/action-zoomout_24x24.png</file>
     <file alias="action_ZoomFull_Icon">../../../../Utilities/Data/Icons/action-zoomtolayer_24x24.png</file>
     <file alias="action_Open_Icon">../../../../Utilities/Data/Icons/document-open_32x32.png</file>
+    <file alias="done">../../../../Utilities/Data/Icons/check_24x24.png</file>
+    <file alias="failed">../../../../Utilities/Data/Icons/forbidden-24x24.png</file>
   </qresource>
   <qresource prefix="/images">
     <file alias="application_icon">../../../../Utilities/Data/Icons/monteverdi-128x128.png</file>
diff --git a/Modules/Visualization/Monteverdi/src/CMakeLists.txt b/Modules/Visualization/Monteverdi/src/CMakeLists.txt
index 6b450c1..87a9ffe 100644
--- a/Modules/Visualization/Monteverdi/src/CMakeLists.txt
+++ b/Modules/Visualization/Monteverdi/src/CMakeLists.txt
@@ -46,7 +46,7 @@ set( OTBMonteverdi_RESOURCES
 #############################################################################
 qt4_wrap_cpp( OTBMonteverdi_SRC_MOC ${OTBMonteverdi_HEADERS_MOC} )
 qt4_wrap_ui( OTBMonteverdi_FORMS_HEADERS ${OTBMonteverdi_FORMS}  )
-qt4_add_resources( OTBMonteverdi_RESOURCES_RCC ${OTBMonteverdi_RESOURCES} )
+qt4_add_resources( OTBMonteverdi_RESOURCES_RCC ${OTBMonteverdi_RESOURCES} OPTIONS "-no-compress")
 
 #############################################################################
 add_to_qt4_i18n_sources( ${OTBMonteverdi_SRCS} )
diff --git a/Modules/Visualization/Monteverdi/src/mvdMainWindow.qrc b/Modules/Visualization/Monteverdi/src/mvdMainWindow.qrc
index dfd8f7d..aa38455 100644
--- a/Modules/Visualization/Monteverdi/src/mvdMainWindow.qrc
+++ b/Modules/Visualization/Monteverdi/src/mvdMainWindow.qrc
@@ -22,6 +22,8 @@
     <file alias="action_ZoomOut_Icon">../../../../Utilities/Data/Icons/action-zoomout_24x24.png</file>
     <file alias="action_ZoomLayer_Icon">../../../../Utilities/Data/Icons/action-zoomtolayer_24x24.png</file>
     <file alias="action_Open_Icon">../../../../Utilities/Data/Icons/document-open_32x32.png</file>
+    <file alias="done">../../../../Utilities/Data/Icons/check_24x24.png</file>
+    <file alias="failed">../../../../Utilities/Data/Icons/forbidden-24x24.png</file>
   </qresource>
   <qresource prefix="/images">
     <file alias="application_icon">../../../../Utilities/Data/Icons/monteverdi-128x128.png</file>
diff --git a/Modules/Visualization/Monteverdi/src/mvdPreferencesDialog.ui b/Modules/Visualization/Monteverdi/src/mvdPreferencesDialog.ui
index c715d1e..ca04e6c 100644
--- a/Modules/Visualization/Monteverdi/src/mvdPreferencesDialog.ui
+++ b/Modules/Visualization/Monteverdi/src/mvdPreferencesDialog.ui
@@ -121,7 +121,7 @@
            </sizepolicy>
           </property>
           <property name="toolTip">
-           <string>When the image width or height is lower than this minimum, overview generation is not proposed</string>
+           <string>When the image width or height is lower than twice this minimum, overview generation is not proposed</string>
           </property>
           <property name="text">
            <string>Minimum size:</string>
@@ -131,7 +131,7 @@
         <item row="1" column="2">
          <widget class="QSpinBox" name="overviewsSpinBox">
           <property name="toolTip">
-           <string>When the image width or height is lower than this minimum, overview generation is not proposed</string>
+           <string>When the image width or height is lower than twice this minimum, overview generation is not proposed</string>
           </property>
           <property name="maximum">
            <number>999999999</number>
diff --git a/Modules/Visualization/MonteverdiCore/include/mvdAbstractImageModel.h b/Modules/Visualization/MonteverdiCore/include/mvdAbstractImageModel.h
index 9b9c263..8eff303 100644
--- a/Modules/Visualization/MonteverdiCore/include/mvdAbstractImageModel.h
+++ b/Modules/Visualization/MonteverdiCore/include/mvdAbstractImageModel.h
@@ -49,7 +49,7 @@
 #ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
 #include "otbImageMetadataInterfaceBase.h"
 #endif //tag=QT4-boost-compatibility
-
+#include "otbImage.h" // Needed to get otb::internal::Get/SetSignedSpacing()
 //
 // Monteverdi includes (sorted by alphabetic order)
 #ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
@@ -263,7 +263,7 @@ public:
 
   /**
    */
-  inline const SpacingType& GetSpacing() const;
+  inline const SpacingType GetSpacing() const;
 
   /**
    */
@@ -479,7 +479,8 @@ AbstractImageModel
   m_CurrentLod = lod;
 
   // if everything ok emit the new spacing of the current lod
-  emit SpacingChanged(ToImageBase()->GetSpacing());
+  emit SpacingChanged( otb::internal::GetSignedSpacing( 
+    static_cast< ImageBaseType * > ( ToImageBase() ) ) );
 }
 
 /*****************************************************************************/
@@ -554,13 +555,14 @@ AbstractImageModel
 
 /*****************************************************************************/
 inline
-const SpacingType&
+const SpacingType
 AbstractImageModel
 ::GetSpacing() const
 {
   assert( !ToImageBase().IsNull() );
 
-  return ToImageBase()->GetSpacing();
+  return otb::internal::GetSignedSpacing( 
+    static_cast< ImageBaseType const * >( ToImageBase() ) );
 }
 
 /*****************************************************************************/
diff --git a/Modules/Visualization/MonteverdiCore/src/mvdOverviewBuilder.cxx b/Modules/Visualization/MonteverdiCore/src/mvdOverviewBuilder.cxx
index 9fa8857..d3f0734 100644
--- a/Modules/Visualization/MonteverdiCore/src/mvdOverviewBuilder.cxx
+++ b/Modules/Visualization/MonteverdiCore/src/mvdOverviewBuilder.cxx
@@ -161,7 +161,7 @@ OverviewBuilder
 
 	emit ProgressTextChanged(
 	  QString(
-	    tr( "Generting overviews for file %1/%2 '%3'." )
+	    tr( "Generating overviews for file %1/%2 '%3'." )
 	  )
 	  .arg( m_Index + 1 )
 	  .arg( m_Count )
diff --git a/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx b/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx
index 378763d..558450d 100644
--- a/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx
+++ b/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx
@@ -112,7 +112,7 @@ VectorImageModel
 
   m_ImageFileReader->SetFileName( QFile::encodeName( GetFilename() ) );
   m_ImageFileReader->GetOutput()->UpdateOutputInformation();
-  
+
   // Retrieve the list of Lod from file
   m_LodCount = m_ImageFileReader->GetOverviewsCount();
 
@@ -121,7 +121,7 @@ VectorImageModel
       m_ImageFileReader->GetOutput()->GetLargestPossibleRegion();
 
   // Remember native spacing
-  m_NativeSpacing = m_ImageFileReader->GetOutput()->GetSpacing();
+  m_NativeSpacing = m_ImageFileReader->GetOutput()->GetSignedSpacing();
 
   // qDebug()
   //   << filename
@@ -130,7 +130,7 @@ VectorImageModel
   //   << m_ImageFileReader->GetOutput()->GetOrigin()[ 1 ]
   //   << "\nspacing:" << m_NativeSpacing[ 0 ] << m_NativeSpacing[ 1 ];
 
-  
+
   // Setup GenericRSTransform
   m_ToWgs84 = otb::GenericRSTransform<>::New();
   m_ToWgs84->SetInputDictionary(m_ImageFileReader->GetOutput()->GetMetaDataDictionary());
@@ -140,11 +140,11 @@ VectorImageModel
   //Compute estimated spacing here
   //m_EstimatedGroundSpacing
   m_EstimatedGroundSpacing = m_NativeSpacing;
- 
+
   typedef otb::GroundSpacingImageFunction<VectorImageType> GroundSpacingImageType;
   GroundSpacingImageType::Pointer GroundSpacing = GroundSpacingImageType::New();
   GroundSpacing->SetInputImage(m_ImageFileReader->GetOutput());
-  
+
   if (m_ToWgs84->IsUpToDate())
     {
     if (m_ToWgs84->GetTransformAccuracy() != otb::Projection::UNKNOWN)
@@ -301,7 +301,7 @@ VectorImageModel
     static_cast< VectorImageSettings * const >( buildContext->m_Settings );
 
 
-// Fetch the no data flags if any
+  // Fetch the no data flags if any
   otb::ImageMetadataInterfaceBase::ConstPointer metaData(
     GetMetaDataInterface()
     );
@@ -316,7 +316,7 @@ VectorImageModel
     GetProperties()->SetNoDataEnabled(true);
     GetProperties()->SetNoData(values[0]);
     }
-  
+
   //
   // Step #1: Perform pre-process of AbstractModel::BuildModel()
   // pattern.
@@ -348,7 +348,7 @@ VectorImageModel
   // Remember image properties.
   if( buildContext->m_Properties!=NULL )
     SetProperties( *buildContext->m_Properties );
-  
+
   // Apply settings to child QuicklookModel.
   ApplySettings();
 }
@@ -479,7 +479,7 @@ VectorImageModel::ComputeBestLod( double zoomFactor ) const
 }
 
 /*****************************************************************************/
-unsigned int 
+unsigned int
 VectorImageModel::Closest( double invZoomfactor,
                            unsigned int lodCount )
 {
@@ -554,7 +554,7 @@ VectorImageModel
   // Update m_ImageFileReader
   m_ImageFileReader->SetFileName( QFile::encodeName( lodFilename ).constData() );
   m_ImageFileReader->GetOutput()->UpdateOutputInformation();
-  
+
   // (Always) Update m_Image reference.
   m_Image = m_ImageFileReader->GetOutput();
 }
@@ -594,17 +594,17 @@ VectorImageModel
   IndexType centerIndex;
   centerIndex[0] = GetNativeLargestRegion().GetIndex()[0] + GetNativeLargestRegion().GetSize(0)/2;
   centerIndex[1] = GetNativeLargestRegion().GetIndex()[1] + GetNativeLargestRegion().GetSize(1)/2;
-  
+
   //
-  // Compute the physical coordinates of the center pixel 
+  // Compute the physical coordinates of the center pixel
   PointType centerPoint;
   centerPoint[0] = (centerIndex[0] *   GetNativeSpacing()[0] )  + GetOrigin()[0];
   centerPoint[1] = (centerIndex[1] *   GetNativeSpacing()[1] )  + GetOrigin()[1];
-  
+
   // lat / long
   PointType wgs84;
   wgs84 = GetGenericRSTransform()->TransformPoint(centerPoint);
-  
+
   // get placename
   otb::CoordinateToName::Pointer coordinateToName = otb::CoordinateToName::New();
   coordinateToName->SetLonLat(wgs84);
@@ -612,13 +612,13 @@ VectorImageModel
 
   // get the placename - Country (if any)
   std::ostringstream oss;
-  
+
   std::string placeName = coordinateToName->GetPlaceName();
   std::string countryName = coordinateToName->GetCountryName();
-  
+
   if (placeName != "")
     oss << placeName;
-  
+
   if (countryName != "")
     oss << " - "<< countryName;
 
@@ -792,7 +792,7 @@ VectorImageModel
   // show the current pixel description only if the mouse cursor is
   // under the image
   if( isInsideNativeLargestRegion || 1 )
-    {   
+    {
     //
     // get the physical coordinates
     if (!ToImage()->GetProjectionRef().empty())
@@ -813,13 +813,13 @@ VectorImageModel
 
     // index in current Lod image
     IndexType currentLodIndex;
-    currentLodIndex[0] = (point[ 0 ] - ToImage()->GetOrigin()[0]) / ToImage()->GetSpacing()[0];
-    currentLodIndex[1] = (point[ 1 ] - ToImage()->GetOrigin()[1]) / ToImage()->GetSpacing()[1];
-    
+    currentLodIndex[0] = (point[ 0 ] - ToImage()->GetOrigin()[0]) / ToImage()->GetSignedSpacing()[0];
+    currentLodIndex[1] = (point[ 1 ] - ToImage()->GetOrigin()[1]) / ToImage()->GetSignedSpacing()[1];
+
     //
     // get the LatLong
-    
-    if (!ToImage()->GetProjectionRef().empty()) 
+
+    if (!ToImage()->GetProjectionRef().empty())
       {
       geoVector.push_back(ToStdString(tr("Geographic(exact)")));
       }
@@ -835,23 +835,23 @@ VectorImageModel
     if( ToImage()->GetLargestPossibleRegion().IsInside(currentLodIndex) || 1 )
       {
       // TODO : Is there a better method to detect no geoinfo available ?
-      if (!ToImage()->GetProjectionRef().empty() || ToImage()->GetImageKeywordlist().GetSize() != 0) 
+      if (!ToImage()->GetProjectionRef().empty() || ToImage()->GetImageKeywordlist().GetSize() != 0)
         {
 	assert( !m_ToWgs84.IsNull() );
 
         PointType wgs84;
 
         wgs84 = m_ToWgs84->TransformPoint( point );
-      
+
         ossGeographicLong.precision(6);
         ossGeographicLat.precision(6);
-        
+
         ossGeographicLong << std::fixed << wgs84[0];
         ossGeographicLat << std::fixed << wgs84[1];
 
         geoVector.push_back(ossGeographicLong.str());
         geoVector.push_back(ossGeographicLat.str());
-      
+
         double elev = otb::DEMHandler::Instance()->GetHeightAboveEllipsoid(wgs84[0],wgs84[1]);
 
         if(elev > -32768)
@@ -873,33 +873,33 @@ VectorImageModel
     /*
     else
       {
-      //handle here the case of QL information display. It 
+      //handle here the case of QL information display. It
       //displays geographic info when the user is scrolling over the QL
       //
       // compute the current ql index
 
-      if (!ToImage()->GetProjectionRef().empty() || ToImage()->GetImageKeywordlist().GetSize() != 0) 
+      if (!ToImage()->GetProjectionRef().empty() || ToImage()->GetImageKeywordlist().GetSize() != 0)
         {
-      currentLodIndex[0] = (Xpc - GetQuicklookModel()->ToImage()->GetOrigin()[0]) 
+      currentLodIndex[0] = (Xpc - GetQuicklookModel()->ToImage()->GetOrigin()[0])
         / GetQuicklookModel()->ToImage()->GetSpacing()[0];
-      currentLodIndex[1] = (Ypc - GetQuicklookModel()->ToImage()->GetOrigin()[1]) 
+      currentLodIndex[1] = (Ypc - GetQuicklookModel()->ToImage()->GetOrigin()[1])
         / GetQuicklookModel()->ToImage()->GetSpacing()[1];
 
        PointType wgs84;
        PointType currentLodPoint;
        GetQuicklookModel()->ToImage()->TransformIndexToPhysicalPoint(currentLodIndex, currentLodPoint);
        wgs84 = GetGenericRSTransform()->TransformPoint(currentLodPoint);
-      
+
        ossGeographicLong.precision(6);
        ossGeographicLat.precision(6);
-       
+
        ossGeographicLong << std::fixed << wgs84[0];
        ossGeographicLat << std::fixed << wgs84[1];
 
        //Update geovector with location over QL index
        geoVector.push_back(ossGeographicLong.str());
        geoVector.push_back(ossGeographicLat.str());
-      
+
        double elev = otb::DEMHandler::Instance()->GetHeightAboveEllipsoid(wgs84[0],wgs84[1]);
 
        if(elev > -32768)
@@ -950,16 +950,16 @@ VectorImageModel
       {
       //
       // compute the current ql index
-      currentLodIndex[0] = (Xpc - GetQuicklookModel()->ToImage()->GetOrigin()[0]) 
+      currentLodIndex[0] = (Xpc - GetQuicklookModel()->ToImage()->GetOrigin()[0])
         / GetQuicklookModel()->ToImage()->GetSpacing()[0];
-      currentLodIndex[1] = (Ypc - GetQuicklookModel()->ToImage()->GetOrigin()[1]) 
+      currentLodIndex[1] = (Ypc - GetQuicklookModel()->ToImage()->GetOrigin()[1])
         / GetQuicklookModel()->ToImage()->GetSpacing()[1];
-    
+
       //
       // Get the radiometry form the Ql
       if ( GetQuicklookModel()->ToImage()->GetBufferedRegion().IsInside(currentLodIndex) )
         {
-        currentPixel = 
+        currentPixel =
           GetQuicklookModel()->ToImage()->GetPixel(currentLodIndex);
 
         ossRadio <<"Ql [ ";
@@ -973,7 +973,7 @@ VectorImageModel
     */
     }
 
-  // update band name for the current position 
+  // update band name for the current position
   bandNames = GetBandNames( true );
 
     // qDebug() << bandNames;
diff --git a/Modules/Visualization/MonteverdiGui/include/mvdLayerStackItemModel.h b/Modules/Visualization/MonteverdiGui/include/mvdLayerStackItemModel.h
index 3a3fc21..97f096a 100644
--- a/Modules/Visualization/MonteverdiGui/include/mvdLayerStackItemModel.h
+++ b/Modules/Visualization/MonteverdiGui/include/mvdLayerStackItemModel.h
@@ -157,15 +157,13 @@ public:
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#data
    */
-  
-    QVariant
+  QVariant
     data( const QModelIndex & index, int role = Qt::DisplayRole ) const ITK_OVERRIDE;
 
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#dropMimeData
    */
-  
-    bool
+  bool
     dropMimeData( const QMimeData * data,
                   Qt::DropAction action,
                   int row,
@@ -188,11 +186,11 @@ public:
   QVariant headerData( int section,
                                Qt::Orientation orientation,
                                int role = Qt::DisplayRole ) const ITK_OVERRIDE;
+
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#index
    */
-  
-    QModelIndex
+  QModelIndex
     index( int row,
            int column,
            const QModelIndex & p = QModelIndex() ) const ITK_OVERRIDE;
@@ -200,8 +198,7 @@ public:
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#insertRows
    */
-  
-    bool
+  bool
     insertRows( int row,
                 int count,
                 const QModelIndex & p = QModelIndex() ) ITK_OVERRIDE;
@@ -224,8 +221,7 @@ public:
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#removeRows
    */
-  
-    bool
+  bool
     removeRows( int row,
                 int count,
                 const QModelIndex & p = QModelIndex() ) ITK_OVERRIDE;
@@ -238,8 +234,7 @@ public:
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#setData
    */
-  
-    bool
+  bool
     setData( const QModelIndex & index,
              const QVariant & value,
              int role = Qt::EditRole ) ITK_OVERRIDE;
diff --git a/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetParameterInitializers.h b/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetParameterInitializers.h
index 61d425e..8af787e 100644
--- a/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetParameterInitializers.h
+++ b/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetParameterInitializers.h
@@ -62,6 +62,7 @@
 #include "otbWrapperQtWidgetComplexInputImageParameter.h"
 #include "otbWrapperQtWidgetComplexOutputImageParameter.h"
 #include "otbWrapperQtWidgetParameterFactory.h"
+#include "otbWrapperQtWidgetListEditWidget.h"
 #endif //tag=QT4-boost-compatibility
 
 #include "OTBMonteverdiGUIExport.h"
@@ -135,7 +136,6 @@ class FileSelectionInitializer : public std::unary_function<
   >
 {
 public:
-  inline FileSelectionInitializer();
   inline result_type operator () ( argument_type widget ) const;
 };
 
@@ -152,7 +152,6 @@ class InputImageInitializer : public std::unary_function<
   >
 {
 public:
-  inline InputImageInitializer();
   inline result_type operator () ( argument_type widget ) const;
 };
 
@@ -169,12 +168,7 @@ class InputImageListInitializer : public std::unary_function<
   >
 {
 public:
-  inline InputImageListInitializer( QWidget * view );
-
   inline result_type operator () ( argument_type widget ) const;
-
-private:
-  QWidget * m_View;
 };
 
 /**
@@ -190,7 +184,6 @@ class ComplexInputImageInitializer : public std::unary_function<
   >
 {
 public:
-  inline ComplexInputImageInitializer();
   inline result_type operator () ( argument_type widget ) const;
 };
 
@@ -221,12 +214,7 @@ class InputVectorDataListInitializer : public std::unary_function<
   void >
 {
 public:
-  inline InputVectorDataListInitializer( QWidget * view );
-
   inline result_type operator () ( argument_type widget ) const;
-
-private:
-  QWidget * m_View;
 };
 
 /**
@@ -256,12 +244,7 @@ class InputFilenameListInitializer : public std::unary_function<
   void >
 {
 public:
-  inline InputFilenameListInitializer( QWidget * view );
-
   inline result_type operator () ( argument_type widget ) const;
-
-private:
-  QWidget * m_View;
 };
 
 /**
@@ -334,8 +317,6 @@ class OutputVectorDataInitializer : public std::unary_function<
 {
 public:
   inline result_type operator () ( argument_type widget ) const;
-
-private:
 };
 
 /**
@@ -352,8 +333,6 @@ class OutputFilenameInitializer : public std::unary_function<
 {
 public:
   inline result_type operator () ( argument_type widget ) const;
-
-private:
 };
 
 /**
@@ -370,8 +349,6 @@ class OutputProcessXMLInitializer : public std::unary_function<
 {
 public:
   inline result_type operator () ( argument_type widget ) const;
-
-private:
 };
 
 /**
@@ -387,6 +364,21 @@ public:
   inline result_type operator () ( argument_type widget ) const;
 };
 
+/**
+ * \class ParameterListInitializer
+ *
+ * \ingroup OTBMonteverdiGUI
+ *
+ * \brief WIP.
+ */
+class ParameterListInitializer : public std::unary_function<
+  otb::Wrapper::QtWidgetParameterList *,
+  void >
+{
+public:
+  inline result_type operator () ( argument_type widget ) const;
+};
+
 } // end namespace 'Wrapper'.
 
 } // end namespace 'mvd'.
@@ -422,13 +414,6 @@ namespace Wrapper
 
 /*****************************************************************************/
 inline
-FileSelectionInitializer
-::FileSelectionInitializer()
-{
-}
-
-/*****************************************************************************/
-inline
 FileSelectionInitializer::result_type
 FileSelectionInitializer
 ::operator () ( argument_type widget ) const
@@ -440,13 +425,6 @@ FileSelectionInitializer
 
 /*****************************************************************************/
 inline
-InputImageInitializer
-::InputImageInitializer()
-{
-}
-
-/*****************************************************************************/
-inline
 InputImageInitializer::result_type
 InputImageInitializer
 ::operator () ( argument_type widget ) const
@@ -458,33 +436,13 @@ InputImageInitializer
 
 /*****************************************************************************/
 inline
-InputImageListInitializer
-::InputImageListInitializer( QWidget * view ) :
-  m_View( view )
-{
-}
-
-/*****************************************************************************/
-inline
 InputImageListInitializer::result_type
 InputImageListInitializer
-::operator () ( argument_type widget ) const
+::operator () ( argument_type /* widget */ ) const
 {
-  assert( widget!=NULL );
+  // assert( widget!=NULL );
 
-  QObject::connect(
-    widget, SIGNAL( FileSelectionWidgetAdded( QWidget * ) ),
-    m_View, SLOT( OnFileSelectionWidgetAdded0( QWidget * ) )
-  );
-
-  SetupWidget( widget, FileSelectionInitializer() );
-}
-
-/*****************************************************************************/
-inline
-ComplexInputImageInitializer
-::ComplexInputImageInitializer()
-{
+  // Drop support is done by ParameterListInitializer
 }
 
 /*****************************************************************************/
@@ -511,26 +469,13 @@ InputFilenameInitializer
 
 /*****************************************************************************/
 inline
-InputFilenameListInitializer
-::InputFilenameListInitializer( QWidget * view ) :
-  m_View( view )
-{
-}
-
-/*****************************************************************************/
-inline
 InputFilenameListInitializer::result_type
 InputFilenameListInitializer
-::operator () ( argument_type widget ) const
+::operator () ( argument_type /* widget */) const
 {
-  assert( widget!=NULL );
-
-  QObject::connect(
-    widget, SIGNAL( FileSelectionWidgetAdded( QWidget * ) ),
-    m_View, SLOT( OnFileSelectionWidgetAdded0( QWidget * ) )
-  );
+  // assert( widget!=NULL );
 
-  SetupWidget( widget, FileSelectionInitializer() );
+  // Drop support is done by ParameterListInitializer
 }
 
 /*****************************************************************************/
@@ -546,26 +491,13 @@ InputVectorDataInitializer
 
 /*****************************************************************************/
 inline
-InputVectorDataListInitializer
-::InputVectorDataListInitializer( QWidget * view ) :
-  m_View( view )
-{
-}
-
-/*****************************************************************************/
-inline
 InputVectorDataListInitializer::result_type
 InputVectorDataListInitializer
-::operator () ( argument_type widget ) const
+::operator () ( argument_type /* widget */) const
 {
-  assert( widget!=NULL );
-
-  QObject::connect(
-    widget, SIGNAL( FileSelectionWidgetAdded( QWidget * ) ),
-    m_View, SLOT( OnFileSelectionWidgetAdded0( QWidget * ) )
-  );
+  // assert( widget!=NULL );
 
-  SetupWidget( widget, FileSelectionInitializer() );
+  // Drop support is done by ParameterListInitializer
 }
 
 /*****************************************************************************/
@@ -720,6 +652,34 @@ OutputProcessXMLInitializer
 }
 
 /*****************************************************************************/
+inline
+ParameterListInitializer::result_type
+ParameterListInitializer
+::operator () ( argument_type widget ) const
+{
+  assert( widget!=nullptr );
+
+  QWidget *listWidget = widget->layout()->itemAt(0)->widget();
+
+  assert( listWidget );
+
+  otb::Wrapper::ListEditWidget *castListEdit =
+    dynamic_cast<otb::Wrapper::ListEditWidget *>(listWidget);
+
+  assert(castListEdit);
+
+  QObject* eventFilter = new FilenameDragAndDropEventFilter( castListEdit );
+  castListEdit->installEventFilter(eventFilter);
+  QObject::connect(
+    eventFilter,
+    SIGNAL( FilenameDropped( const QString& ) ),
+    // to:
+    castListEdit,
+    SLOT( OnFilenameDropped( const QString& ) )
+  );
+}
+
+/*****************************************************************************/
 template< typename W >
 void
 SetupForFilenameDrop( W* widget, const char* text )
@@ -796,18 +756,21 @@ SetupOutputFilename( W* widget,
                      const QString& prefix,
                      const QString& extension )
 {
-  QString id( QUuid::createUuid().toString() );
+  if(widget->isEnabled())
+    {
+    QString id( QUuid::createUuid().toString() );
 
-  id.replace( QRegExp( "[\\{|\\}]" ), "" );
+    id.replace( QRegExp( "[\\{|\\}]" ), "" );
 
-  if( prefix!=NULL )
-    id.prepend( "_" );
+    if( prefix!=NULL )
+      id.prepend( "_" );
 
-  widget->SetFileName(
-    dir.absoluteFilePath( prefix + id + extension )
-  );
+    widget->SetFileName(
+      dir.absoluteFilePath( prefix + id + extension )
+    );
 
-  widget->UpdateGUI();
+    widget->UpdateGUI();
+    }
 }
 
 /*****************************************************************************/
@@ -816,9 +779,12 @@ void
 SetupOutputFilename( W * widget,
                      const QDir & dir )
 {
-  widget->SetFileName( dir.path() );
+  if(widget->isEnabled())
+    {
+    widget->SetFileName( dir.path() );
 
-  widget->UpdateGUI();
+    widget->UpdateGUI();
+    }
 }
 
 /*******************************************************************************/
diff --git a/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetView.h b/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetView.h
index ed2aab0..9aba72c 100644
--- a/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetView.h
+++ b/Modules/Visualization/MonteverdiGui/include/mvdQtWidgetView.h
@@ -220,6 +220,8 @@ private slots:
 
   void UpdateMessageAfterApplicationReady(bool val);
 
+  void UpdateMessageAfterExecution(int status);
+
   /**
    */
   void OnExecButtonClicked();
diff --git a/Modules/Visualization/MonteverdiGui/src/mvdApplicationsToolBox.ui b/Modules/Visualization/MonteverdiGui/src/mvdApplicationsToolBox.ui
index 5121277..bc95dd7 100644
--- a/Modules/Visualization/MonteverdiGui/src/mvdApplicationsToolBox.ui
+++ b/Modules/Visualization/MonteverdiGui/src/mvdApplicationsToolBox.ui
@@ -48,7 +48,7 @@
      </attribute>
      <column>
       <property name="text">
-       <string notr="true">Name</string>
+       <string>Name</string>
       </property>
      </column>
      <column>
diff --git a/Modules/Visualization/MonteverdiGui/src/mvdQtWidgetView.cxx b/Modules/Visualization/MonteverdiGui/src/mvdQtWidgetView.cxx
index ff6d14e..3c33015 100644
--- a/Modules/Visualization/MonteverdiGui/src/mvdQtWidgetView.cxx
+++ b/Modules/Visualization/MonteverdiGui/src/mvdQtWidgetView.cxx
@@ -187,36 +187,43 @@ QtWidgetView
   // Create a VBoxLayout with the header, the input widgets, and the footer
   QVBoxLayout *mainLayout = new QVBoxLayout();
   QTabWidget *tab = new QTabWidget();
-  tab->addTab(CreateInputWidgets(), "Parameters");
+  tab->addTab(CreateInputWidgets(), tr("Parameters"));
 
-   
   //otb::Wrapper::QtWidgetProgressReport* prog =  new otb::Wrapper::QtWidgetProgressReport(m_Model);
   //prog->SetApplication(m_Application);
   //tab->addTab(prog, "Progress");
-  tab->addTab(CreateDoc(), "Documentation");
+  tab->addTab(CreateDoc(), tr("Documentation"));
   mainLayout->addWidget(tab);
 
   QTextEdit *log = new QTextEdit();
   connect( m_Model->GetLogOutput(), SIGNAL(NewContentLog(QString)), log, SLOT(append(QString) ) );
-  tab->addTab(log, "Logs");
+  tab->addTab(log, tr("Logs"));
 
-  m_Message = new QLabel("<center><font color=\"#FF0000\">Select parameters</font></center>");
+  m_Message = new QLabel("<center><font color=\"#FF0000\">"+tr("Select parameters")+"</font></center>");
   connect(
     m_Model,
     SIGNAL( SetApplicationReady( bool ) ),
     this, SLOT( UpdateMessageAfterApplicationReady( bool ) )
   );
+  connect(
+    m_Model,
+    SIGNAL(SetProgressReportDone(int)),
+    this, SLOT(UpdateMessageAfterExecution(int)) );
   mainLayout->addWidget(m_Message);
 
   otb::Wrapper::QtWidgetSimpleProgressReport* progressReport =
     new otb::Wrapper::QtWidgetSimpleProgressReport(m_Model);
   progressReport->SetApplication(m_Application);
+
+  QWidget* footer = CreateFooter();
    
   QHBoxLayout *footLayout = new QHBoxLayout;
   footLayout->addWidget(progressReport);
-  footLayout->addWidget(CreateFooter());
+  footLayout->addWidget(footer);
   mainLayout->addLayout(footLayout);
 
+  footLayout->setAlignment(footer, Qt::AlignBottom);
+
   QGroupBox *mainGroup = new QGroupBox();
   mainGroup->setLayout(mainLayout);
 
@@ -345,13 +352,14 @@ QtWidgetView
   assert( widget!=NULL );
 
   SetupWidget( widget, InputFilenameInitializer() );
-  SetupWidget( widget, InputFilenameListInitializer( this ) );
+  //SetupWidget( widget, InputFilenameListInitializer() );
   SetupWidget( widget, InputImageInitializer() );
-  SetupWidget( widget, InputImageListInitializer( this ) );
+  //SetupWidget( widget, InputImageListInitializer() );
   SetupWidget( widget, ComplexInputImageInitializer() );
   SetupWidget( widget, InputProcessXMLInitializer() );
   SetupWidget( widget, InputVectorDataInitializer() );
-  SetupWidget( widget, InputVectorDataListInitializer( this ) );
+  //SetupWidget( widget, InputVectorDataListInitializer() );
+  SetupWidget( widget, ParameterListInitializer() );
 #if defined( OTB_DEBUG )
   SetupWidget( widget, ToolTipInitializer() );
 #endif
@@ -610,9 +618,28 @@ QtWidgetView
     }
   */
 
-  m_Message->setText("<center><font color=\"#FF0000\">Running</font></center>");
-
   emit ExecuteAndWriteOutput();
+
+  m_Message->setText("<center><font color=\"#FF0000\">"+tr("Running")+"</font></center>");
+}
+
+/******************************************************************************/
+void
+QtWidgetView
+::UpdateMessageAfterExecution(int status)
+{
+  if (status >= 0)
+    {
+    m_Message->setText("<center>"
+      "<img src=\":/icons/done\" width=\"16\" height=\"16\" />"
+      "<font color=\"#00A000\">"+tr("Done")+"</font></center>");
+    }
+  else
+    {
+    m_Message->setText("<center>"
+      "<img src=\":/icons/failed\" width=\"16\" height=\"16\" />"
+      "<font color=\"#FF0000\">"+tr("Failed")+"</font></center>");
+    }
 }
 
 /*******************************************************************************/
@@ -621,9 +648,9 @@ QtWidgetView
 ::UpdateMessageAfterApplicationReady( bool val )
 {
   if(val == true)
-    m_Message->setText("<center><font color=\"#00FF00\">Ready to run</font></center>");
+    m_Message->setText("<center><font color=\"#00A000\">"+tr("Ready to run")+"</font></center>");
   else
-    m_Message->setText("<center><font color=\"#FF0000\">Select parameters</font></center>");
+    m_Message->setText("<center><font color=\"#FF0000\">"+tr("Select parameters")+"</font></center>");
 }
 
 /*******************************************************************************/
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperAbstractParameterList.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperAbstractParameterList.h
new file mode 100644
index 0000000..94a0c28
--- /dev/null
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperAbstractParameterList.h
@@ -0,0 +1,88 @@
+/*
+ * 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 otbWrapperAbstractParameterList_h
+#define otbWrapperAbstractParameterList_h
+
+
+#include "otbWrapperParameter.h"
+#include "otbWrapperStringListInterface.h"
+
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+
+/** \class AbstractParameterList
+ *  \brief This class is a base class for list-type parameters
+ *
+ * \ingroup OTBApplicationEngine
+ */
+class OTBApplicationEngine_EXPORT AbstractParameterList :
+    public Parameter,
+    public StringListInterface
+{
+//
+// Public types.
+public:
+  /** Standard class typedef */
+  typedef AbstractParameterList Self;
+  typedef Parameter Superclass;
+
+//
+// Public methods.
+public:
+
+  /** RTTI support */
+  itkTypeMacro( AbstractParameterList, Parameter );
+
+//
+// Protected methods.
+protected:
+  /** Constructor */
+  AbstractParameterList();
+
+  /** Destructor */
+  ~AbstractParameterList() override;
+
+//
+// Private methods.
+private:
+  AbstractParameterList( const Parameter & ) = delete; // purposely not implemented
+  void operator = ( const Parameter & ) = delete; // purposely not implemented
+
+//
+// Protected methods.
+protected:
+
+//
+// Private attributes.
+private:
+
+}; // End class InputImage Parameter
+
+} // End namespace Wrapper
+
+} // End namespace otb
+
+#endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
index cbc0f7f..f97134c 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
@@ -27,7 +27,7 @@
 #include "otbWrapperParameterGroup.h"
 
 #include "otbLogger.h"
-#include "itkTimeProbe.h"
+#include "otbStopwatch.h"
 #include "otbWrapperMacros.h"
 #include "otbWrapperInputImageParameter.h"
 #include "otbWrapperInputImageListParameter.h"
@@ -375,7 +375,7 @@ public:
   /**
    * Enable single selection mode for list view if status in true
    * (default is false).
-   * 
+   *
    * Can be called for types:
    * \li ParameterType_ListView
    */
@@ -455,10 +455,18 @@ public:
    * \li ParameterType_InputImageList
    * \li ParameterType_InputFilenameList
    */
-  std::vector<std::string> GetParameterStringList(std::string parameter);
+  // TODO: Should be rewritten:
+  //
+  // std::size_t
+  // GetParameterStringList( const std::vector< String > & v,
+  //                         const std::string & parameter ) const;
+  //
+  // to avoid useless memory allocations.
+  std::vector< std::string >
+    GetParameterStringList( const std::string & parameter );
 
 
-  /** 
+  /**
    * Set the input image parameter as an ImageBase * instead
    * of filename. Useful to connect pipelines between different
    * application instances.
@@ -480,7 +488,7 @@ public:
    */
   OutputImageParameter::ImageBaseType * GetParameterOutputImage(std::string parameter);
 
-  /** 
+  /**
    * Set the input complex image parameter as an ImageBase * instead
    * of filename. Useful to connect pipelines between different
    * application instances.
@@ -510,7 +518,7 @@ public:
    * \in img The ImageBase * of the image to add
    * \throw itk::Exception if parameter is not found or not an
    * InputImageList parameter
-   */ 
+   */
   void AddImageToParameterInputImageList(std::string parameter, InputImageListParameter::ImageBaseType * img);
 
   /**
@@ -522,7 +530,7 @@ public:
    * \in img The ImageBase * of the image to add
    * \throw itk::Exception if parameter is not found or not an
    * InputImageList parameter or if id is out of bounds
-   */ 
+   */
   void SetNthParameterInputImageList(std::string parameter, const unsigned int &id, InputImageListParameter::ImageBaseType * img);
 
 /**
@@ -530,12 +538,12 @@ public:
    *
    * Can be called for parameter types:
    * \li ParameterType_InputImageList
-   * 
+   *
    * \in parameter The parameter key
    * \in str The string
    * \throw itk::Exception if parameter is not found or not an
    * InputImageList parameter
-   */ 
+   */
   void AddParameterStringList(std::string parameter, const std::string & str);
 
   /**
@@ -543,15 +551,15 @@ public:
    *
    * Can be called for parameter types:
    * \li ParameterType_InputImageList
-   *  
+   *
    * \in parameter The parameter key
    * \in id Position at which to set the ImageBase pointer
    * \in str The string
    * \throw itk::Exception if parameter is not found or not an
    * InputImageList parameter or if id is out of bounds
-   */ 
+   */
   void SetNthParameterStringList(std::string parameter, const unsigned int &id, const std::string& str);
-  
+
 
   /**
    * Clear all images from an InputImageList parameter.
@@ -559,7 +567,7 @@ public:
    * \in parameter The parameter key
    * \throw itk::Exception if parameter is not found or not an
    * InputImageList parameter
-   */ 
+   */
   void ClearParameterInputImageList(std::string parameter);
 
   /**
@@ -568,10 +576,10 @@ public:
    * \return The number of images
    * \throw itk::Exception if parameter is not found or not an
    * InputImageList parameter
-   */ 
+   */
   unsigned int GetNumberOfElementsInParameterInputImageList(std::string parameter);
 
-  
+
   /* Get an image value
    *
    * Can be called for types :
@@ -1008,7 +1016,7 @@ private:
   std::string m_Doclink;
 
   /** Chrono to measure execution time */
-  itk::TimeProbe m_Chrono;
+  otb::Stopwatch m_Chrono;
 
   //rashad:: controls adding of -xml parameter. set to true by default
   bool                              m_HaveInXML;
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx
index 4732064..774dfdb 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx
@@ -49,21 +49,14 @@ ComplexInputImageParameter::GetImage()
       {
       //////////////////////// Filename case:
       // A new valid filename has been given : a reader is created
-      m_PreviousFileName = m_FileName;
       typedef otb::ImageFileReader<TOutputImage> ReaderType;
       typename ReaderType::Pointer reader = ReaderType::New();
       reader->SetFileName(m_FileName);
-      try
-        {
-        reader->UpdateOutputInformation();
-        }
-      catch(itk::ExceptionObject &)
-        {
-        this->ClearValue();
-        }
+      reader->UpdateOutputInformation();
 
       m_Image = reader->GetOutput();
       m_Reader = reader;
+      m_PreviousFileName = m_FileName;
 
       // Pay attention, don't return m_Image because it is a ImageBase...
       return reader->GetOutput();
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
index 37dc143..371c4d4 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h
@@ -85,6 +85,10 @@ public:
   /** Static method to convert pixel type into string */
   static std::string ConvertPixelTypeToString(ComplexImagePixelType type);
 
+  /** Convert a string into a ComplexImagePixelType (returns false if the
+   *  conversion fails) */
+  static bool ConvertStringToPixelType(const std::string &value, ComplexImagePixelType &type);
+
   /** Return true if a filename is set */
   bool HasValue() const ITK_OVERRIDE;
 
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputFilenameListParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputFilenameListParameter.h
index b5ef343..61e1dd6 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputFilenameListParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputFilenameListParameter.h
@@ -21,88 +21,85 @@
 #ifndef otbWrapperInputFilenameListParameter_h
 #define otbWrapperInputFilenameListParameter_h
 
-#include <string>
+
+#include "otbWrapperParameterList.h"
 #include "otbWrapperStringParameter.h"
 
-#include "otbObjectList.h"
 
 namespace otb
 {
+
 namespace Wrapper
 {
+
 /** \class InputFilenameListParameter
  *  \brief This class represents a list of InputFilename parameter
  *
  * \ingroup OTBApplicationEngine
  */
-
-class OTBApplicationEngine_EXPORT InputFilenameListParameter : public Parameter
+class OTBApplicationEngine_EXPORT InputFilenameListParameter :
+    public ParameterList< StringParameter >
 {
+//
+// Public types.
 public:
   /** Standard class typedef */
-  typedef InputFilenameListParameter    Self;
-  typedef Parameter                     Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  typedef otb::ObjectList<StringParameter>  StringParameterListType;
-  typedef StringParameterListType*          StringParameterListPointerType;
+  typedef InputFilenameListParameter Self;
+  typedef ParameterList< StringParameter > Superclass;
 
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
 
+//
+// Public methods.
+public:
   /** Defining ::New() static method */
-  itkNewMacro(Self);
+  itkNewMacro( Self );
 
   /** RTTI support */
-  itkTypeMacro(InputFilenameListParameter, Parameter);
-
-  /** Set file form a list of filenames */
-  bool SetListFromFileName(const std::vector<std::string> & filenames);
+  itkTypeMacro( InputFilenameListParameter, Superclass );
 
-  /** Add null element to lists. */
-  void AddNullElement();
+  /** */
+  Role GetDirection( std::size_t ) const override;
 
-  /** Add a filename from a filename */
-  bool AddFromFileName(const std::string & filename);
+  /** */
+  Role GetDirection() const override;
 
-  /** Set one specific stored filename. */
-  bool SetNthFileName( const unsigned int id, const std::string & filename );
+  /** */
+  const std::string & GetFilenameFilter( std::size_t ) const override;
 
-  /** Get the stored filename list */
-  std::vector<std::string> GetFileNameList() const;
-
- /** Get one specific stored filename. */
-  std::string GetNthFileName( unsigned int i ) const;
-
-  /** Get one list of the stored files. */
-  StringParameterListPointerType GetFileList() const;
-
-  bool HasValue() const ITK_OVERRIDE;
-
-
-  /** Erase one element of the list. */
-  void Erase( unsigned int id );
-
- /** Clear all the list. */
-  void ClearValue() ITK_OVERRIDE;
+  /** */
+  const std::string & GetFilenameFilter() const override;
 
 
+//
+// Protected methods.
 protected:
   /** Constructor */
   InputFilenameListParameter();
 
   /** Destructor */
-  ~InputFilenameListParameter() ITK_OVERRIDE;
+  ~InputFilenameListParameter() override;
 
+  /** */
+  const std::string & ToString( const ParameterType::Pointer & ) const override;
 
-  StringParameterListType::Pointer  m_FilenameList;
+  /** */
+  using Superclass::FromString;
+  const ParameterType::Pointer &
+    FromString( const ParameterType::Pointer &,
+		const std::string & ) const override;
 
+//
+// Private methods.
 private:
-  InputFilenameListParameter(const Parameter &); //purposely not implemented
-  void operator =(const Parameter&); //purposely not implemented
+  InputFilenameListParameter( const Parameter & ); //purposely not implemented
+  void operator = ( const Parameter & ); //purposely not implemented
 
 }; // End class InputFilenameList Parameter
 
 } // End namespace Wrapper
+
 } // End namespace otb
 
 #endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h
index 6b4bf70..889e6d8 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageListParameter.h
@@ -21,104 +21,113 @@
 #ifndef otbWrapperInputImageListParameter_h
 #define otbWrapperInputImageListParameter_h
 
-#include "otbWrapperParameter.h"
+
 #include "otbWrapperInputImageParameter.h"
+#include "otbWrapperParameterList.h"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
+
 /** \class InputImageListParameter
  *  \brief This class represents a list of InputImage parameter
  *
  * \ingroup OTBApplicationEngine
  */
-
-class OTBApplicationEngine_EXPORT InputImageListParameter : public Parameter
+class OTBApplicationEngine_EXPORT InputImageListParameter :
+    public ParameterList< InputImageParameter >
 {
 public:
   /** Standard class typedef */
-  typedef InputImageListParameter           Self;
-  typedef Parameter                     Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
+  typedef InputImageListParameter Self;
+  typedef ParameterList< InputImageParameter > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
 
-  typedef std::vector<InputImageParameter::Pointer> InputImageParameterVectorType;
+  typedef itk::ImageBase< 2 > ImageBaseType;
 
-  typedef itk::ImageBase<2> ImageBaseType;
-  
   /** Defining ::New() static method */
-  itkNewMacro(Self);
+  itkNewMacro( Self );
 
   /** RTTI support */
-  itkTypeMacro(InputImageListParameter, Parameter);
-
-  /** Set image form a list of filename */
-  bool SetListFromFileName(const std::vector<std::string> & filenames);
-
-  /** Add null element to lists. */
-  void AddNullElement();
-
-  /** Add an image from a filename */
-  bool AddFromFileName(const std::string & filename);
-
-  /** Set one specific stored image filename. */
-  bool SetNthFileName( const unsigned int id, const std::string & filename );
-
-  /** Get the stored image filename list */
-  std::vector<std::string> GetFileNameList() const;
-
- /** Get one specific stored image filename. */
-  std::string GetNthFileName( unsigned int i ) const;
+  itkTypeMacro( InputImageListParameter, ParameterList );
 
   /** Get one list of the stored image. WARNING : if the parameter list changes,
    *  the returned image list may become obsolete. You should call
    *  GetImageList() again to make sure your image list is up-to-date. */
-  FloatVectorImageListType* GetImageList() const;
+  const FloatVectorImageListType * GetImageList() const;
+  FloatVectorImageListType * GetImageList();
 
   /** Get one specific stored image. */
-  FloatVectorImageType* GetNthImage(unsigned int i) const;
+  const FloatVectorImageType * GetNthImage( std::size_t ) const;
+  FloatVectorImageType * GetNthImage( std::size_t );
 
   /** Set one specific image. */
-  void SetNthImage(unsigned int i, ImageBaseType * img);
-  
+  void SetNthImage( std::size_t, ImageBaseType * );
+
   /** Set the list of image. */
-  void SetImageList(FloatVectorImageListType* imList);
+  void SetImageList( FloatVectorImageListType * );
 
   /** Add an image to the list. */
-  void AddImage(ImageBaseType* image);
-
-  bool HasValue() const ITK_OVERRIDE;
+  void AddImage( ImageBaseType * );
 
+  /** Clear all the list. */
+  void ClearValue() override;
 
-  /** Erase one element of the list. */
-  void Erase( unsigned int id );
+  /** */
+  using StringListInterface::GetDirection;
+  Role GetDirection() const override;
 
- /** Clear all the list. */
-  void ClearValue() ITK_OVERRIDE;
+  /** */
+  using StringListInterface::GetFilenameFilter;
+  const std::string & GetFilenameFilter() const override;
 
-  /** Retrieve number of elements */
-  unsigned int Size() const;
-  
 protected:
   /** Constructor */
   InputImageListParameter();
 
   /** Destructor */
-  ~InputImageListParameter() ITK_OVERRIDE;
+  ~InputImageListParameter() override;
+
+//
+// Protected methods.
+protected:
+
+  /** */
+  const std::string & ToString( const ParameterType::Pointer & ) const override;
 
+  /** */
+  using Superclass::FromString;
+  const ParameterType::Pointer &
+    FromString( const ParameterType::Pointer &,
+		const std::string & ) const override;
 
+//
+// Private methods.
 private:
-  InputImageListParameter(const Parameter &); //purposely not implemented
-  void operator =(const Parameter&); //purposely not implemented
+  InputImageListParameter( const Parameter & ); //purposely not implemented
+  void operator = ( const Parameter & ); //purposely not implemented
+
+  InputImageParameter::Pointer
+    FromImage( ImageBaseType * );
 
-  InputImageParameterVectorType m_InputImageParameterVector;
+  InputImageParameter::Pointer &
+    FromImage( InputImageParameter::Pointer &, ImageBaseType * );
+
+//
+// Private attributes
+private:
   FloatVectorImageListType::Pointer m_ImageList;
-  
-  
+
+
 }; // End class InputImage Parameter
 
 } // End namespace Wrapper
+
 } // End namespace otb
 
 #endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
index 0cf771a..6ff36ee 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h
@@ -53,8 +53,8 @@ public:
   itkTypeMacro(InputImageParameter, Parameter);
 
   /** Set value from filename */
-  bool SetFromFileName(const std::string& filename);
-  itkGetConstMacro(FileName, std::string);
+  bool SetFromFileName( const std::string & filename );
+  itkGetConstReferenceMacro( FileName, std::string );
 
 
   /** Get the input image as FloatVectorImageType. */
@@ -96,7 +96,7 @@ public:
   /** Generic cast method that will be specified for each image type. */
   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>
@@ -177,7 +177,7 @@ private:
   otbDeclareCastImageMacro(InputImageType, Float##prefix##ImageType) \
   otbDeclareCastImageMacro(InputImageType, Double##prefix##ImageType)
 
-  
+
 /*********************************************************************
 ********************** Image -> Image
 **********************************************************************/
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx
index 64a620f..9db0e61 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx
@@ -33,6 +33,8 @@ namespace Wrapper
 {
 
 
+#define INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION 0
+
 template <class TImageType>
 TImageType*
 InputImageParameter::GetImage()
@@ -45,27 +47,35 @@ InputImageParameter::GetImage()
   // Only one image type can be used
 
   // 2 cases : the user set a filename vs. the user set an image
-  if (m_UseFilename)
+  if( m_UseFilename )
     {
-    if( m_PreviousFileName!=m_FileName && !m_FileName.empty() )
+    if( m_PreviousFileName!=m_FileName &&
+	!m_FileName.empty() )
       {
       //////////////////////// Filename case:
       // A new valid filename has been given : a reader is created
-      m_PreviousFileName = m_FileName;
       typedef otb::ImageFileReader<TImageType> ReaderType;
+
       typename ReaderType::Pointer reader = ReaderType::New();
-      reader->SetFileName(m_FileName);
+
+      reader->SetFileName( m_FileName );
 
       reader->UpdateOutputInformation();
 
       m_Image = reader->GetOutput();
       m_Reader = reader;
 
+      m_PreviousFileName = m_FileName;
+
       // Pay attention, don't return m_Image because it is a ImageBase...
       return reader->GetOutput();
       }
     else
       {
+#if INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION
+      return dynamic_cast< TImageType* >( m_Image.GetPointer() );
+
+#else // INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION
       // In this case, the reader and the image should already be there
       if (m_Image.IsNull())
         {
@@ -83,14 +93,20 @@ InputImageParameter::GetImage()
           itkExceptionMacro("Cannot ask a different image type");
           }
         }
+#endif // INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION
       }
     }
+
   else
     {
     //////////////////////// Image case:
     if (m_Image.IsNull())
       {
+#if INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION
       itkExceptionMacro("No input image or filename detected...");
+#else
+      return nullptr;
+#endif
       }
     else
       {
@@ -160,7 +176,11 @@ InputImageParameter::GetImage()
         }
       else
         {
+#if INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION
         itkExceptionMacro("Unknown image type");
+#else
+	return nullptr;
+#endif
         }
       }
     }
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataListParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataListParameter.h
index 423d2ca..52d4ac3 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataListParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataListParameter.h
@@ -21,78 +21,65 @@
 #ifndef otbWrapperInputVectorDataListParameter_h
 #define otbWrapperInputVectorDataListParameter_h
 
-#include "otbVectorDataFileReader.h"
 
-#include "otbWrapperParameter.h"
-#include "otbObjectList.h"
+#include "otbWrapperInputVectorDataParameter.h"
+#include "otbWrapperParameterList.h"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
+
 /** \class InputVectorDataListParameter
  *  \brief This class represents a list of VectorData parameter
  *
  * \ingroup OTBApplicationEngine
  */
-
-class OTBApplicationEngine_EXPORT InputVectorDataListParameter : public Parameter
+class OTBApplicationEngine_EXPORT InputVectorDataListParameter :
+    public ParameterList< InputVectorDataParameter >
 {
 public:
   /** Standard class typedef */
-  typedef InputVectorDataListParameter           Self;
-  typedef Parameter                     Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  typedef otb::VectorDataFileReader<VectorDataType>  VectorDataFileReaderType;
-  typedef otb::ObjectList<VectorDataFileReaderType>  VectorDataFileReaderListType;
+  typedef InputVectorDataListParameter Self;
+  typedef ParameterList< InputVectorDataParameter > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
 
   /** Defining ::New() static method */
-  itkNewMacro(Self);
+  itkNewMacro( Self );
 
   /** RTTI support */
-  itkTypeMacro(InputVectorDataListParameter, Parameter);
-
-  /** Set image form a list of filename */
-  bool SetListFromFileName(const std::vector<std::string> & filenames);
-
-  /** Add null element to lists. */
-  void AddNullElement();
-
-  /** Add an image from a filename */
-  bool AddFromFileName(const std::string & filename);
-
-  /** Set one specific stored image filename. */
-  bool SetNthFileName( const unsigned int id, const std::string & filename );
-
-
-  /** Get the stored image filename list */
-  std::vector<std::string> GetFileNameList() const;
-
- /** Get one specific stored image filename. */
-  std::string GetNthFileName( unsigned int i ) const;
+  itkTypeMacro( InputVectorDataListParameter, ParameterList );
 
   /** Get one list of the stored image. */
-  VectorDataListType* GetVectorDataList() const;
+  const VectorDataListType * GetVectorDataList() const;
+  VectorDataListType * GetVectorDataList();
 
   /** Get one specific stored image. */
-  VectorDataType* GetNthVectorData(unsigned int i) const;
+  //
+  // FIXME: Definition is not const-correct because
+  // InputVectorDataParameter::GetVectorData() is not const-correct!
+  const VectorDataType * GetNthVectorData( std::size_t );
 
   /** Set the list of image. */
-  void SetVectorDataList(VectorDataListType* vdList);
+  void SetVectorDataList( VectorDataListType * );
 
   /** Add an image to the list. */
-  void AddVectorData(VectorDataType* image);
-
-  bool HasValue() const ITK_OVERRIDE;
+  void AddVectorData( VectorDataType * );
 
+ /** Clear all the list. */
+  void ClearValue() override;
 
-  /** Erase one element of the list. */
-  void Erase( unsigned int id );
+  /** */
+  using StringListInterface::GetDirection;
+  virtual Role GetDirection() const override;
 
- /** Clear all the list. */
-  void ClearValue() ITK_OVERRIDE;
+  /** */
+  using StringListInterface::GetFilenameFilter;
+  const std::string & GetFilenameFilter() const override;
 
 
 protected:
@@ -100,18 +87,39 @@ protected:
   InputVectorDataListParameter();
 
   /** Destructor */
-  ~InputVectorDataListParameter() ITK_OVERRIDE;
+  ~InputVectorDataListParameter() override;
 
-  VectorDataListType::Pointer m_VectorDataList;
-  VectorDataFileReaderListType::Pointer  m_ReaderList;
+  /** */
+  const std::string & ToString( const ParameterType::Pointer & ) const override;
+
+  /** */
+  using Superclass::FromString;
+  const ParameterType::Pointer &
+    FromString( const ParameterType::Pointer &,
+		const std::string & ) const override;
+
+private:
+  // Purposely not implemented
+  InputVectorDataListParameter( const Parameter & );
+
+  // Purposely not implemented
+  void operator = ( const Parameter & );
+
+  InputVectorDataParameter::Pointer
+    FromVectorData( VectorDataType * );
 
+  InputVectorDataParameter::Pointer &
+    FromVectorData( InputVectorDataParameter::Pointer &, VectorDataType * );
+
+//
+// Private attributes
 private:
-  InputVectorDataListParameter(const Parameter &); //purposely not implemented
-  void operator =(const Parameter&); //purposely not implemented
+  VectorDataListType::Pointer m_VectorDataList;
 
 }; // End class InputVectorDataList Parameter
 
 } // End namespace Wrapper
+
 } // End namespace otb
 
 #endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataParameter.h
index dded12d..f84a383 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputVectorDataParameter.h
@@ -55,9 +55,10 @@ public:
 
   /** Set value from filename */
   bool SetFromFileName(const std::string& filename);
-  itkGetConstMacro(FileName, std::string);
+  itkGetConstReferenceMacro( FileName, std::string );
 
-  VectorDataType* GetVectorData();
+  const VectorDataType * GetVectorData() const;
+  VectorDataType * GetVectorData();
 
   void SetVectorData(VectorDataType* vectorData);
 
@@ -78,6 +79,8 @@ protected:
 
   std::string m_FileName;
 
+  std::string m_PreviousFileName;
+
 private:
   InputVectorDataParameter(const Parameter &); //purposely not implemented
   void operator =(const Parameter&); //purposely not implemented
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
index adbf9d1..b420299 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h
@@ -86,6 +86,10 @@ public:
   /** Static method to convert pixel type into string */
   static std::string ConvertPixelTypeToString(ImagePixelType type);
 
+  /** Converts a string into a pixel type (returns false if the conversion
+   *  fails) */
+  static bool ConvertStringToPixelType(const std::string &value, ImagePixelType &type);
+
   /** Return true if a filename is set */
   bool HasValue() const ITK_OVERRIDE;
 
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h
index 772ee60..236411f 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameter.h
@@ -70,9 +70,6 @@ public:
   typedef itk::SmartPointer<Self>       Pointer;
   typedef itk::SmartPointer<const Self> ConstPointer;
 
-  /** Defining ::New() static method */
-  itkNewMacro(Self);
-
   /** RTTI support */
   itkTypeMacro(Parameter, itk::Object);
 
@@ -86,7 +83,7 @@ public:
   itkSetStringMacro(Description);
 
   /** Get the parameter description */
-  itkGetStringMacro(Description);
+  itkGetConstReferenceMacro( Description, std::string );
 
   /** Set the parameter key */
   itkSetStringMacro(Key);
@@ -151,14 +148,11 @@ public:
   {
   }
 
-  virtual bool HasValue() const
-  {
-    itkExceptionMacro(<<"HasValue() method must be re-implemented by sub-classes.");
-  }
+  virtual bool HasValue() const = 0;
 
   virtual bool HasUserValue() const
   {
-    return HasValue() && m_UserValue;
+    return this->HasValue() && m_UserValue;
   }
 
   virtual void SetUserValue(bool isUserValue)
@@ -168,7 +162,8 @@ public:
 
   virtual void ClearValue()
   {
-    itkExceptionMacro(<<"ClearValue() method must be re-implemented by sub-classes.");
+    SetActive( false );
+    Modified();
   }
 
   /** Set/Get the root of the current parameter (direct parent) */
@@ -207,7 +202,7 @@ public:
   /** Store the state of the check box relative to this parameter (TO
     * BE MOVED to QtWrapper Model )
     */
-  virtual bool IsChecked()
+  virtual bool IsChecked() const
   {
     return m_IsChecked;
   }
@@ -220,23 +215,23 @@ public:
 
 protected:
   /** Constructor */
-  Parameter() : m_Name(""),
-                m_Description(""),
-                m_Key(""),
-                m_Mandatory(true),
-                m_Active(false),
-                m_UserValue(false),
-                m_AutomaticValue(false),
-                m_DefaultValueMode(DefaultValueMode_UNKNOWN),
-                m_UserLevel(UserLevel_Basic),
-                m_Role(Role_Input),
-                m_Root(this),
-                m_IsChecked(false)
+  Parameter() :
+    m_Name( "" ),
+    m_Description( "" ),
+    m_Key( "" ),
+    m_Mandatory( true ),
+    m_Active( false ),
+    m_UserValue( false ),
+    m_AutomaticValue( false ),
+    m_DefaultValueMode( DefaultValueMode_UNKNOWN ),
+    m_UserLevel( UserLevel_Basic ),
+    m_Role( Role_Input ),
+    m_Root( this ),
+    m_IsChecked( false )
   {}
 
   /** Destructor */
-  ~Parameter() ITK_OVERRIDE
-  {}
+  ~Parameter() ITK_OVERRIDE {}
 
   /** Name of the parameter */
   std::string                        m_Name;
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.h
new file mode 100644
index 0000000..2c9c699
--- /dev/null
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.h
@@ -0,0 +1,205 @@
+/*
+ * 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 otbWrapperParameterList_h
+#define otbWrapperParameterList_h
+
+
+#include "otbWrapperAbstractParameterList.h"
+#include "otbWrapperStringListInterface.h"
+
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+
+/** \class ParameterList
+ *  \brief This class represents a InputImage parameter
+ *
+ * \ingroup OTBApplicationEngine
+ */
+template< typename T >
+class ParameterList :
+    public AbstractParameterList
+{
+//
+// Public types.
+public:
+  /** Standard class typedef */
+  typedef ParameterList Self;
+  typedef AbstractParameterList Superclass;
+
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
+
+  /** Custom types */
+  typedef T ParameterType;
+  typedef std::vector< typename T::Pointer > ParameterVector;
+
+//
+// Public methods.
+public:
+
+  /** RTTI support */
+  itkTypeMacro( ParameterList, AbstractParameterList );
+
+  /** */
+  typename ParameterVector::const_iterator begin() const;
+
+  /** */
+  typename ParameterVector::const_iterator end() const;
+
+  /** */
+  void ClearValue() override;
+
+  /** */
+  bool HasValue() const override;
+
+  /** Set file form a list of filenames */
+  void SetListFromFileName( const StringVector & ) override;
+
+  /** */
+  void InsertNullElement( std::size_t = -1 ) override;
+
+  /** Add a filename from a filename */
+  void AddFromFileName( const std::string & ) override;
+
+  /** */
+  void Insert( const std::string &, std::size_t = -1 ) override;
+
+  /** Set one specific stored filename. */
+  void SetNthFileName( std::size_t, const std::string & ) override;
+
+  /** */
+  std::size_t SetStrings( const StringVector & );
+
+  /** */
+  std::size_t GetStrings( StringVector & ) const override;
+
+  /** Get the stored image filename list */
+  StringVector GetFileNameList() const override;
+
+ /** Get one specific stored image filename. */
+  const std::string & GetNthFileName( std::size_t ) const override;
+
+  /** */
+  const std::string & GetToolTip( std::size_t ) const override;
+
+  /** */
+  using StringListInterface::Erase;
+  void Erase( std::size_t start, std::size_t count ) override;
+
+  /** Retrieve number of elements */
+  std::size_t Size() const override;
+
+  /** */
+  bool IsActive( size_t ) const override;
+
+  /** */
+  void Swap( std::size_t, std::size_t ) override;
+
+//
+// Protected methods.
+protected:
+  /** Constructor */
+  ParameterList();
+
+  /** Destructor */
+  ~ParameterList() override;
+
+//
+// Private methods.
+private:
+  // ParameterList( const Parameter & ); // purposely not implemented
+  // void operator = ( const Parameter & ); // purposely not implemented
+
+//
+// Protected methods.
+protected:
+  /** Utility method to factorize some code */
+  template< typename L, typename From, typename Get >
+    void
+    SetObjectList( L &,  const L &, From, Get );
+
+  /** Utility method to factorize some code */
+  template< typename L, typename Get >
+    typename L::ObjectType *
+    GetObjectList( L &, Get );
+
+  /** */
+  template< typename L, typename Get >
+    const typename L::ObjectType *
+    GetObjectList( L &, Get ) const;
+
+  /** */
+  template< typename D, typename From >
+    void AddData( D *, From );
+
+  /** */
+  template< typename D, typename Set >
+    typename T::Pointer
+    FromData( D *,
+	      Set,
+	      const std::string & description = std::string() );
+
+  /** */
+  template< typename D, typename Set >
+    typename T::Pointer &
+    FromData( typename T::Pointer &,
+	      D *,
+	      Set,
+	      const std::string & description = std::string() );
+
+  /** ParameterType::ValueType -> std::string protocol */
+  virtual
+    const std::string &
+    ToString( const typename ParameterType::Pointer & ) const = 0;
+
+  /** std::string -> ParameterType::ValueType protocol */
+  virtual
+    const typename ParameterType::Pointer &
+    FromString( const typename ParameterType::Pointer &,
+		const std::string & ) const = 0;
+
+  /** Utility method to use std::string -> conversion in lambdas. */
+  virtual
+    typename ParameterType::Pointer
+    FromString( const std::string & ) const;
+
+//
+// Protected attributes.
+protected:
+  /** */
+  ParameterVector m_Parameters;
+
+}; // End class InputImage Parameter
+
+} // End namespace Wrapper
+
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+# include "otbWrapperParameterList.txx"
+#endif
+
+#endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.txx
new file mode 100644
index 0000000..da857bc
--- /dev/null
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperParameterList.txx
@@ -0,0 +1,487 @@
+/*
+ * 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 otbWrapperParameterList_txx
+#define otbWrapperParameterList_txx
+
+
+#include <algorithm>
+#include <iterator>
+
+#include "otbCast.h"
+#include "otbWrapperParameterList.h"
+
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+
+/*****************************************************************************/
+template< typename T >
+ParameterList< T >
+::ParameterList() :
+  AbstractParameterList(),
+  m_Parameters()
+{
+}
+
+/*****************************************************************************/
+template< typename T >
+ParameterList< T >
+::~ParameterList()
+{
+}
+
+/*****************************************************************************/
+template< typename T >
+typename ParameterList< T >::ParameterVector::const_iterator
+ParameterList< T >
+::begin() const
+{
+  return m_Parameters.begin();
+}
+
+/*****************************************************************************/
+template< typename T >
+typename ParameterList< T >::ParameterVector::const_iterator
+ParameterList< T >
+::end() const
+{
+  return m_Parameters.end();
+}
+
+/*****************************************************************************/
+template< typename T >
+bool
+ParameterList< T >
+::HasValue() const
+{
+  return
+    Size()>0
+    &&
+    std::all_of(
+      begin(),
+      end(),
+      []( auto p ) -> bool
+      {
+        assert( p!=nullptr );
+        return p && p->HasValue();
+      }
+    );
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::ClearValue()
+{
+  m_Parameters.clear();
+
+  Superclass::ClearValue();
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::SetListFromFileName( const StringVector & strings )
+{
+  this->SetStrings(strings);
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::InsertNullElement( std::size_t index )
+{
+  m_Parameters.insert(
+    index>=m_Parameters.size()
+    ? m_Parameters.end()
+    : m_Parameters.begin() + index,
+    typename T::Pointer()
+  );
+
+  SetActive( false );
+
+  Modified();
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::AddFromFileName( const std::string & filename )
+{
+  assert( !filename.empty() );
+
+  typename T::Pointer p( T::New() );
+
+  FromString( p, filename );
+
+  m_Parameters.push_back( p );
+
+  assert( !m_Parameters.back().IsNull() );
+
+  SetActive( true );
+
+  Modified();
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::Insert( const std::string & filename, std::size_t index )
+{
+  typename T::Pointer p( T::New() );
+
+  FromString( p, filename );
+
+  m_Parameters.insert( m_Parameters.begin() + index, p );
+
+  assert( !m_Parameters.back().IsNull() );
+
+  SetActive( true );
+
+  Modified();
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::SetNthFileName( std::size_t i,
+		  const std::string & filename )
+{
+  assert( i<m_Parameters.size() );
+  assert( !m_Parameters[ i ].IsNull() );
+
+  // Should throw exception when failed.
+  FromString( m_Parameters[ i ], filename );
+
+  SetActive( true );
+
+  Modified();
+}
+
+/*****************************************************************************/
+template< typename T >
+std::size_t
+ParameterList< T >
+::SetStrings( const StringVector & strings )
+{
+  // First clear previous file chosen
+  ClearValue();
+
+  if ( !strings.empty() )
+    {
+    std::transform(
+      strings.begin(),
+      strings.end(),
+      std::back_inserter( m_Parameters ),
+      [ this ]( auto s ) -> auto
+      {
+        return this->FromString( s );
+      }
+    );
+
+    SetActive( true );
+    Modified();
+    }
+  return strings.size();
+}
+
+/*****************************************************************************/
+template< typename T >
+std::size_t
+ParameterList< T >
+::GetStrings( StringVector & strings ) const
+{
+  std::transform(
+    begin(),
+    end(),
+    std::back_inserter( strings ),
+    [ this ]( auto p ) -> auto
+    {
+      return this->ToString( p );
+    }
+  );
+
+  return m_Parameters.size();
+}
+
+/*****************************************************************************/
+template< typename T >
+StringListInterface::StringVector
+ParameterList< T >
+::GetFileNameList() const
+{
+  StringVector filenames;
+
+  GetStrings( filenames );
+
+  return filenames;
+}
+
+/*****************************************************************************/
+template< typename T >
+const std::string &
+ParameterList< T >
+::GetNthFileName( std::size_t i ) const
+{
+  assert( i<m_Parameters.size() );
+
+  return ToString( m_Parameters[ i ] );
+}
+
+/*****************************************************************************/
+template< typename T >
+const std::string &
+ParameterList< T >
+::GetToolTip( std::size_t i ) const
+{
+  assert( i<m_Parameters.size() );
+  assert( !m_Parameters[ i ].IsNull() );
+
+  return m_Parameters[ i ]->GetDescription();
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::Erase( std::size_t start, std::size_t count )
+{
+  assert( start<m_Parameters.size() );
+  assert( start+count<=m_Parameters.size() );
+
+  m_Parameters.erase(
+    m_Parameters.begin() + start,
+    m_Parameters.begin() + start + count
+  );
+
+  Modified();
+}
+
+/*****************************************************************************/
+template< typename T >
+std::size_t
+ParameterList< T >
+::Size() const
+{
+  return m_Parameters.size();
+}
+
+/*****************************************************************************/
+template< typename T >
+bool
+ParameterList< T >
+::IsActive( std::size_t i ) const
+{
+  assert( i<m_Parameters.size() );
+  assert( !m_Parameters[ i ].IsNull() );
+
+  return m_Parameters[ i ]->GetActive();
+}
+
+/*****************************************************************************/
+template< typename T >
+void
+ParameterList< T >
+::Swap( std::size_t i1, std::size_t i2 )
+{
+  assert( !m_Parameters.empty() );
+
+  auto clamp = [ this ]( std::size_t i ) -> std::size_t
+  {
+    return
+      i>=m_Parameters.size()
+      ? m_Parameters.size() - 1
+      : i;
+  };
+
+  std::swap(
+    m_Parameters[ clamp( i1 ) ],
+    m_Parameters[ clamp( i2 ) ]
+  );
+}
+
+/*****************************************************************************/
+template< typename T >
+template< typename L, typename From, typename Get >
+void
+ParameterList< T >
+::SetObjectList( L & this_list,
+		 const L & list,
+		 From from,
+		 Get get )
+{
+  // Force update of input-list elements.
+  for( std::size_t i=0; i<list.Size(); i++ )
+  {
+    assert( list.GetNthElement( i )!=nullptr );
+
+    list.GetNthElement( i )->UpdateOutputInformation();
+  }
+
+  // Clear previous target list.
+  ClearValue();
+
+  for( std::size_t i=0; i<list.Size(); i++ )
+    {
+    assert( list.GetNthElement( i )!=nullptr );
+
+    typename T::Pointer parameter;
+
+    from( parameter, list.GetNthElement( i ) );
+
+    m_Parameters.push_back( parameter );
+
+    assert( get( parameter )!=nullptr );
+
+    this_list.PushBack( get( parameter ) );
+    }
+
+  SetActive( true );
+
+  Modified();
+}
+
+/*****************************************************************************/
+template< typename T >
+template< typename L, typename Get >
+typename L::ObjectType *
+ParameterList< T >
+::GetObjectList( L & this_list, Get get )
+{
+  assert( this_list );
+
+  this_list->Clear();
+
+  std::for_each(
+    begin(),
+    end(),
+    [ this_list, get ]( auto parameter ) -> void
+    {
+      assert( parameter );
+      assert( parameter==otb::DynamicCast< T >( parameter ) );
+
+      assert( get( DynamicCast< T >( parameter ) ) );
+
+      this_list->PushBack(
+	get(
+	  DynamicCast< T >( parameter )
+	)
+      );
+    }
+  );
+
+  return this_list;
+}
+
+/*****************************************************************************/
+template< typename T >
+template< typename L, typename Get >
+const typename L::ObjectType *
+ParameterList< T >
+::GetObjectList( L & this_list, Get get ) const
+{
+  return
+    const_cast< ParameterList< T > * >( this )
+    ->GetObjectList( this_list, get );
+}
+
+/*****************************************************************************/
+template< typename T >
+template< typename D, typename From >
+void
+ParameterList< T >
+::AddData( D * data, From from )
+{
+  assert( data!=nullptr );
+
+  // Check input availability
+  data->UpdateOutputInformation();
+
+  // Build & add parameter.
+  m_Parameters.push_back( from( data ) );
+
+  Modified();
+}
+
+/*****************************************************************************/
+template< typename T >
+template< typename D, typename Set >
+typename T::Pointer
+ParameterList< T >
+::FromData( D * data,
+	    Set set,
+	    const std::string & description )
+{
+  assert( data!=nullptr );
+
+  typename T::Pointer p;
+
+  return From( p, data, set, description );
+}
+
+/*****************************************************************************/
+template< typename T >
+template< typename D, typename Set >
+typename T::Pointer &
+ParameterList< T >
+::FromData( typename T::Pointer & parameter,
+	    D * data,
+	    Set set,
+	    const std::string & description )
+{
+  assert( data!=nullptr );
+
+  parameter = T::New();
+
+  set( parameter, data );
+  parameter->SetDescription( description );
+
+  return parameter;
+}
+
+/*****************************************************************************/
+template< typename T >
+typename T::Pointer
+ParameterList< T >
+::FromString( const std::string & s ) const
+{
+  typename T::Pointer parameter( T::New() );
+
+  return FromString( parameter, s );
+}
+
+} // End namespace Wrapper
+
+
+} // End namespace otb
+
+
+#endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperProxyParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperProxyParameter.h
index 1a93c24..c7594f8 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperProxyParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperProxyParameter.h
@@ -70,6 +70,11 @@ public:
     return m_Target;
     }
 
+  bool HasValue() const override
+    {
+    return m_Target.first.IsNotNull();
+    }
+
 protected:
   ProxyParameter() {}
   ~ProxyParameter() ITK_OVERRIDE {}
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringListInterface.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringListInterface.h
new file mode 100644
index 0000000..dd84632
--- /dev/null
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringListInterface.h
@@ -0,0 +1,126 @@
+/*
+ * 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 otbWrapperStringListInterface_h
+#define otbWrapperStringListInterface_h
+
+
+#include <string>
+#include <vector>
+
+#include "OTBApplicationEngineExport.h"
+
+#include "otbWrapperTypes.h"
+
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+/** \class StringListInterface
+ *  \brief This class represents a list of InputFilename parameter
+ *
+ * \ingroup OTBApplicationEngine
+ */
+class OTBApplicationEngine_EXPORT StringListInterface
+{
+public:
+  /** */
+  typedef std::vector< std::string > StringVector;
+
+  /** Set file form a list of filenames */
+  virtual void SetListFromFileName( const StringVector & ) = 0;
+
+  /** Add null element to lists. */
+  virtual void AddNullElement();
+
+  /** */
+  virtual void InsertNullElement( std::size_t = -1 ) = 0;
+
+  /** Add a filename from a filename */
+  virtual void AddFromFileName( const std::string & ) = 0;
+
+  /** */
+  virtual void Insert( const std::string & filename, std::size_t = -1 ) = 0;
+
+  /** Set one specific stored filename. */
+  virtual void SetNthFileName( std::size_t, const std::string & ) = 0;
+
+  /** */
+  virtual std::size_t SetStrings( const StringVector & );
+
+  /** */
+  virtual std::size_t GetStrings( StringVector & ) const;
+
+  /** Get the stored filename list */
+  virtual StringVector GetFileNameList() const = 0;
+
+  /** Get one specific stored filename. */
+  virtual const std::string & GetNthFileName( std::size_t i ) const = 0;
+
+  /** Erase one element of the list. */
+  virtual void Erase( std::size_t id );
+
+  /** */
+  virtual void Erase( std::size_t start, std::size_t count ) = 0;
+
+  /** Retrieve number of elements */
+  virtual std::size_t Size() const = 0;
+
+  /** */
+  virtual bool IsActive( std::size_t ) const = 0;
+
+  /** */
+  virtual const std::string & GetToolTip( std::size_t ) const = 0;
+
+  /** */
+  virtual void Swap( std::size_t, std::size_t ) = 0;
+
+  /** */
+  virtual Role GetDirection( std::size_t ) const;
+
+  /** */
+  virtual Role GetDirection() const = 0;
+
+  /** */
+  virtual const std::string & GetFilenameFilter( std::size_t ) const;
+
+  /** */
+  virtual const std::string & GetFilenameFilter() const;
+
+  /** */
+  virtual bool IsFilename() const;
+
+protected:
+  /** Constructor */
+  StringListInterface() {};
+
+private:
+
+};
+
+} // End namespace Wrapper
+
+} // End namespace otb
+
+
+#endif // otbWrapperStringListInterface_h
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringListParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringListParameter.h
index c036828..a01a11d 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringListParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringListParameter.h
@@ -21,11 +21,15 @@
 #ifndef otbWrapperStringListParameter_h
 #define otbWrapperStringListParameter_h
 
-#include <string>
-#include "otbWrapperParameter.h"
+
+#include "otbWrapperParameterList.h"
+#include "otbWrapperStringParameter.h"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
 
@@ -34,114 +38,79 @@ namespace Wrapper
  *
  * \ingroup OTBApplicationEngine
  */
-class OTBApplicationEngine_EXPORT StringListParameter
-  : public Parameter
+class OTBApplicationEngine_EXPORT StringListParameter :
+    public ParameterList< StringParameter >
 {
+//
+// Public methods.
 public:
   /** Standard class typedef */
   typedef StringListParameter Self;
-  typedef Parameter Superclass;
-  typedef itk::SmartPointer<Self> Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
+  typedef ParameterList< StringParameter > Superclass;
+  typedef itk::SmartPointer< Self > Pointer;
+  typedef itk::SmartPointer< const Self > ConstPointer;
 
-  typedef std::vector<std::string> StringListType;
+  typedef StringListInterface::StringVector StringListType;
 
   /** Defining ::New() static method */
-  itkNewMacro(Self)
-;
+  itkNewMacro( Self );
 
   /** RTTI support */
-  itkTypeMacro(StringListParameter, Parameter)
-;
+  itkTypeMacro( StringListParameter, ParameterList );
 
   /** Set the value */
-  void SetValue(StringListType sList)
-  {
-    m_Value.clear();
-    for(unsigned int i=0; i<sList.size(); i++)
-      {
-      this->AddString(sList[i]);
-      }
-  }
-
-  void AddString(std::string value)
-  {
-    if(!value.empty())
-      {
-      m_Value.push_back(value);
-      if(!this->GetActive())
-        {
-        this->SetActive(true);
-        }
-      }
-  }
+  void SetValue( const StringListInterface::StringVector & );
 
-  /** Get the value */
-  StringListType GetValue() const
-  {
-    return m_Value;
-  }
+  /** */
+  void AddString( const std::string & value );
 
   /** Get the value */
-  std::string GetNthElement(unsigned int i) const
-  {
-    if (m_Value.size() < i)
-      {
-      itkExceptionMacro( "Invalid index "<<i<<" the string list has only "<<m_Value.size()<<" elements...")
-      }
+  StringListInterface::StringVector GetValue() const;
 
-    return m_Value[i];
-  }
+  /** Get the value */
+  const std::string & GetNthElement( std::size_t ) const;
 
   /** Get the value */
-  void SetNthElement(unsigned int i, std::string value)
-  {
-    if (m_Value.size() < i)
-      {
-      itkExceptionMacro( "Invalid index "<<i<<" the string list has only "<<m_Value.size()<<" elements...")
-      }
-    m_Value[i] = value;
-  }
-
-  bool HasValue() const ITK_OVERRIDE
-  {
-    return !m_Value.empty();
-  }
-
-  void ClearValue() ITK_OVERRIDE
-  {
-    m_Value.clear();
-  }
-
-  void AddNullElement()
-  {
-    m_Value.push_back("");
-    SetActive(false);
-    this->Modified();
-  }
+  void SetNthElement( std::size_t, const std::string & );
 
+  /** */
+  using StringListInterface::GetDirection;
+  Role GetDirection() const override;
+
+  /** */
+  bool IsFilename() const override;
+
+//
+// Protected methods.
 protected:
   /** Constructor */
-  StringListParameter()
-  {
-    this->SetName("String List");
-    this->SetKey("strList");
-  }
+  StringListParameter();
 
   /** Destructor */
-  ~StringListParameter() ITK_OVERRIDE
-  {
-  }
+  ~StringListParameter() override;
+
+  /** */
+  const std::string & ToString( const ParameterType::Pointer & ) const override;
 
-  StringListType m_Value;
+  /** */
+  using Superclass::FromString;
+  const ParameterType::Pointer &
+    FromString( const ParameterType::Pointer &,
+		const std::string & ) const override;
 
+//
+// Private methods.
 private:
-  StringListParameter(const StringListParameter &); //purposely not implemented
-  void operator =(const StringListParameter&); //purposely not implemented
+  // Purposely not implemented
+  StringListParameter ( const StringListParameter & );
+
+  // Purposely not implemented
+  void operator = ( const StringListParameter & );
 
 }; // End class Parameter
 
 } // End namespace Wrapper
+
 } // End namespace otb
 
 #endif
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringParameter.h
index a8f7943..9c8b1e8 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringParameter.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperStringParameter.h
@@ -51,14 +51,14 @@ public:
   itkTypeMacro(StringParameter, Parameter);
 
   /** Set the value */
-  void SetValue( std::string value)
+  void SetValue( const std::string & value )
   {
     m_Value = value;
-    SetActive(true);
+    SetActive( true );
   }
 
   /** Get the value */
-  std::string GetValue() const
+  const std::string & GetValue() const
   {
     return m_Value;
   }
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTags.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTags.h
index ace5277..6b5e386 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTags.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTags.h
@@ -49,6 +49,7 @@ static const std::string SAR="SAR";
 static const std::string Stereo="Stereo";
 static const std::string Segmentation="Segmentation";
 static const std::string Vector="Vector Data Manipulation";
+static const std::string Deprecated="Deprecated";
 
 } // end namespace Wrappers
 } // end namespace Tags
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
index f00cb08..63dafb6 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h
@@ -87,7 +87,7 @@ typedef enum
 
 typedef enum
 {
-  Role_Input,
+  Role_Input = 0,
   Role_Output
 } Role;
 
diff --git a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt
index 3251a05..343f9db 100644
--- a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt
+++ b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt
@@ -18,7 +18,7 @@
 # limitations under the License.
 #
 
-set(OTBApplicationEngine_SRC
+set( OTBApplicationEngine_SRC
   otbWrapperApplicationHtmlDocGenerator.cxx
   otbWrapperComplexOutputImageParameter.cxx
   otbWrapperInputVectorDataListParameter.cxx
@@ -48,11 +48,15 @@ set(OTBApplicationEngine_SRC
   otbWrapperApplicationRegistry.cxx
   otbWrapperApplicationFactoryBase.cxx
   otbWrapperCompositeApplication.cxx
+  otbWrapperStringListInterface.cxx
+  otbWrapperStringListParameter.cxx
+  otbWrapperAbstractParameterList.cxx
+  otbWrapperParameterList.cxx
   otbLogger.cxx
   )
 
 add_library(OTBApplicationEngine ${OTBApplicationEngine_SRC})
-target_link_libraries(OTBApplicationEngine 
+target_link_libraries(OTBApplicationEngine
   ${OTBVectorDataBase_LIBRARIES}
   ${OTBImageManipulation_LIBRARIES}
   ${OTBImageIO_LIBRARIES}
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperAbstractParameterList.cxx
similarity index 50%
copy from Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
copy to Modules/Wrappers/ApplicationEngine/src/otbWrapperAbstractParameterList.cxx
index e4104cd..06b3cef 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperAbstractParameterList.cxx
@@ -18,37 +18,31 @@
  * limitations under the License.
  */
 
-#if defined(_MSC_VER)
-#pragma warning ( disable : 4786 )
-#endif
+#include "otbWrapperAbstractParameterList.h"
 
-#include "otbWrapperParameter.h"
 
-int otbWrapperParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+namespace otb
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
 
-  //std::cout << parameter << std::endl;
 
-  return EXIT_SUCCESS;
+namespace Wrapper
+{
+
+
+/*****************************************************************************/
+AbstractParameterList
+::AbstractParameterList()
+{
 }
 
-int otbWrapperParameterTest1(int itkNotUsed(argc), char* argv[])
+/*****************************************************************************/
+AbstractParameterList
+::~AbstractParameterList()
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
+}
 
-  const std::string name = argv[1];
 
-  parameter->SetName(name);
+} // End of namespace 'Wrapper'
 
-  if (name == parameter->GetName())
-    {
-    return EXIT_SUCCESS;
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
-}
+
+} // End of namespace 'otb'
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
index 47c4e85..cca32d5 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
@@ -265,20 +265,17 @@ void Application::SetParameterStringList(std::string parameter, std::vector<std:
   if (dynamic_cast<InputImageListParameter*>(param))
     {
     InputImageListParameter* paramDown = dynamic_cast<InputImageListParameter*>(param);
-    if( !paramDown->SetListFromFileName(values) )
-    otbAppLogCRITICAL( <<"At least one image filename is invalid.");
+    paramDown->SetListFromFileName( values );
     }
   else if (dynamic_cast<InputVectorDataListParameter*>(param))
     {
     InputVectorDataListParameter* paramDown = dynamic_cast<InputVectorDataListParameter*>(param);
-    if( !paramDown->SetListFromFileName(values)  )
-    otbAppLogCRITICAL( <<"At least one vector data filename is invalid..");
+    paramDown->SetListFromFileName( values );
     }
   else if (dynamic_cast<InputFilenameListParameter*>(param))
     {
     InputFilenameListParameter* paramDown = dynamic_cast<InputFilenameListParameter*>(param);
-    if( !paramDown->SetListFromFileName(values)  )
-    otbAppLogCRITICAL( <<"At least one filename is invalid..");
+    paramDown->SetListFromFileName( values );
     }
   else if (dynamic_cast<StringListParameter*>(param))
     {
@@ -391,14 +388,29 @@ int Application::Execute()
     }
 
   this->DoExecute();
+  
+  // Ensure that all output image parameter have called UpdateOutputInformation()
+  for (auto it = paramList.begin(); it != paramList.end(); ++it)
+    {
+    OutputImageParameter * outImgParamPtr = dynamic_cast<OutputImageParameter *>(GetParameterByKey(*it));
+    // If this is an OutputImageParameter
+    if(outImgParamPtr != ITK_NULLPTR)
+      {
+      // If the parameter is enabled
+      if(IsParameterEnabled(*it))
+        {
+        // Call UpdateOutputInformation()
+        outImgParamPtr->GetValue()->UpdateOutputInformation();
+        }
+      }
+    }
 
   return 0;
 }
 
 int Application::ExecuteAndWriteOutput()
 {
-  m_Chrono.Reset();
-  m_Chrono.Start();
+  m_Chrono.Restart();
 
   int status = this->Execute();
 
@@ -476,7 +488,7 @@ int Application::ExecuteAndWriteOutput()
           {
           Parameter* param = GetParameterByKey(key);
           ComplexOutputImageParameter* outputParam = dynamic_cast<ComplexOutputImageParameter*>(param);
-          
+
           if(outputParam!=ITK_NULLPTR)
             {
             outputParam->InitializeWriters();
@@ -829,7 +841,7 @@ void Application::SetMinimumParameterIntValue(std::string parameter, int value)
     paramInt->SetMinimumValue(value);
     }
  else
-    itkExceptionMacro(<<parameter << "parameter can't be casted to int");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to int");
 }
 
 void Application::SetMaximumParameterIntValue(std::string parameter, int value)
@@ -842,7 +854,7 @@ void Application::SetMaximumParameterIntValue(std::string parameter, int value)
     paramInt->SetMaximumValue(value);
     }
   else
-    itkExceptionMacro(<<parameter << "parameter can't be casted to int");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to int");
 
 }
 
@@ -856,7 +868,7 @@ void Application::SetMinimumParameterFloatValue(std::string parameter, float val
     paramFloat->SetMinimumValue(value);
     }
  else
-    itkExceptionMacro(<<parameter << "parameter can't be casted to float");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to float");
 }
 
 void Application::SetMaximumParameterFloatValue(std::string parameter, float value)
@@ -869,7 +881,7 @@ void Application::SetMaximumParameterFloatValue(std::string parameter, float val
     paramFloat->SetMaximumValue(value);
     }
   else
-    itkExceptionMacro(<<parameter << "parameter can't be casted to float");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to float");
 
 }
 
@@ -883,8 +895,8 @@ void Application::SetListViewSingleSelectionMode(std::string parameter, bool sta
     paramListView->SetSingleSelection(status);
     }
   else
-    itkExceptionMacro(<<parameter << "parameter can't be casted to ListView");
-  
+    itkExceptionMacro(<<parameter << " parameter can't be casted to ListView");
+
 }
 
 
@@ -997,7 +1009,7 @@ int Application::GetParameterInt(std::string parameter)
     }
   else
     {
-     itkExceptionMacro(<<parameter << "parameter can't be casted to int");
+     itkExceptionMacro(<<parameter << " parameter can't be casted to int");
     }
 
   return ret;
@@ -1015,7 +1027,7 @@ float Application::GetParameterFloat(std::string parameter)
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to float");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to float");
     }
 
   return ret;
@@ -1124,14 +1136,16 @@ std::string Application::GetParameterString(std::string parameter)
   return ret;
 }
 
-std::vector<std::string> Application::GetParameterStringList(std::string parameter)
+std::vector< std::string >
+Application
+::GetParameterStringList( const std::string & parameter )
 {
   std::vector<std::string> ret;
-  Parameter* param = GetParameterByKey(parameter);
+  Parameter * param = GetParameterByKey(parameter);
 
   if (dynamic_cast<InputImageListParameter*> (param))
     {
-    InputImageListParameter* paramDown = dynamic_cast<InputImageListParameter*> (param);
+    InputImageListParameter * paramDown = dynamic_cast<InputImageListParameter*> (param);
     ret = paramDown->GetFileNameList();
     }
   else
@@ -1143,13 +1157,13 @@ std::vector<std::string> Application::GetParameterStringList(std::string paramet
     else
       if (dynamic_cast<InputFilenameListParameter*> (param))
         {
-        InputFilenameListParameter* paramDown = dynamic_cast<InputFilenameListParameter*> (param);
+	InputFilenameListParameter* paramDown = dynamic_cast<InputFilenameListParameter*> (param);
         ret = paramDown->GetFileNameList();
         }
       else
         if (dynamic_cast<StringListParameter*> (param))
           {
-          StringListParameter* paramDown = dynamic_cast<StringListParameter*> (param);
+	  StringListParameter* paramDown = dynamic_cast<StringListParameter*> (param);
           ret = paramDown->GetValue();
           }
         else
@@ -1160,7 +1174,7 @@ std::vector<std::string> Application::GetParameterStringList(std::string paramet
             }
           else
             {
-            itkExceptionMacro(<<parameter << "parameter can't be casted to StringList");
+            itkExceptionMacro(<<parameter << " parameter can't be casted to StringList");
             }
 
   return ret;
@@ -1171,30 +1185,30 @@ void Application::SetParameterInputImage(std::string parameter, InputImageParame
   Parameter* param = GetParameterByKey(parameter);
 
   InputImageParameter* paramDown = dynamic_cast<InputImageParameter*> (param);
-  
+
   if (paramDown)
     {
     paramDown->SetImage(inputImage);
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to InputImageParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to InputImageParameter");
     }
 }
 
 OutputImageParameter::ImageBaseType * Application::GetParameterOutputImage(std::string parameter)
 {
   Parameter* param = GetParameterByKey(parameter);
-  
+
   OutputImageParameter* paramDown = dynamic_cast<OutputImageParameter*> (param);
-  
+
   if (paramDown)
-    {    
+    {
     return paramDown->GetValue();
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to OutputImageParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to OutputImageParameter");
     }
 }
 
@@ -1204,48 +1218,48 @@ void Application::SetParameterComplexInputImage(std::string parameter, ComplexIn
   Parameter* param = GetParameterByKey(parameter);
 
   ComplexInputImageParameter* paramDown = dynamic_cast<ComplexInputImageParameter*> (param);
-  
+
   if (paramDown)
     {
     paramDown->SetImage(inputImage);
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to ComplexInputImageParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to ComplexInputImageParameter");
     }
 }
 
 ComplexOutputImageParameter::ImageBaseType * Application::GetParameterComplexOutputImage(std::string parameter)
 {
   Parameter* param = GetParameterByKey(parameter);
-  
+
   ComplexOutputImageParameter* paramDown = dynamic_cast<ComplexOutputImageParameter*> (param);
-  
+
   if (paramDown)
-    {    
+    {
     return paramDown->GetValue();
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to ComplexOutputImageParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to ComplexOutputImageParameter");
     }
 }
 
 void Application::AddImageToParameterInputImageList(std::string parameter, InputImageListParameter::ImageBaseType * img)
 {
   Parameter* param = GetParameterByKey(parameter);
-  
+
   InputImageListParameter * paramDown = dynamic_cast<InputImageListParameter *>(param);
-  
+
   if(paramDown)
     {
     paramDown->AddImage(img);
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to InputImageListParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to InputImageListParameter");
     }
-  
+
 }
 
 void Application::SetNthParameterInputImageList(std::string parameter, const unsigned int &id, InputImageListParameter::ImageBaseType * img)
@@ -1260,7 +1274,7 @@ void Application::SetNthParameterInputImageList(std::string parameter, const uns
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to InputImageListParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to InputImageListParameter");
     }
 
 }
@@ -1268,18 +1282,18 @@ void Application::SetNthParameterInputImageList(std::string parameter, const uns
 void Application::AddParameterStringList(std::string parameter, const std::string & str)
 {
   Parameter* param = GetParameterByKey(parameter);
-  
+
   InputImageListParameter * paramDown = dynamic_cast<InputImageListParameter *>(param);
-  
+
   if(paramDown)
     {
     paramDown->AddFromFileName(str);
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to InputImageListParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to InputImageListParameter");
     }
-  
+
 }
 
 void Application::SetNthParameterStringList(std::string parameter, const unsigned int &id, const std::string & str)
@@ -1294,7 +1308,7 @@ void Application::SetNthParameterStringList(std::string parameter, const unsigne
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to InputImageListParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to InputImageListParameter");
     }
 
 }
@@ -1313,7 +1327,7 @@ void Application::ClearParameterInputImageList(std::string parameter)
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to InputImageListParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to InputImageListParameter");
     }
 
 }
@@ -1330,7 +1344,7 @@ unsigned int Application::GetNumberOfElementsInParameterInputImageList(std::stri
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to InputImageListParameter");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to InputImageListParameter");
     }
 
 }
@@ -1349,7 +1363,7 @@ FloatVectorImageType* Application::GetParameterImage(std::string parameter)
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to ImageType");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to ImageType");
     }
 
   return ret;
@@ -1367,7 +1381,7 @@ FloatVectorImageListType* Application::GetParameterImageList(std::string paramet
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to ImageListType");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to ImageListType");
     }
 
   return ret;
@@ -1385,7 +1399,7 @@ ComplexFloatVectorImageType* Application::GetParameterComplexImage(std::string p
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to ComplexImageType");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to ComplexImageType");
     }
 
   return ret;
@@ -1403,7 +1417,7 @@ VectorDataType* Application::GetParameterVectorData(std::string parameter)
     }
   else
     {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to Vector Data");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to Vector Data");
     }
   return ret;
 }
@@ -1420,7 +1434,7 @@ VectorDataListType* Application::GetParameterVectorDataList(std::string paramete
     }
   else
    {
-    itkExceptionMacro(<<parameter << "parameter can't be casted to Vector Data List");
+    itkExceptionMacro(<<parameter << " parameter can't be casted to Vector Data List");
    }
   return ret;
 }
@@ -1454,7 +1468,10 @@ std::string Application::GetParameterAsString(std::string paramKey)
       oss << this->GetParameterFloat( paramKey );
       ret = oss.str();
     }
-  else if( type == ParameterType_StringList )
+  else if( type == ParameterType_StringList ||
+    type == ParameterType_InputImageList ||
+    type == ParameterType_InputVectorDataList ||
+    type == ParameterType_InputFilenameList)
     {
       std::ostringstream oss;
       oss << std::setprecision(10);
@@ -1683,7 +1700,7 @@ std::string Application::GetProgressDescription() const
 
 double Application::GetLastExecutionTiming() const
 {
-  return m_Chrono.GetTotal();
+  return m_Chrono.GetElapsedMilliseconds() / 1000.0;
 }
 
 }
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationHtmlDocGenerator.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationHtmlDocGenerator.cxx
index 02d4c8c..3e35f46 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationHtmlDocGenerator.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationHtmlDocGenerator.cxx
@@ -22,6 +22,7 @@
 
 #include <stdio.h>
 #include "otbWrapperChoiceParameter.h"
+#include "otbStringToHTML.h"
 
 namespace otb
 {
@@ -55,12 +56,12 @@ namespace Wrapper
 
 #define otbDocHtmlParamMacro( type, param, fullKey, showKey )           \
   oss << "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:'Courier New, courier'; font-weight:600;\"; >"; \
-  oss << param->GetName();                                              \
+  oss << otb::StringToHTML(param->GetName());                           \
   if( showKey == true &&  param->GetKey()[0] != '\0' )       \
     {                                                                   \
 if (!fullKey.empty())                                           \
   {                                                                   \
-  oss << " ("<< fullKey<< "." << param->GetKey() << ")";                                        \
+  oss << " ("<< fullKey<< "." << param->GetKey() << ")";              \
   }                                                                   \
 else                                                                  \
   {                                                                   \
@@ -70,7 +71,7 @@ else                                                                  \
   oss << ": </span>";                                                   \
 if( param->GetDescription()[0] != '\0' )                  \
   {                                                                   \
-  oss << param->GetDescription();                                     \
+  oss << otb::StringToHTML(param->GetDescription());                  \
   }                                                                   \
 oss << "</p>";
 
@@ -93,10 +94,10 @@ ApplicationHtmlDocGenerator::GenerateDoc( const Application::Pointer app, std::s
   oss << "p, li { white-space: pre-wrap; }";
   oss << "</style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\">";
 
-  otbDocHtmlTitleMacro( app->GetDocName() );
+  otbDocHtmlTitleMacro( otb::StringToHTML(app->GetDocName()) );
 
   otbDocHtmlTitle1Macro( "Brief Description" );
-  otbDocHtmlBodyMacro( app->GetDescription() );
+  otbDocHtmlBodyMacro( otb::StringToHTML(app->GetDescription()) );
 
   otbDocHtmlTitle1Macro( "Tags" );
   std::string tagList;
@@ -107,7 +108,7 @@ ApplicationHtmlDocGenerator::GenerateDoc( const Application::Pointer app, std::s
       tagList.append( app->GetDocTags()[i] ).append(", ");
       }
     tagList.append( app->GetDocTags()[app->GetDocTags().size() - 1]);
-    otbDocHtmlBodyMacro( tagList );
+    otbDocHtmlBodyMacro( otb::StringToHTML(tagList) );
     }
   else
     {
@@ -115,7 +116,7 @@ ApplicationHtmlDocGenerator::GenerateDoc( const Application::Pointer app, std::s
     }
 
   otbDocHtmlTitle1Macro("Long Description");
-  otbDocHtmlBodyMacro( app->GetDocLongDescription() );
+  otbDocHtmlBodyMacro( otb::StringToHTML(app->GetDocLongDescription()) );
 
   otbDocHtmlTitle1Macro("Parameters");
   oss << "<ul>";
@@ -125,13 +126,13 @@ ApplicationHtmlDocGenerator::GenerateDoc( const Application::Pointer app, std::s
   oss<<"</ul>";
 
   otbDocHtmlTitle1Macro( "Limitations");
-  otbDocHtmlBodyMacro( app->GetDocLimitations() );
+  otbDocHtmlBodyMacro( otb::StringToHTML(app->GetDocLimitations()) );
 
   otbDocHtmlTitle1Macro( "Authors" );
-  otbDocHtmlBodyMacro( app->GetDocAuthors() );
+  otbDocHtmlBodyMacro( otb::StringToHTML(app->GetDocAuthors()) );
 
   otbDocHtmlTitle1Macro( "See also" );
-  otbDocHtmlBodyMacro( app->GetDocSeeAlso() );
+  otbDocHtmlBodyMacro( otb::StringToHTML(app->GetDocSeeAlso()) );
 
   otbDocHtmlTitle1Macro( "Example of use" );
   if( showKey == true )
@@ -143,7 +144,7 @@ ApplicationHtmlDocGenerator::GenerateDoc( const Application::Pointer app, std::s
   if( showKey == true )
     {
     otbDocHtmlBodyMacro( "<li>Command line to execute:</li>" );
-    otbDocHtmlBodyCodeMacro( app->GetCLExample() );
+    otbDocHtmlBodyCodeMacro( otb::StringToHTML(app->GetCLExample()) );
 
     oss << "</ul>";
     }
@@ -151,8 +152,8 @@ ApplicationHtmlDocGenerator::GenerateDoc( const Application::Pointer app, std::s
 
   val = oss.str();
 
-// Replace "\n" string with <br/>
-  itksys::SystemTools::ReplaceString( val, "\n", "<br/>");
+  // Replace ":\n\n" string with ":\n" (the extra LF is needed because of rst syntax
+  itksys::SystemTools::ReplaceString( val, ":<br/><br/>", ":<br/>");
 }
 
 void
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx
index bb4e574..f022af0 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx
@@ -375,7 +375,31 @@ ApplicationRegistry::LoadApplicationFromPath(std::string path,std::string name)
 
   if (itksys::SystemTools::FileExists(path.c_str(),true))
     {
-    itk::LibHandle lib = itk::DynamicLoader::OpenLibrary(path.c_str());
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    int cp = CP_UTF8;
+    int acp = GetACP();
+    if (acp != CP_UTF8)
+      {
+      bool hasNonAscii=false;
+      for (auto c: path)
+        {
+        if (0 > (int) c)
+          {
+          hasNonAscii = true;
+          break;
+          }
+        }
+      if (hasNonAscii) cp = acp;
+      }
+    int length = MultiByteToWideChar(cp, 0, path.c_str(), -1, NULL, 0);
+    wchar_t* wpath = new wchar_t[length+1];
+    wpath[0] = '\0';
+    MultiByteToWideChar(cp, 0, path.c_str(), -1, wpath, length);
+    itk::LibHandle lib = LoadLibraryW(wpath);
+    delete [] wpath;
+#else
+    itk::LibHandle lib = itksys::DynamicLoader::OpenLibrary(path);
+#endif
     if (lib)
       {
       /**
@@ -412,6 +436,10 @@ ApplicationRegistry::LoadApplicationFromPath(std::string path,std::string name)
         }
       itk::DynamicLoader::CloseLibrary(lib);
       }
+    else
+      {
+      otbMsgDevMacro( << "Can't load library : " << path << std::endl );
+      }
     }
   return appli;
 }
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx
index df0ed51..6c59ad4 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx
@@ -52,27 +52,10 @@ ComplexInputImageParameter::SetFromFileName(const std::string& filename)
   //  - Done in the reader
   //  - allow appending additional information to the filename
   // myfile.tif:2 for example, or myfile.tif:nocarto
-  if (!filename.empty())
-    {
-    ComplexFloatVectorReaderType::Pointer reader = ComplexFloatVectorReaderType::New();
-
-    try
-      {
-      reader->SetFileName(filename);
-      reader->UpdateOutputInformation();
-      }
-    catch(itk::ExceptionObject & /*err*/)
-      {
-           return false;
-      }
-
-    // the specified filename is valid => store the value
-    m_FileName = filename;
-    m_UseFilename = true;
-    SetActive(true);
-    return true;
-    }
-  return false;
+  m_FileName = filename;
+  m_UseFilename = true;
+  SetActive(true);
+  return true;
 }
 
 
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
index ce11263..64ef365 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx
@@ -73,6 +73,18 @@ ComplexOutputImageParameter::ConvertPixelTypeToString(ComplexImagePixelType type
   return ret;
 }
 
+bool
+ComplexOutputImageParameter::ConvertStringToPixelType(const std::string &value, ComplexImagePixelType &type)
+{
+  if (value == "cfloat")
+    type = ComplexImagePixelType_float;
+  else if (value == "cdouble")
+    type = ComplexImagePixelType_double;
+  else
+    return false;
+  return true;
+}
+
 void ComplexOutputImageParameter::InitializeWriters()
 {
   m_ComplexFloatWriter = ComplexFloatWriterType::New();
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperDocExampleStructure.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperDocExampleStructure.cxx
index d88c5b9..59c9448 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperDocExampleStructure.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperDocExampleStructure.cxx
@@ -19,6 +19,7 @@
  */
 
 #include "otbWrapperDocExampleStructure.h"
+#include "otbStringToHTML.h"
 
 namespace otb
 {
@@ -185,7 +186,7 @@ DocExampleStructure::GenerateHtmlExample( unsigned int exId )
       {
       oss << "<li>";
       oss << "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">";
-      oss << it->first << ": " << it->second;
+      oss << it->first << ": " << otb::StringToHTML(it->second);
       oss << "</p>";
       oss << "</li>";
       }
@@ -211,7 +212,7 @@ DocExampleStructure::GenerateHtmlExample()
     if( m_NbOfExamples>1 )
       oss << "<li>";
     if( !m_ExampleCommentList[exId].empty() )
-      oss << m_ExampleCommentList[exId];
+      oss << otb::StringToHTML(m_ExampleCommentList[exId]);
     oss << this->GenerateHtmlExample( exId );
     if( m_NbOfExamples>1 )
       oss << "</li>";
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
index 304e5b6..f645553 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
@@ -57,7 +57,7 @@ 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 (http://hg.orfeo-toolbox.org/OTB-Data/raw-file/404aa6e4b3e0/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://git.orfeo-toolbox.org/otb-data.git/blob/HEAD:/Input/DEM/egm96.grd).");
   app->MandatoryOff(oss.str());
 
   std::string geoidFromConfig = otb::ConfigurationManager::GetGeoidFile();
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx
index e65e220..72b5aa1 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputFilenameListParameter.cxx
@@ -19,189 +19,110 @@
  */
 
 #include "otbWrapperInputFilenameListParameter.h"
-#include "itksys/SystemTools.hxx"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
 
-InputFilenameListParameter::InputFilenameListParameter()
-{
-  this->SetName("Input Filename List");
-  this->SetKey("inList");
-  m_FilenameList = StringParameterListType::New();
-}
 
-InputFilenameListParameter::~InputFilenameListParameter()
-{
-}
+const std::string FILENAME_FILTER(
+  "All files (*);;"
+  "CSV files (.csv);;"
+  "Text files (.txt);;"
+  "XML files (.xml)"
+);
+
 
-bool
-InputFilenameListParameter::SetListFromFileName(const std::vector<std::string> & filenames)
+/*****************************************************************************/
+InputFilenameListParameter
+::InputFilenameListParameter()
 {
-  // First clear previous file chosen
-  this->ClearValue();
-
-  for(unsigned int i=0; i<filenames.size(); i++)
-    {
-    std::string filename = filenames[i];
-    // File existence checked by the reader
-    if (!filename.empty())
-      {
-      StringParameter::Pointer strParameter = StringParameter::New();
-      strParameter->SetValue(filename);
-      strParameter->HasValue();
-
-      // everything went fine, store the object reference
-      m_FilenameList->PushBack(strParameter);
-      }
-    }
-
-  SetActive(true);
-  this->Modified();
-  return true;
+  SetName( "Input Filename List" );
+  SetKey( "inList" );
 }
 
 
-void
-InputFilenameListParameter::AddNullElement()
+/*****************************************************************************/
+InputFilenameListParameter
+::~InputFilenameListParameter()
 {
-  m_FilenameList->PushBack(ITK_NULLPTR);
-  SetActive(false);
-  this->Modified();
 }
 
-bool
-InputFilenameListParameter::AddFromFileName(const std::string & filename)
-{
-  // File existence checked by the reader
-  if (!filename.empty())
-    {
-    StringParameter::Pointer strParameter = StringParameter::New();
-    strParameter->SetValue(filename);
-    strParameter->HasValue();
-
-    // everything went fine, store the object references
-    m_FilenameList->PushBack(strParameter);
-    SetActive(true);
-    this->Modified();
-    return true;
-    }
-
-  return false;
-}
 
-bool
-InputFilenameListParameter::SetNthFileName( const unsigned int id, const std::string & filename )
+/*****************************************************************************/
+Role
+InputFilenameListParameter
+::GetDirection( std::size_t ) const
 {
-  if( m_FilenameList->Size()<id )
-    {
-    itkExceptionMacro(<< "No file "<<id<<". Only "<<m_FilenameList->Size()<<" filenames available.");
-    }
-
-  // File existence checked by the reader
-  if (!filename.empty())
-    {
-    StringParameter::Pointer strParameter = StringParameter::New();
-    strParameter->SetValue(filename);
-    strParameter->HasValue();
-
-    m_FilenameList->SetNthElement(id, strParameter);
-    SetActive(true);
-    this->Modified();
-    return true;
-    }
-
-  return false;
-}
+#if 0
+  assert( i<m_FilenameList->Size() );
+  assert( !m_FilenameList->GetNthElement( i ).IsNull() );
 
+  return m_FilenameList->GetNthElement( i )->GetRole();
 
-std::vector<std::string>
-InputFilenameListParameter::GetFileNameList() const
-{
-  if (m_FilenameList)
-    {
-    std::vector<std::string> filenames;
-    for(unsigned int i=0; i<m_FilenameList->Size(); i++)
-      {
-      if( m_FilenameList->GetNthElement(i) )
-        filenames.push_back( m_FilenameList->GetNthElement(i)->GetValue() );
-      }
-
-    return filenames;
-    }
-
-  itkExceptionMacro(<< "No filename value");
+#else
+  // otb::Parameter::GetRole() does not necessarily stand for
+  // direction of parameter.
+  return GetDirection();
+
+#endif
 }
 
 
-std::string
-InputFilenameListParameter::GetNthFileName( unsigned int i ) const
+/*****************************************************************************/
+Role
+InputFilenameListParameter
+::GetDirection() const
 {
-  if (m_FilenameList)
-    {
-    if(m_FilenameList->Size()<i)
-      {
-      itkExceptionMacro(<< "No file "<<i<<". Only "<<m_FilenameList->Size()<<" filenames available.");
-      }
-
-    return m_FilenameList->GetNthElement(i)->GetValue();
-    }
-
-  itkExceptionMacro(<< "No filename value");
+  return Role_Input;
 }
 
 
-InputFilenameListParameter::StringParameterListPointerType
-InputFilenameListParameter::GetFileList() const
+/*****************************************************************************/
+const std::string &
+InputFilenameListParameter
+::GetFilenameFilter( std::size_t ) const
 {
-  return m_FilenameList;
+  return GetFilenameFilter();
 }
 
-bool
-InputFilenameListParameter::HasValue() const
+
+/*****************************************************************************/
+const std::string &
+InputFilenameListParameter
+::GetFilenameFilter() const
 {
-  if(m_FilenameList->Size() == 0)
-    {
-    return false;
-    }
-
-  bool res(true);
-  unsigned int i(0);
-  while(i < m_FilenameList->Size() && res == true)
-    {
-    res = m_FilenameList->GetNthElement(i).IsNotNull();
-    i++;
-    }
-
-  return res;
+  return FILENAME_FILTER;
 }
 
 
-void
-InputFilenameListParameter::Erase( unsigned int id )
+/*****************************************************************************/
+const std::string &
+InputFilenameListParameter
+::ToString( const ParameterType::Pointer & p ) const
 {
-  if(m_FilenameList->Size()<id)
-    {
-    itkExceptionMacro(<< "No file "<<id<<". Only "<<m_FilenameList->Size()<<" filenames available.");
-    }
+  assert( !p.IsNull() );
 
-  m_FilenameList->Erase( id );
-
-  this->Modified();
+  return p->GetValue();
 }
 
-void
-InputFilenameListParameter::ClearValue()
+/*****************************************************************************/
+const InputFilenameListParameter::ParameterType::Pointer &
+InputFilenameListParameter
+::FromString( const ParameterType::Pointer & p,
+	      const std::string & s ) const
 {
-  m_FilenameList->Clear();
-
-  SetActive(false);
-  this->Modified();
-}
+  assert( !p.IsNull() );
 
+  p->SetValue( s );
 
+  return p;
 }
+
 }
 
+}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx
index 01c31e1..4bb5f61 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageListParameter.cxx
@@ -19,280 +19,235 @@
  */
 
 #include "otbWrapperInputImageListParameter.h"
-#include "itksys/SystemTools.hxx"
+
+
+#include "otbCast.h"
+
 
 namespace otb
 {
+
 namespace Wrapper
 {
 
-InputImageListParameter::InputImageListParameter()
-  : m_InputImageParameterVector(),
-    m_ImageList(FloatVectorImageListType::New())
-{
-  this->SetName("Input Image List");
-  this->SetKey("inList");
-}
 
-InputImageListParameter::~InputImageListParameter()
-{
-}
+const std::string
+IMAGES_FILTER(
+  "All files (*);;"
+  "TIFF file (*tif);;"
+  "PNG File (*.png);;"
+  "JPEG File (*.jpg)"
+);
+
 
-bool
-InputImageListParameter::SetListFromFileName(const std::vector<std::string> & filenames)
+/*****************************************************************************/
+InputImageParameter::Pointer
+InputImageListParameter
+::FromImage( ImageBaseType * image )
 {
-  // First clear previous file chosen
-  this->ClearValue();
+  assert( image!=nullptr );
 
-  for(unsigned int i=0; i<filenames.size(); i++)
-    {
-    const std::string filename = filenames[i];
+  InputImageParameter::Pointer p;
 
-    // File existence checked by the reader
-    if (!filename.empty())
-      {
-      // Try to build a new ParameterInputImage
-      InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New();
-      tmpInputImageParameter->SetFromFileName(filename);
+  return FromImage( p, image );
+}
 
-      m_InputImageParameterVector.push_back(tmpInputImageParameter);
-      }
-    }
+/*****************************************************************************/
+InputImageParameter::Pointer &
+InputImageListParameter
+::FromImage( InputImageParameter::Pointer & parameter,
+	     ImageBaseType * image )
+{
+  return
+    FromData(
+      parameter,
+      image,
+      []( auto p, auto i ) -> void
+      {
+        assert( p );
 
-  this->Modified();
-  SetActive(true);
-  return true;
+	p->SetImage( i );
+      },
+      "Image filename"
+    );
 }
 
 
-void
-InputImageListParameter::AddNullElement()
+/*****************************************************************************/
+InputImageListParameter
+::InputImageListParameter() :
+  m_ImageList( FloatVectorImageListType::New() )
 {
-  m_InputImageParameterVector.push_back(ITK_NULLPTR);
-  SetActive(false);
-  this->Modified();
+  SetName( "Input Image List" );
+  SetKey( "inList" );
 }
 
-bool
-InputImageListParameter::AddFromFileName(const std::string & filename)
-{
-  // File existence checked by the reader
-  if (!filename.empty())
-    {
-    InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New();
-    tmpInputImageParameter->SetFromFileName(filename);
-
-    m_InputImageParameterVector.push_back(tmpInputImageParameter);
-
-    this->Modified();
-    SetActive(true);
-    return true;
-    }
 
-  return false;
+/*****************************************************************************/
+InputImageListParameter
+::~InputImageListParameter()
+{
 }
 
-bool
-InputImageListParameter::SetNthFileName( const unsigned int id, const std::string & filename )
+/*****************************************************************************/
+const FloatVectorImageListType *
+InputImageListParameter
+::GetImageList() const
 {
-  if( m_InputImageParameterVector.size()<id )
-    {
-    itkExceptionMacro(<< "No image "<<id<<". Only "<<m_InputImageParameterVector.size()<<" images available.");
-    }
-
-  // File existence checked by the reader
-  if (!filename.empty())
-    {
-    InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New();
-    tmpInputImageParameter->SetFromFileName(filename);
-
-    m_InputImageParameterVector[id] = tmpInputImageParameter;
-
-    this->Modified();
-    SetActive(true);
-    return true;
-    }
-
-  return false;
+  return const_cast< InputImageListParameter * >( this )->GetImageList();
 }
 
 
-std::vector<std::string>
-InputImageListParameter::GetFileNameList() const
+/*****************************************************************************/
+FloatVectorImageListType *
+InputImageListParameter
+::GetImageList()
 {
-  std::vector<std::string> filenames;
-
-  for(InputImageParameterVectorType::const_iterator it = m_InputImageParameterVector.begin();
-      it!=m_InputImageParameterVector.end();++it)
-    {
-    if(it->IsNull())
+  return
+    GetObjectList(
+      m_ImageList,
+      []( auto param ) -> auto
       {
-      itkExceptionMacro(<< "Empty image in InputImageListParameter.");
-      }
-    filenames.push_back( (*it)->GetFileName() );
-    }
+        assert( param );
 
-  return filenames;
+        return param->GetFloatVectorImage();
+      }
+    );
 }
 
 
-std::string
-InputImageListParameter::GetNthFileName( unsigned int i ) const
+/*****************************************************************************/
+const FloatVectorImageType *
+InputImageListParameter
+::GetNthImage( std::size_t i ) const
 {
-    if(m_InputImageParameterVector.size()<i)
-      {
-      itkExceptionMacro(<< "No image "<<i<<". Only "<<m_InputImageParameterVector.size()<<" images available.");
-      }
-    if(m_InputImageParameterVector[i].IsNull())
-      {
-      itkExceptionMacro(<< "Requested image "<<i<<" has no filename");
-      }
-    return m_InputImageParameterVector[i]->GetFileName();
+  return const_cast< InputImageListParameter * >( this )->GetNthImage( i );
 }
 
-FloatVectorImageListType*
-InputImageListParameter::GetImageList() const
-{
-  m_ImageList->Clear();
-  for (unsigned int i=0 ; i < this->Size() ; ++i)
-    {
-    if(m_InputImageParameterVector[i].IsNull())
-      {
-      itkExceptionMacro(<< "Image "<<i<<" is empty.");
-      }
-    m_ImageList->PushBack(m_InputImageParameterVector[i]->GetFloatVectorImage());
-    }
-  return m_ImageList;
-}
 
-FloatVectorImageType*
-InputImageListParameter::GetNthImage(unsigned int i) const
+/*****************************************************************************/
+FloatVectorImageType *
+InputImageListParameter::GetNthImage( std::size_t i )
 {
-  if(this->Size()<=i)
-    {
-    itkExceptionMacro(<< "No image "<<i<<". Only "<<this->Size()<<" images available.");
-    }
-  if(m_InputImageParameterVector[i].IsNull())
-    {
-    itkExceptionMacro(<< "Image "<<i<<" is empty.");
-    }
-  return m_InputImageParameterVector[i]->GetFloatVectorImage();
+  assert( i<Size() );
+  assert( !m_Parameters[ i ].IsNull() );
+  assert( m_Parameters[ i ]->GetFloatVectorImage()!=nullptr );
+
+  return m_Parameters[ i ]->GetFloatVectorImage();
 }
 
+/*****************************************************************************/
 void
-InputImageListParameter::SetImageList(FloatVectorImageListType* imList)
+InputImageListParameter
+::SetImageList( FloatVectorImageListType * imList )
 {
-  // Check input availability
-  for(unsigned int i = 0; i < imList->Size(); i++)
-  {
-    imList->GetNthElement(i)->UpdateOutputInformation();
-  }
+  assert( imList!=nullptr );
+  assert( !m_ImageList.IsNull() );
 
-  // Clear previous values
-  this->ClearValue();
-
-  for(unsigned int i = 0; i<imList->Size(); i++)
+  SetObjectList(
+    *m_ImageList,
+    *imList,
+    [ this ]( auto p, auto image ) -> auto
     {
-    // Try to build a new ParameterInputImage
-    InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New();
-
-    tmpInputImageParameter->SetImage(imList->GetNthElement(i));
+      this->FromImage( p, image );
+    },
+    //
+    []( auto p ) -> auto
+    {
+      assert( p );
 
-    m_InputImageParameterVector.push_back(tmpInputImageParameter);
-    m_ImageList->PushBack(tmpInputImageParameter->GetFloatVectorImage());
+      return p->GetFloatVectorImage();
     }
-
-  SetActive(true);
-  this->Modified();
+  );
 }
 
-void InputImageListParameter::SetNthImage(unsigned int i, ImageBaseType * img)
+
+/*****************************************************************************/
+void
+InputImageListParameter
+::SetNthImage( std::size_t i, ImageBaseType * image )
 {
-  if(this->Size()<i)
-  {
-    itkExceptionMacro(<< "No image "<<i<<". Only "<<this->Size()<<" images available.");
-  }
+  assert( i<Size() );
+  assert( image!=nullptr );
 
   // Check input availability
-  img->UpdateOutputInformation();
-
-  // Try to build a new ParameterInputImage
-  InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New();
-
-  tmpInputImageParameter->SetImage(img);
+  image->UpdateOutputInformation();
 
-  m_InputImageParameterVector[i] = tmpInputImageParameter;
+  // Build parameter.
+  FromImage( m_Parameters[ i ], image );
 }
 
 
+/*****************************************************************************/
 void
-InputImageListParameter::AddImage(ImageBaseType* image)
+InputImageListParameter
+::AddImage( ImageBaseType * image )
 {
-  // Check input availability
-  image->UpdateOutputInformation();
+  AddData(
+    image,
+    [ this ]( auto i ) -> auto
+    {
+      return this->FromImage( i );
+    }
+  );
+}
 
-  InputImageParameter::Pointer tmpInputImageParameter = InputImageParameter::New();
 
-  tmpInputImageParameter->SetImage(image);
+/*****************************************************************************/
+void
+InputImageListParameter
+::ClearValue()
+{
+  Superclass::ClearValue();
 
-  m_InputImageParameterVector.push_back(tmpInputImageParameter);
+  assert( m_ImageList );
 
-  this->Modified();
+  m_ImageList->Clear();
 }
 
-bool
-InputImageListParameter::HasValue() const
+
+/*****************************************************************************/
+Role
+InputImageListParameter
+::GetDirection() const
 {
-  if(this->Size() == 0)
-    {
-    return false;
-    }
+  return Role_Input;
+}
 
-  bool res(true);
-  unsigned int i(0);
-  while(i < this->Size() && res == true)
-    {
-    res = (m_InputImageParameterVector[i] ?
-           m_InputImageParameterVector[i]->HasValue() :
-           false);
-    i++;
-    }
 
-  return res;
+/*****************************************************************************/
+const std::string &
+InputImageListParameter
+::GetFilenameFilter() const
+{
+  return IMAGES_FILTER;
 }
 
 
-void
-InputImageListParameter::Erase( unsigned int id )
+/*****************************************************************************/
+const std::string &
+InputImageListParameter
+::ToString( const ParameterType::Pointer & p ) const
 {
-  if(this->Size()<id)
-    {
-    itkExceptionMacro(<< "No image "<<id<<". Only "<<this->Size()<<" images available.");
-    }
+  assert( !p.IsNull() );
 
-  m_InputImageParameterVector.erase(m_InputImageParameterVector.begin()+id);
-
-  this->Modified();
+  return p->GetFileName();
 }
 
-unsigned int
-InputImageListParameter::Size() const
+/*****************************************************************************/
+const InputImageListParameter::ParameterType::Pointer &
+InputImageListParameter
+::FromString( const ParameterType::Pointer & p,
+	      const std::string & s ) const
 {
-  return m_InputImageParameterVector.size();
-}
+  assert( !p.IsNull() );
 
+  p->SetFromFileName( s );
 
-void
-InputImageListParameter::ClearValue()
-{
-  m_ImageList->Clear();
-  m_InputImageParameterVector.clear();
-
-  SetActive(false);
-  this->Modified();
+  return p;
 }
 
 
 }
-}
 
+}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx
index 08c0e1c..166ab29 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx
@@ -26,6 +26,7 @@
 
 namespace otb
 {
+
 namespace Wrapper
 {
 
@@ -55,7 +56,8 @@ InputImageParameter::SetFromFileName(const std::string& filename)
   // myfile.tif:2 for example, or myfile.tif:nocarto
   m_FileName = filename;
   m_UseFilename = true;
-  SetActive(true);
+  SetActive( true );
+
   return true;
 }
 
@@ -88,14 +90,15 @@ InputImageParameter::HasValue() const
 }
 
 void
-InputImageParameter::ClearValue()
+InputImageParameter
+::ClearValue()
 {
- m_Image  = ITK_NULLPTR;
- m_Reader = ITK_NULLPTR;
- m_Caster = ITK_NULLPTR;
- m_FileName = "";
- m_PreviousFileName="";
- m_UseFilename = true;
+  m_Image  = ITK_NULLPTR;
+  m_Reader = ITK_NULLPTR;
+  m_Caster = ITK_NULLPTR;
+  m_FileName = "";
+  m_PreviousFileName="";
+  m_UseFilename = true;
 }
 
 }
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
index 8bfd04b..938936e 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputProcessXMLParameter.cxx
@@ -384,7 +384,6 @@ InputProcessXMLParameter::Read(Application::Pointer this_)
       if(itksys::SystemTools::FileExists(value.c_str()))
 	{
 	InputVectorDataParameter* paramDown = dynamic_cast<InputVectorDataParameter*>(param);
-	paramDown->SetFromFileName(value);
 	if ( !paramDown->SetFromFileName(value) )
 	  {
 	  ret = -1;
@@ -395,28 +394,16 @@ InputProcessXMLParameter::Read(Application::Pointer this_)
       {
       InputImageListParameter* paramDown = dynamic_cast<InputImageListParameter*>(param);
       paramDown->SetListFromFileName(values);
-      if ( !paramDown->SetListFromFileName(values) )
-	{
-	ret = -1;
-	}
       }
     else if (dynamic_cast<InputVectorDataListParameter*>(param))
       {
       InputVectorDataListParameter* paramDown = dynamic_cast<InputVectorDataListParameter*>(param);
-      paramDown->SetListFromFileName(values);
-      if ( !paramDown->SetListFromFileName(values) )
-	{
-	ret = -1;
-	}
+      paramDown->SetListFromFileName( values );
       }
     else if (dynamic_cast<InputFilenameListParameter*>(param))
       {
       InputFilenameListParameter* paramDown = dynamic_cast<InputFilenameListParameter*>(param);
-      paramDown->SetListFromFileName(values);
-      if ( !paramDown->SetListFromFileName(values) )
-	{
-	ret= -1;
-	}
+      paramDown->SetListFromFileName( values );
       }
     else if (type == ParameterType_Radius || type == ParameterType_Int ||
 	     typeAsString == "rand" )
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataListParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataListParameter.cxx
index 8b40c1e..3b21c91 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataListParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataListParameter.cxx
@@ -19,291 +19,201 @@
  */
 
 #include "otbWrapperInputVectorDataListParameter.h"
-#include "itksys/SystemTools.hxx"
 
-#include "otbWrapperMacros.h"
 
 namespace otb
 {
-namespace Wrapper
-{
 
-InputVectorDataListParameter::InputVectorDataListParameter()
-{
-  this->SetName("Input VectorData List");
-  this->SetKey("vdList");
-  m_VectorDataList = VectorDataListType::New();
-  m_ReaderList = VectorDataFileReaderListType::New();
-}
 
-InputVectorDataListParameter::~InputVectorDataListParameter()
+namespace Wrapper
 {
-}
 
-bool
-InputVectorDataListParameter::SetListFromFileName(const std::vector<std::string> & filenames)
-{
-  // First clear previous file chosen
-  this->ClearValue();
 
-  bool isOk = true;
-  for(unsigned int i=0; i<filenames.size(); i++)
-    {
-    const std::string filename = filenames[i];
-    // TODO : when the logger will be available, redirect the exception
-    // in the logger (like what is done in MsgReporter)
-    if (!filename.empty())
-      {
-      VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
-      try
-        {
-        reader->SetFileName(filename);
-        reader->UpdateOutputInformation();
-        }
-      catch(itk::ExceptionObject & /*err*/)
-        {
-        this->ClearValue();
-        isOk = false;
-        break;
-        }
-
-      // everything went fine, store the object references
-      m_ReaderList->PushBack(reader);
-      m_VectorDataList->PushBack(reader->GetOutput());
-      }
-    }
+const std::string
+VECTOR_DATA_FILTER(
+  "All files (*);;"
+  "Shape file (*shp)"
+);
 
-  if( !isOk )
-    {
-    return false;
-    }
 
-  SetActive(true);
-  this->Modified();
-  return true;
-}
+/*****************************************************************************/
+InputVectorDataParameter::Pointer
+InputVectorDataListParameter
+::FromVectorData( VectorDataType * data )
+{
+  assert( data!=nullptr );
 
+  InputVectorDataParameter::Pointer p;
 
-void
-InputVectorDataListParameter::AddNullElement()
-{
-  m_ReaderList->PushBack(ITK_NULLPTR);
-  m_VectorDataList->PushBack(ITK_NULLPTR);
-  SetActive(false);
-  this->Modified();
+  return FromVectorData( p, data );
 }
 
-bool
-InputVectorDataListParameter::AddFromFileName(const std::string & filename)
+/*****************************************************************************/
+InputVectorDataParameter::Pointer &
+InputVectorDataListParameter
+::FromVectorData( InputVectorDataParameter::Pointer & parameter,
+		  VectorDataType * data )
 {
-  // TODO : when the logger will be available, redirect the exception
-  // in the logger (like what is done in MsgReporter)
-  if (!filename.empty())
-    {
-    VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
-    reader->SetFileName(filename);
-    try
+  return
+    FromData(
+      parameter,
+      data,
+      []( auto p, auto d ) -> void
       {
-      reader->UpdateOutputInformation();
-      }
-    catch(itk::ExceptionObject & /*err*/)
-      {
-      this->ClearValue();
-      return false;
-      }
+        assert( p );
 
-    // everything went fine, store the object references
-    m_ReaderList->PushBack(reader);
-    m_VectorDataList->PushBack(reader->GetOutput());
-    SetActive(true);
-    this->Modified();
-    return true;
-    }
-
-  return false;
+	p->SetVectorData( d );
+      },
+      "Vector-data filename"
+    );
 }
 
-bool
-InputVectorDataListParameter::SetNthFileName( const unsigned int id, const std::string & filename )
+/*****************************************************************************/
+InputVectorDataListParameter
+::InputVectorDataListParameter() :
+  m_VectorDataList( VectorDataListType::New() )
 {
-  if( m_ReaderList->Size()<id )
-    {
-    itkExceptionMacro(<< "No vectordata "<<id<<". Only "<<m_ReaderList->Size()<<" vector data available.");
-    }
-
-  // TODO : when the logger will be available, redirect the exception
-  // in the logger (like what is done in MsgReporter)
-  if (!filename.empty())
-    {
-    VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
-    reader->SetFileName(filename);
-    try
-      {
-      reader->UpdateOutputInformation();
-      }
-    catch(itk::ExceptionObject &)
-      {
-      this->ClearValue();
-      return false;
-      }
-
-    m_ReaderList->SetNthElement(id, reader);
-    m_VectorDataList->SetNthElement(id, reader->GetOutput());
-
-    this->Modified();
-    return true;
-    }
-
-  return false;
+  SetName( "Input VectorData List" );
+  SetKey( "vdList" );
 }
 
-
-std::vector<std::string>
-InputVectorDataListParameter::GetFileNameList() const
+/*****************************************************************************/
+InputVectorDataListParameter
+::~InputVectorDataListParameter()
 {
-  if (m_ReaderList)
-    {
-    std::vector<std::string> filenames;
-    for(unsigned int i=0; i<m_ReaderList->Size(); i++)
-      {
-      if( m_ReaderList->GetNthElement(i) )
-        filenames.push_back( m_ReaderList->GetNthElement(i)->GetFileName() );
-      }
-
-    return filenames;
-    }
-
-  itkExceptionMacro(<< "No filename value");
 }
 
+/*****************************************************************************/
+const VectorDataListType *
+InputVectorDataListParameter
+::GetVectorDataList() const
+{
+  return
+    const_cast< InputVectorDataListParameter * >( this )
+    ->GetVectorDataList();
+}
 
-std::string
-InputVectorDataListParameter::GetNthFileName( unsigned int i ) const
+/*****************************************************************************/
+VectorDataListType *
+InputVectorDataListParameter
+::GetVectorDataList()
 {
-  if (m_ReaderList)
-    {
-    if(m_ReaderList->Size()<i)
+  return
+    GetObjectList(
+      m_VectorDataList,
+      []( auto param ) -> auto
       {
-      itkExceptionMacro(<< "No vector data "<<i<<". Only "<<m_ReaderList->Size()<<" vector data available.");
-      }
+        assert( param );
 
-    return m_ReaderList->GetNthElement(i)->GetFileName();
-    }
-
-  itkExceptionMacro(<< "No filename value");
+	return param->GetVectorData();
+      }
+    );
 }
 
-VectorDataListType*
-InputVectorDataListParameter::GetVectorDataList() const
+/*****************************************************************************/
+const VectorDataType *
+InputVectorDataListParameter
+::GetNthVectorData( std::size_t i )
 {
-  return m_VectorDataList;
-}
+  assert( i<m_Parameters.size() );
+  assert( !m_Parameters[ i ].IsNull() );
+  assert( m_Parameters[ i ]->GetVectorData()!=nullptr );
 
-VectorDataType*
-InputVectorDataListParameter::GetNthVectorData(unsigned int i) const
-{
-  if(m_VectorDataList->Size()<i)
-    {
-    itkExceptionMacro(<< "No vector data "<<i<<". Only "<<m_VectorDataList->Size()<<" vector data available.");
-    }
-  return m_VectorDataList->GetNthElement(i);
+  return m_Parameters[ i ]->GetVectorData();
 }
 
+/*****************************************************************************/
 void
-InputVectorDataListParameter::SetVectorDataList(VectorDataListType* vdList)
+InputVectorDataListParameter
+::SetVectorDataList( VectorDataListType * vdList )
 {
-  // Check input availability
-  // TODO : when the logger will be available, redirect the exception
-  // in the logger (like what is done in MsgReporter)
-  try
+  assert( vdList!=nullptr );
+  assert( !m_VectorDataList.IsNull() );
+
+  SetObjectList(
+    *m_VectorDataList,
+    *vdList,
+    //
+    [ this ]( auto p, auto vd ) -> auto
     {
-    for(unsigned int i=0; i<vdList->Size(); i++)
-      {
-      vdList->GetNthElement( i )->UpdateOutputInformation();
-      }
-    }
-  catch(itk::ExceptionObject &)
+      this->FromVectorData( p, vd );
+    },
+    //
+    []( auto p ) -> auto
     {
-    return;
-    }
+      assert( p );
 
-  m_VectorDataList = vdList;
-  m_ReaderList = VectorDataFileReaderListType::Pointer();
-  for(unsigned int i=0; i<m_VectorDataList->Size(); i++)
-    {
-    m_ReaderList->PushBack( VectorDataFileReaderType::Pointer() );
+      return p->GetVectorData();
     }
-
-  SetActive(true);
-  this->Modified();
+  );
 }
 
+/*****************************************************************************/
 void
-InputVectorDataListParameter::AddVectorData(VectorDataType* vectorData)
+InputVectorDataListParameter
+::AddVectorData( VectorDataType * vectorData )
 {
-  // Check input availability
-  // TODO : when the logger will be available, redirect the exception
-  // in the logger (like what is done in MsgReporter)
-  try
-    {
-    vectorData->UpdateOutputInformation();
-    }
-  catch(itk::ExceptionObject &)
+  AddData(
+    vectorData,
+    [ this ]( auto d ) -> auto
     {
-    return;
+      return this->FromVectorData( d );
     }
-
-  m_VectorDataList->PushBack( vectorData );
-  m_ReaderList->PushBack( VectorDataFileReaderType::Pointer() );
-
-  this->Modified();
+  );
 }
 
-bool
-InputVectorDataListParameter::HasValue() const
+/*****************************************************************************/
+void
+InputVectorDataListParameter
+::ClearValue()
 {
-  if (m_VectorDataList->Size() == 0)
-    {
-    return false;
-    }
+  Superclass::ClearValue();
 
-  bool res(true);
-  unsigned int i(0);
-  while (i < m_VectorDataList->Size() && res == true)
-    {
-    res = m_VectorDataList->GetNthElement(i).IsNotNull();
-    i++;
-    }
+  assert( m_VectorDataList );
 
-  return res;
+  m_VectorDataList->Clear();
 }
 
+/*****************************************************************************/
+Role
+InputVectorDataListParameter
+::GetDirection() const
+{
+  return Role_Input;
+}
 
-void
-InputVectorDataListParameter::Erase( unsigned int id )
+/*****************************************************************************/
+const std::string &
+InputVectorDataListParameter
+::GetFilenameFilter() const
 {
-  if(m_VectorDataList->Size()<id)
-    {
-    itkExceptionMacro(<< "No vector data "<<id<<". Only "<<m_VectorDataList->Size()<<" vector data available.");
-    }
+  return VECTOR_DATA_FILTER;
+}
 
-  m_VectorDataList->Erase( id );
-  m_ReaderList->Erase( id );
+/*****************************************************************************/
+const std::string &
+InputVectorDataListParameter
+::ToString( const ParameterType::Pointer & p ) const
+{
+  assert( !p.IsNull() );
 
-  this->Modified();
+  return p->GetFileName();
 }
 
-void
-InputVectorDataListParameter::ClearValue()
+/*****************************************************************************/
+const InputVectorDataListParameter::ParameterType::Pointer &
+InputVectorDataListParameter
+::FromString( const ParameterType::Pointer & p,
+	      const std::string & s ) const
 {
-  m_VectorDataList->Clear();
-  m_ReaderList->Clear();
+  assert( !p.IsNull() );
+
+  p->SetFromFileName( s );
 
-  SetActive(false);
-  this->Modified();
+  return p;
 }
 
 
 }
-}
 
+}
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataParameter.cxx
index ee3b255..f60cf29 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputVectorDataParameter.cxx
@@ -43,53 +43,37 @@ InputVectorDataParameter::SetFromFileName(const std::string& filename)
   // First clear previous file chosen
   this->ClearValue();
 
-  // TODO : when the logger will be available, redirect the exception
-  // in the logger (like what is done in MsgReporter)
-  if (!filename.empty()
-      && itksys::SystemTools::FileExists(filename.c_str()))
-    {
-    VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
-    try
-      {
-      reader->SetFileName(filename);
-      reader->UpdateOutputInformation();
-      }
-    catch(itk::ExceptionObject & /*err*/)
-      {
-      return false;
-      }
+  // No file existence is done here :
+  m_FileName = filename;
+  SetActive( true );
 
-    // the specified filename is valid => store the value
-    m_FileName = filename;
-    SetActive(true);
-    return true;
-    }
- return false;
+  return true;
 }
 
 
-VectorDataType*
+const VectorDataType *
+InputVectorDataParameter
+::GetVectorData() const
+{
+  return const_cast< InputVectorDataParameter * >( this )->GetVectorData();
+}
+
+VectorDataType *
 InputVectorDataParameter::GetVectorData()
 {
   // 2 cases : the user sets a filename vs. the user sets a vector data
   //////////////////////// Filename case:
-  if (!m_FileName.empty())
+  if (!m_FileName.empty() && m_PreviousFileName!=m_FileName)
     {
-    //typedef otb::ImageFileReader<TOutputImage> ReaderType;
-    //typename ReaderType::Pointer reader = ReaderType::New();
-    m_Reader = VectorDataFileReaderType::New();
-    m_Reader->SetFileName(m_FileName);
-    try
-      {
-      // Update the viewer here to load the file => no streaming for VectorData
-      m_Reader->Update();
-      }
-    catch (itk::ExceptionObject &)
-      {
-      this->ClearValue();
-      }
+    VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
+    reader->SetFileName(m_FileName);
+    // Update the viewer here to load the file => no streaming for VectorData
+    reader->Update();
+
+    m_VectorData = reader->GetOutput();
+    m_Reader = reader;
 
-    m_VectorData = m_Reader->GetOutput();
+    m_PreviousFileName = m_FileName;
     }
   //////////////////////// VectorData case:
   else
@@ -97,7 +81,7 @@ InputVectorDataParameter::GetVectorData()
     if (m_VectorData.IsNull())
       {
       // Else : error
-      itkExceptionMacro("No input vector data or filename detected...");
+      itkExceptionMacro("No input vector data detected...");
       }
     }
 
@@ -131,5 +115,3 @@ InputVectorDataParameter::ClearValue()
 
 }
 }
-
-
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx
index 364fb60..4931916 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperMapProjectionParametersHandler.cxx
@@ -33,8 +33,8 @@ namespace Wrapper
 
 void MapProjectionParametersHandler::AddMapProjectionParameters( Application::Pointer app, const std::string & key)
 {
-  app->AddParameter(ParameterType_Choice, key, "Output Cartographic Map Projection");
-  app->SetParameterDescription(key,"Parameters of the output map projection to be used.");
+  app->AddParameter(ParameterType_Choice, key, "Map Projection");
+  app->SetParameterDescription(key,"Defines the map projection to be used.");
 
   // utm
   std::ostringstream oss;
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
index b2f2d8d..2790bdc 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx
@@ -98,6 +98,28 @@ std::string OutputImageParameter::ConvertPixelTypeToString(ImagePixelType type)
   return ret;
 }
 
+bool
+OutputImageParameter::ConvertStringToPixelType(const std::string &value, ImagePixelType &type)
+{
+  if (value == "uint8")
+    type = ImagePixelType_uint8;
+  else if (value == "int16")
+    type = ImagePixelType_int16;
+  else if (value == "uint16")
+    type = ImagePixelType_uint16;
+  else if (value == "int32")
+    type = ImagePixelType_int32;
+  else if (value == "uint32")
+    type = ImagePixelType_uint32;
+  else if (value == "float")
+    type = ImagePixelType_float;
+  else if (value == "double")
+    type = ImagePixelType_double;
+  else
+    return false;
+  return true;
+}
+
 void OutputImageParameter::InitializeWriters()
 {
   m_UInt8Writer = UInt8WriterType::New();
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterList.cxx
similarity index 50%
rename from Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
rename to Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterList.cxx
index e4104cd..272f1fa 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperParameterTest.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperParameterList.cxx
@@ -18,37 +18,18 @@
  * limitations under the License.
  */
 
-#if defined(_MSC_VER)
-#pragma warning ( disable : 4786 )
-#endif
+#include "otbWrapperParameterList.h"
 
-#include "otbWrapperParameter.h"
 
-int otbWrapperParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[])
+namespace otb
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
 
-  //std::cout << parameter << std::endl;
 
-  return EXIT_SUCCESS;
-}
-
-int otbWrapperParameterTest1(int itkNotUsed(argc), char* argv[])
+namespace Wrapper
 {
-  typedef otb::Wrapper::Parameter ParameterBaseType;
-  ParameterBaseType::Pointer parameter = ParameterBaseType::New();
-
-  const std::string name = argv[1];
-
-  parameter->SetName(name);
-
-  if (name == parameter->GetName())
-    {
-    return EXIT_SUCCESS;
-    }
-  else
-    {
-    return EXIT_FAILURE;
-    }
-}
+
+
+} // End of namespace 'Wrapper'
+
+
+} // End of namespace 'otb'
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperStringListInterface.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperStringListInterface.cxx
new file mode 100644
index 0000000..3f8175e
--- /dev/null
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperStringListInterface.cxx
@@ -0,0 +1,105 @@
+/*
+ * 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 "otbWrapperStringListInterface.h"
+
+
+namespace otb
+{
+
+
+namespace Wrapper
+{
+
+const std::string
+NULL_STRING;
+
+
+/*****************************************************************************/
+void
+StringListInterface
+::AddNullElement()
+{
+  InsertNullElement();
+}
+
+
+/*****************************************************************************/
+Role
+StringListInterface
+::GetDirection( std::size_t ) const
+{
+  return GetDirection();
+}
+
+
+/*****************************************************************************/
+const std::string &
+StringListInterface
+::GetFilenameFilter( std::size_t ) const
+{
+  return GetFilenameFilter();
+}
+
+
+/*****************************************************************************/
+const std::string &
+StringListInterface
+::GetFilenameFilter() const
+{
+  return NULL_STRING;
+}
+
+/*****************************************************************************/
+bool
+StringListInterface
+::IsFilename() const
+{
+  return true;
+}
+
+/*****************************************************************************/
+void
+StringListInterface
+::Erase( std::size_t id )
+{
+  Erase( id, 1 );
+}
+
+/*****************************************************************************/
+std::size_t
+StringListInterface
+::SetStrings( const StringVector & )
+{
+  return 0;
+}
+
+/*****************************************************************************/
+std::size_t
+StringListInterface
+::GetStrings( StringVector & ) const
+{
+  return 0;
+}
+
+} // End of Namespace 'Wrapper'
+
+} // End of Namespace 'otb'
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperStringListParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperStringListParameter.cxx
new file mode 100644
index 0000000..c880f2f
--- /dev/null
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperStringListParameter.cxx
@@ -0,0 +1,133 @@
+/*
+ * 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 "otbWrapperStringListParameter.h"
+
+
+#include "otbCast.h"
+
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+
+/*****************************************************************************/
+StringListParameter
+::StringListParameter()
+{
+  SetName( "String List" );
+  SetKey( "strList" );
+}
+
+
+/*****************************************************************************/
+StringListParameter
+::~StringListParameter()
+{
+}
+
+
+/*****************************************************************************/
+void
+StringListParameter
+::SetValue( const StringListInterface::StringVector & strings )
+{
+  SetStrings( strings );
+}
+
+/*****************************************************************************/
+StringListInterface::StringVector
+StringListParameter
+::GetValue() const
+{
+  // Should get benefit of C++11 move constructor.
+  return GetFileNameList();
+}
+
+/*****************************************************************************/
+void
+StringListParameter
+::AddString( const std::string & s )
+{
+  AddFromFileName( s );
+}
+
+/*****************************************************************************/
+const std::string &
+StringListParameter
+::GetNthElement( std::size_t i ) const
+{
+  return GetNthFileName( i );
+}
+
+/*****************************************************************************/
+void
+StringListParameter
+::SetNthElement( std::size_t i, const std::string & string )
+{
+  SetNthFileName( i, string );
+}
+
+/*****************************************************************************/
+Role
+StringListParameter
+::GetDirection() const
+{
+  return GetRole();
+}
+
+/*****************************************************************************/
+bool
+StringListParameter
+::IsFilename() const
+{
+  return false;
+}
+
+/*****************************************************************************/
+const std::string &
+StringListParameter
+::ToString( const ParameterType::Pointer & p ) const
+{
+  assert( !p.IsNull() );
+
+  return p->GetValue();
+}
+
+/*****************************************************************************/
+const StringListParameter::ParameterType::Pointer &
+StringListParameter
+::FromString( const ParameterType::Pointer & p,
+	      const std::string & s ) const
+{
+  assert( !p.IsNull() );
+
+  p->SetValue( s );
+
+  return p;
+}
+
+
+}
+
+}
diff --git a/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt
index 0a5bd88..860c867 100644
--- a/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt
+++ b/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt
@@ -23,7 +23,6 @@ otb_module_test()
 set(OTBApplicationEngineTests
 otbApplicationEngineTestDriver.cxx
 otbWrapperApplicationTest.cxx
-otbWrapperParameterTest.cxx
 otbWrapperInputImageParameterTest.cxx
 otbWrapperNumericalParameterTest.cxx
 otbWrapperStringParameterTest.cxx
@@ -54,15 +53,6 @@ otb_add_test(NAME owTuApplication COMMAND otbApplicationEngineTestDriver
   otbWrapperApplicationNew
   )
 
-otb_add_test(NAME owTvParameter COMMAND otbApplicationEngineTestDriver
-  otbWrapperParameterTest1
-  "param1"
-  )
-
-otb_add_test(NAME owTuParameterNew COMMAND otbApplicationEngineTestDriver
-  otbWrapperParameterNew
-  )
-
 otb_add_test(NAME owTvInputImageParameter COMMAND otbApplicationEngineTestDriver
   otbWrapperInputImageParameterTest1
   ${INPUTDATA}/poupees.tif
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx b/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx
index f5db296..f5b3aab 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx
+++ b/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx
@@ -23,8 +23,6 @@
 void RegisterTests()
 {
   REGISTER_TEST(otbWrapperApplicationNew);
-  REGISTER_TEST(otbWrapperParameterNew);
-  REGISTER_TEST(otbWrapperParameterTest1);
   REGISTER_TEST(otbWrapperInputImageParameterNew);
   REGISTER_TEST(otbWrapperInputImageParameterTest1);
   REGISTER_TEST(otbWrapperNumericalParameterNew);
diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperApplicationDocTests.cxx b/Modules/Wrappers/ApplicationEngine/test/otbWrapperApplicationDocTests.cxx
index 1bbfbf2..6cafbaf 100644
--- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperApplicationDocTests.cxx
+++ b/Modules/Wrappers/ApplicationEngine/test/otbWrapperApplicationDocTests.cxx
@@ -99,7 +99,7 @@ int otbWrapperApplicationDocTest(int argc, char* argv[])
   otb::Wrapper::DocExampleStructure::Pointer doc = app->GetDocExample();
   if( doc->GetApplicationName() == "" )
     {
-    std::cout<<"Error in doc example: no aaplication name found."<<std::endl;
+    std::cout<<"Error in doc example: no application name found."<<std::endl;
     isOK = false;
     }
   if( doc->GetParameterList().size() == 0 )
diff --git a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
index 5d57a83..cf70dc0 100644
--- a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
+++ b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
@@ -390,7 +390,6 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters()
     const std::string paramKey(appKeyList[i]);
     std::vector<std::string> values;
 
-    Parameter::Pointer param = m_Application->GetParameterByKey(paramKey);
     ParameterType type = m_Application->GetParameterType(paramKey);
 
     const bool paramExists(m_Parser->IsAttributExists(std::string("-").append(paramKey), m_VExpression));
@@ -412,166 +411,99 @@ CommandLineLauncher::ParamResultType CommandLineLauncher::LoadParameters()
           return INVALIDNUMBEROFVALUE;
           }
 
-        // Ensure that the parameter is enabled
-        m_Application->EnableParameter(paramKey);
-
-        if (type == ParameterType_InputVectorDataList)
+        if (type == ParameterType_InputVectorDataList ||
+            type == ParameterType_InputImageList ||
+            type == ParameterType_InputFilenameList ||
+            type == ParameterType_StringList ||
+            type == ParameterType_ListView)
           {
-          dynamic_cast<InputVectorDataListParameter *> (param.GetPointer())->SetListFromFileName(values);
+          // Multiple values parameters
+          m_Application->SetParameterStringList(paramKey, values);
           }
-        else
-          if (type == ParameterType_InputImageList)
-            {
-            dynamic_cast<InputImageListParameter *> (param.GetPointer())->SetListFromFileName(values);
-            }
-          else
-            if (type == ParameterType_InputFilenameList)
-              {
-              dynamic_cast<InputFilenameListParameter *> (param.GetPointer())->SetListFromFileName(values);
-              }
-            else
-              if (type == ParameterType_StringList)
-                {
-                dynamic_cast<StringListParameter *> (param.GetPointer())->SetValue(values);
-                }
-              else
-                if (type == ParameterType_String)
-                  {
-                  dynamic_cast<StringParameter *> (param.GetPointer())->SetValue(
-                    m_Parser->GetAttributAsString(std::string("-").append(paramKey), m_VExpression) );
-                  }
-                else
-                  if (type == ParameterType_OutputImage)
-                    {
-                    m_Application->SetParameterString(paramKey, values[0]);
-                    // Check if pixel type is given
-                    if (values.size() == 2)
-                      {
-                      ImagePixelType outPixType = ImagePixelType_float;
-                      if (values[1] == "uint8")
-                        outPixType = ImagePixelType_uint8;
-                      else if (values[1] == "int16")
-                        outPixType = ImagePixelType_int16;
-                      else if (values[1] == "uint16")
-                        outPixType = ImagePixelType_uint16;
-                      else if (values[1] == "int32")
-                        outPixType = ImagePixelType_int32;
-                      else if (values[1] == "uint32")
-                        outPixType = ImagePixelType_uint32;
-                      else if (values[1] == "float")
-                        outPixType = ImagePixelType_float;
-                      else if (values[1] == "double")
-                        outPixType = ImagePixelType_double;
-                      else
-                      {
-                        std::cerr << "ERROR: Invalid output type for parameter -" << paramKey << ": " << values[1] << "." << std::endl;
-                        return WRONGPARAMETERVALUE;
-                      }
-                      dynamic_cast<OutputImageParameter *> (param.GetPointer())->SetPixelType(outPixType);
-                      }
-                    else
-                      if (values.size() > 2)
-                        {
-                        std::cerr << "ERROR: Too many values for parameter -" << paramKey << " (expected 2 or less, got " << values.size() << ")." << std::endl;
-                        return INVALIDNUMBEROFVALUE;
-                        }
-                    }
-                  else if (type == ParameterType_ComplexOutputImage)
-                    {
-                    m_Application->SetParameterString(paramKey, values[0]);
-                    // Check if pixel type is given
-                    if (values.size() == 2)
-                      {
-                      ComplexImagePixelType outPixType = ComplexImagePixelType_float;
-                      if (values[1] == "cfloat")
-                        outPixType = ComplexImagePixelType_float;
-                      else if (values[1] == "cdouble")
-                        outPixType = ComplexImagePixelType_double;
-                      else
-                      {
-                        std::cerr << "ERROR: Invalid output type for parameter -" << paramKey << ": " << values[1] << "." << std::endl;
-                        return WRONGPARAMETERVALUE;
-                      }
-                      dynamic_cast<ComplexOutputImageParameter *> (param.GetPointer())->SetComplexPixelType(outPixType);
-                      }
-                    else
-                      if (values.size() != 1 && values.size() != 2)
-                        {
-                        std::cerr << "ERROR: Invalid number of value for: \"" << paramKey
-                                  << "\", invalid number of values " << values.size() << std::endl;
-                        return INVALIDNUMBEROFVALUE;
-                        }
-                    }
-                  else
-                    if (type == ParameterType_ListView)
-                      {
-                      
-                      ListViewParameter * tmpLV = dynamic_cast<ListViewParameter *>(param.GetPointer());
-
-                      if(tmpLV->GetSingleSelection() && values.size() > 1)
-                        {
-                        std::cerr << "ERROR: Invalid number of value for: \"" << paramKey
-                                  << "\", invalid number of values " << values.size() << std::endl;
-                        return INVALIDNUMBEROFVALUE;
-                        }
-                      
-                      tmpLV->SetSelectedNames(values);
-                      }
-                    else
-                      if(values.size() != 1)
-                        {
-                        // Handle space in filename. Only for input
-                        // files or directories
-                        if (type == ParameterType_Directory         || type == ParameterType_InputFilename ||
-                            type == ParameterType_ComplexInputImage ||
-                            type == ParameterType_InputImage ||
-                            type == ParameterType_InputVectorData   || type == ParameterType_OutputVectorData )
-                          {
-                          for(unsigned int j=1; j<values.size(); j++)
-                            {
-                            values[0].append(" ");
-                            values[0].append(values[j]);
-                            }
-                          }
-                        else if (!param->GetAutomaticValue())
-                          {
-                          std::cerr << "ERROR: Invalid number of value for: \"" << paramKey << "\", must have 1 value, not  "
-                                    << values.size() << std::endl;
-                          return INVALIDNUMBEROFVALUE;
-                          }
-                        }
-        // Single value parameter
-        if (type == ParameterType_Choice || type == ParameterType_Float || type == ParameterType_Int ||
-            type == ParameterType_Radius || type == ParameterType_Directory || type == ParameterType_InputFilename ||
+        else if (type == ParameterType_Choice ||
+            type == ParameterType_Float ||
+            type == ParameterType_Int ||
+            type == ParameterType_Radius ||
+            type == ParameterType_Directory ||
+            type == ParameterType_String ||
+            type == ParameterType_InputFilename ||
             type == ParameterType_OutputFilename ||
-            type == ParameterType_ComplexInputImage || type == ParameterType_InputImage ||
+            type == ParameterType_ComplexInputImage ||
+            type == ParameterType_InputImage ||
+            type == ParameterType_OutputImage ||
             type == ParameterType_ComplexOutputImage ||
             type == ParameterType_InputVectorData ||
-            type == ParameterType_OutputVectorData || type == ParameterType_RAM ||
+            type == ParameterType_OutputVectorData ||
+            type == ParameterType_RAM ||
             type == ParameterType_OutputProcessXML) // || type == ParameterType_InputProcessXML)
           {
+          // Single value parameter
           m_Application->SetParameterString(paramKey, values[0]);
-          }
-        else
-          if (type == ParameterType_Empty)
+
+          if (type == ParameterType_OutputImage)
             {
-            if (values[0] == "1" || values[0] == "true")
+            // Check if pixel type is given
+            if (values.size() == 2)
               {
-              dynamic_cast<EmptyParameter *> (param.GetPointer())->SetActive(true);
+              ImagePixelType pixType = ImagePixelType_float;
+              if ( !OutputImageParameter::ConvertStringToPixelType(values[1],pixType) )
+                {
+                std::cerr << "ERROR: Invalid output type for parameter -" <<
+                  paramKey << ": " << values[1] << "." << std::endl;
+                return WRONGPARAMETERVALUE;
+                }
+              m_Application->SetParameterOutputImagePixelType(paramKey, pixType);
               }
-            else
-              if (values[0] == "0" || values[0] == "false")
+            else if (values.size() > 2)
+              {
+              std::cerr << "ERROR: Too many values for parameter -" <<
+                paramKey << " (expected 2 or 1, got " << values.size() << ")."
+                << std::endl;
+              return INVALIDNUMBEROFVALUE;
+              }
+            }
+          else if (type == ParameterType_ComplexOutputImage)
+            {
+            // Check if pixel type is given
+            if (values.size() == 2)
+              {
+              ComplexImagePixelType cpixType = ComplexImagePixelType_float;
+              if ( !ComplexOutputImageParameter::ConvertStringToPixelType(values[1],cpixType) )
                 {
-                dynamic_cast<EmptyParameter *> (param.GetPointer())->SetActive(false);
+                std::cerr << "ERROR: Invalid output type for parameter -" <<
+                  paramKey << ": " << values[1] << "." << std::endl;
+                return WRONGPARAMETERVALUE;
                 }
-             else
+              m_Application->SetParameterComplexOutputImagePixelType(paramKey, cpixType);
+              }
+            else if (values.size() > 2)
               {
-              std::cerr << "ERROR: Wrong value for parameter -" << paramKey << "." << std::endl;
-              return WRONGPARAMETERVALUE;
+              std::cerr << "ERROR: Too many values for parameter: -" << paramKey
+                        << " (expected 2 or 1, got " << values.size() << ")." <<std::endl;
+              return INVALIDNUMBEROFVALUE;
               }
             }
-        // Update the flag UserValue
-        param->SetUserValue(true);
+          }
+        else if (type == ParameterType_Empty)
+          {
+          // Set UserValue flag specific for EmptyParameter, beware that it
+          // should be done before Enable/Disable because SetParameterUserValue()
+          // may enable it by default
+          m_Application->SetParameterUserValue(paramKey,true);
+          if (values[0] == "1" || values[0] == "true")
+            {
+            m_Application->EnableParameter(paramKey);
+            }
+          else if (values[0] == "0" || values[0] == "false")
+            {
+            m_Application->DisableParameter(paramKey);
+            }
+          else
+            {
+            std::cerr << "ERROR: Wrong value for parameter -" << paramKey << "." << std::endl;
+            return WRONGPARAMETERVALUE;
+            }
+          }
         // Call the DoUpdateParameter to update dependent params
         m_Application->UpdateParameters();
         }
@@ -668,12 +600,6 @@ void CommandLineLauncher::DisplayHelp(bool longHelp)
   for(unsigned int i=0; i<maxKeySize-std::string("progress").size(); i++)
     bigKey.append(" ");
 
-  std::cerr << "        -"<<bigKey<<" <boolean>        Report progress " << std::endl;
-  bigKey = "help";
-  for(unsigned int i=0; i<maxKeySize-std::string("help").size(); i++)
-    bigKey.append(" ");
-  std::cerr << "        -"<<bigKey<<" <string list>    Display long help (empty list), or help for given parameters keys" << std::endl;
-
   for (unsigned int i = 0; i < nbOfParam; i++)
     {
     Parameter::Pointer param = m_Application->GetParameterByKey(appKeyList[i]);
@@ -683,6 +609,12 @@ void CommandLineLauncher::DisplayHelp(bool longHelp)
       }
     }
 
+  std::cerr << "        -"<<bigKey<<" <boolean>        Report progress " << std::endl;
+  bigKey = "help";
+  for(unsigned int i=0; i<maxKeySize-std::string("help").size(); i++)
+    bigKey.append(" ");
+  std::cerr << "        -"<<bigKey<<" <string list>    Display long help (empty list), or help for given parameters keys" << std::endl;
+
   std::cerr<<std::endl;
   //std::string cl(m_Application->GetCLExample());
 
@@ -721,11 +653,9 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer &
   // Display the type the type
   ParameterType type = m_Application->GetParameterType(paramKey);
 
-  // Discard Group parameters (they don't need a value)
-  if (type == ParameterType_Group)
-    {
-    return "";
-    }
+  std::string bigKey = paramKey;
+  
+  unsigned int maxKeySize = GetMaxKeySize();
 
   bool singleSelectionForListView = false;
 
@@ -745,10 +675,6 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer &
     {
     oss << "        ";
     }
-
-  std::string bigKey = paramKey;
-
-  unsigned int maxKeySize = GetMaxKeySize();
   
   for(unsigned int i=0; i<maxKeySize-paramKey.size(); i++)
     bigKey.append(" ");
@@ -784,6 +710,10 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer &
     {
     oss << "<string list>   ";
     }
+  else if(type == ParameterType_Group)
+    {
+    oss<< "<group>         ";
+    }
   else
     itkExceptionMacro("Not handled parameter type.");
 
@@ -835,30 +765,33 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer &
       }
     }
 
-  if(m_Application->IsMandatory(paramKey))
+  if(type != ParameterType_Group)
     {
-    oss<<" (mandatory";
-    }
-  else
-    {
-    oss<<" (optional";
 
-    if(m_Application->IsParameterEnabled(paramKey))
+    if(m_Application->IsMandatory(paramKey))
       {
-      oss<<", on by default";
+      oss<<" (mandatory";
       }
     else
       {
-      oss<<", off by default";
-      }
-    }
+      oss<<" (optional";
 
-  if(m_Application->HasValue(paramKey))
-    {
-    oss<<", default value is "<<m_Application->GetParameterAsString(paramKey);
+      if(m_Application->IsParameterEnabled(paramKey))
+        {
+        oss<<", on by default";
+        }
+      else
+        {
+        oss<<", off by default";
+        }
+      }
+    
+    if(m_Application->HasValue(paramKey))
+      {
+      oss<<", default value is "<<m_Application->GetParameterAsString(paramKey);
+      }
+    oss<<")";
     }
-  oss<<")";
-
   oss << std::endl;
 
   if(longHelp)
@@ -869,8 +802,25 @@ std::string CommandLineLauncher::DisplayParameterHelp(const Parameter::Pointer &
     oss<<"                   ";
     oss<<m_Application->GetParameterDescription(paramKey)<<std::endl;
 
+
+    if (type == ParameterType_Choice)
+      {
+      std::vector<std::string> keys = dynamic_cast<ChoiceParameter*>(param.GetPointer())->GetChoiceKeys();
+      std::vector<std::string> names = dynamic_cast<ChoiceParameter*>(param.GetPointer())->GetChoiceNames();
+      
+      auto keyIt = keys.begin();
+      auto nameIt = names.begin();
+      
+      for( ; keyIt!=keys.end()&&nameIt!=names.end();++keyIt,++nameIt)
+        {
+        oss << "        ";
+        for(unsigned int i=0; i<maxKeySize;++i)
+          oss<<" ";
+        oss<<"                   ";
+        oss<<"- "<<*nameIt<<" ("<<*keyIt<<"): "<<m_Application->GetParameterDescription(paramKey+"."+(*keyIt))<<std::endl;
+        }
+      }
     }
-  
   return oss.str();
 }
 
diff --git a/Modules/Wrappers/QtWidget/CMakeLists.txt b/Modules/Wrappers/QtWidget/CMakeLists.txt
index 4162b8d..7776d93 100644
--- a/Modules/Wrappers/QtWidget/CMakeLists.txt
+++ b/Modules/Wrappers/QtWidget/CMakeLists.txt
@@ -21,4 +21,10 @@
 project(OTBQtWidget)
 
 set(OTBQtWidget_LIBRARIES OTBQtWidget)
+
+# folder where ui headers are generated
+set( OTBQtWidget_INCLUDE_DIRS
+  ${OTBQtWidget_BINARY_DIR}/src
+  )
+
 otb_module_impl()
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputFilenameListParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputFilenameListParameter.h
index 0fd0399..9a64d46 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputFilenameListParameter.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputFilenameListParameter.h
@@ -22,59 +22,43 @@
 #define otbWrapperQtWidgetInputFilenameListParameter_h
 
 #include <QtGui>
+
 #ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
-#include "otbQtFileSelectionWidget.h"
+#  include "otbWrapperQtWidgetParameterList.h"
 #endif //tag=QT4-boost-compatibility
 
 namespace otb
 {
+
 namespace Wrapper
 {
 
+class InputFilenameListParameter;
+
 /** \class QtWidgetInputFilenameListParameter
  * \brief
  *
  * \ingroup OTBQtWidget
  */
-class OTBQtWidget_EXPORT QtWidgetInputFilenameListParameter : public QtWidgetParameterBase
+class OTBQtWidget_EXPORT QtWidgetInputFilenameListParameter :
+    public QtWidgetParameterList
 {
   Q_OBJECT
-public:
-  QtWidgetInputFilenameListParameter(InputFilenameListParameter*, QtWidgetModel*);
-  ~QtWidgetInputFilenameListParameter() ITK_OVERRIDE;
-
-
-signals:
-  void Change();
-  void FileSelectionWidgetAdded( QWidget * );
 
-protected slots:
-  //void SetFileName( const QString& value );
-  //virtual void SelectFile();
-  virtual void UpFile();
-  virtual void DownFile();
-  virtual void AddFile();
-  virtual void SuppressFile();
-  virtual void EraseFile();
-  virtual void UpdateFilenameList();
+//
+// Public methods.
+public:
+  QtWidgetInputFilenameListParameter( InputFilenameListParameter *, QtWidgetModel * );
+  ~QtWidgetInputFilenameListParameter() override;
 
+//
+// Private methods.
 private:
-  QtWidgetInputFilenameListParameter(const QtWidgetInputFilenameListParameter&); //purposely not implemented
-  void operator=(const QtWidgetInputFilenameListParameter&); //purposely not implemented
-
-  void DoCreateWidget() ITK_OVERRIDE;
-
-  void DoUpdateGUI() ITK_OVERRIDE;
-
-  void RecreateFilenameList();
-  void UpdateFileList( std::map<unsigned int, unsigned int> idMap );
-
-  InputFilenameListParameter::Pointer m_InputFilenameListParam;
+  // purposely not implemented
+  QtWidgetInputFilenameListParameter( const QtWidgetInputFilenameListParameter & );
 
-  QHBoxLayout * m_HLayout;
-  QVBoxLayout * m_FileLayout;
-  QScrollArea * m_Scroll;
-  std::vector<QtFileSelectionWidget *> m_FileSelectionList;
+  //  purposely not implemented
+  void operator = ( const QtWidgetInputFilenameListParameter & );
 };
 
 
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageListParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageListParameter.h
index e4e5b0c..a975ded 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageListParameter.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputImageListParameter.h
@@ -21,60 +21,49 @@
 #ifndef otbWrapperQtWidgetInputImageListParameter_h
 #define otbWrapperQtWidgetInputImageListParameter_h
 
+
 #include <QtGui>
-#ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
-#include "otbQtFileSelectionWidget.h"
-#endif //tag=QT4-boost-compatibility
+
+
+#include "OTBQtWidgetExport.h"
+#include "otbWrapperQtWidgetParameterList.h"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
 
+
+class InputImageListParameter;
+
+
 /** \class QtWidgetInputImageListParameter
  * \brief
  *
  * \ingroup OTBQtWidget
  */
-class OTBQtWidget_EXPORT QtWidgetInputImageListParameter : public QtWidgetParameterBase
+class OTBQtWidget_EXPORT QtWidgetInputImageListParameter :
+    public QtWidgetParameterList
 {
-  Q_OBJECT
-public:
-  QtWidgetInputImageListParameter(InputImageListParameter*, QtWidgetModel*);
-  ~QtWidgetInputImageListParameter() ITK_OVERRIDE;
-
+  Q_OBJECT;
 
-signals:
-  void Change();
-  void FileSelectionWidgetAdded( QWidget * );
-
-protected slots:
-  //void SetFileName( const QString& value );
-  //virtual void SelectFile();
-  virtual void UpFile();
-  virtual void DownFile();
-  virtual void AddFile();
-  virtual void SuppressFile();
-  virtual void EraseFile();
-  virtual void UpdateImageList();
+//
+// Public methods.
+public:
+  QtWidgetInputImageListParameter( InputImageListParameter *, QtWidgetModel * );
+  ~QtWidgetInputImageListParameter() override;
 
+//
+// Private methods.
 private:
-  QtWidgetInputImageListParameter(const QtWidgetInputImageListParameter&); //purposely not implemented
-  void operator=(const QtWidgetInputImageListParameter&); //purposely not implemented
-
-  void DoCreateWidget() ITK_OVERRIDE;
-
-  void DoUpdateGUI() ITK_OVERRIDE;
-
-  void RecreateImageList();
-  void UpdateFileList( std::map<unsigned int, unsigned int> idMap );
-
-  InputImageListParameter::Pointer m_InputImageListParam;
+  // Purposely not implemented
+  QtWidgetInputImageListParameter( const QtWidgetInputImageListParameter & );
 
-  QHBoxLayout * m_HLayout;
-  QVBoxLayout * m_FileLayout;
-  QScrollArea * m_Scroll;
-  std::vector<QtFileSelectionWidget *> m_FileSelectionList;
+  // Purposely not implemented
+  void operator = ( const QtWidgetInputImageListParameter & );
 };
 
 
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputVectorDataListParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputVectorDataListParameter.h
index 4a43f7a..7101cee 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputVectorDataListParameter.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetInputVectorDataListParameter.h
@@ -21,61 +21,52 @@
 #ifndef otbWrapperQtWidgetInputVectorDataListParameter_h
 #define otbWrapperQtWidgetInputVectorDataListParameter_h
 
+
 #include <QtGui>
+
+
 #ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
-#include "otbWrapperInputVectorDataListParameter.h"
-#include "otbQtFileSelectionWidget.h"
+#  include "otbWrapperQtWidgetParameterList.h"
 #endif //tag=QT4-boost-compatibility
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
 
+
+class InputVectorDataListParameter;
+
+
 /** \class QtWidgetInputVectorDataListParameter
  * \brief
  *
  * \ingroup OTBQtWidget
  */
-class OTBQtWidget_EXPORT QtWidgetInputVectorDataListParameter : public QtWidgetParameterBase
+class OTBQtWidget_EXPORT QtWidgetInputVectorDataListParameter
+  : public QtWidgetParameterList
 {
-  Q_OBJECT
-public:
-  QtWidgetInputVectorDataListParameter(InputVectorDataListParameter*, QtWidgetModel*);
-  ~QtWidgetInputVectorDataListParameter() ITK_OVERRIDE;
+  Q_OBJECT;
 
+//
+// Public methods.
+public:
+  QtWidgetInputVectorDataListParameter( InputVectorDataListParameter *,
+					QtWidgetModel * );
 
-signals:
-  void Change();
-  void FileSelectionWidgetAdded( QWidget * );
+  ~QtWidgetInputVectorDataListParameter() override;
 
-protected slots:
-  //void SetFileName( const QString& value );
-  //virtual void SelectFile();
-  virtual void UpFile();
-  virtual void DownFile();
-  virtual void AddFile();
-  virtual void SuppressFile();
-  virtual void EraseFile();
-  virtual void UpdateVectorDataList();
 
+//
+// Private methods.
 private:
-  QtWidgetInputVectorDataListParameter(const QtWidgetInputVectorDataListParameter&); //purposely not implemented
-  void operator=(const QtWidgetInputVectorDataListParameter&); //purposely not implemented
-
-  void DoCreateWidget() ITK_OVERRIDE;
-
-  void DoUpdateGUI() ITK_OVERRIDE;
-
-  void RecreateVectorDataList();
-  void UpdateFileList( std::map<unsigned int, unsigned int> idMap );
-
-  InputVectorDataListParameter::Pointer m_InputVectorDataListParam;
+  // Purposely not implemented
+  QtWidgetInputVectorDataListParameter( const QtWidgetInputVectorDataListParameter & );
 
-  QHBoxLayout * m_HLayout;
-  QVBoxLayout * m_FileLayout;
-  QScrollArea * m_Scroll;
-  std::vector<QtFileSelectionWidget *> m_FileSelectionList;
+  // Purposely not implemented
+  void operator = ( const QtWidgetInputVectorDataListParameter & );
 };
 
 
diff --git a/Modules/Visualization/MonteverdiGui/include/mvdLayerStackItemModel.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetListEditItemModel.h
similarity index 66%
copy from Modules/Visualization/MonteverdiGui/include/mvdLayerStackItemModel.h
copy to Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetListEditItemModel.h
index 3a3fc21..34000eb 100644
--- a/Modules/Visualization/MonteverdiGui/include/mvdLayerStackItemModel.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetListEditItemModel.h
@@ -18,14 +18,17 @@
  * limitations under the License.
  */
 
-#ifndef mvdLayerStackItemModel_h
-#define mvdLayerStackItemModel_h
+#ifndef otbListEditItemModel_h
+#define otbListEditItemModel_h
 
 //
 // Configuration include.
 //// Included at first position before any other ones.
-#include "ConfigureMonteverdi.h"
+#ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
+#include "otbMacro.h"
+#endif //tag=QT4-boost-compatibility
 
+#include "OTBQtWidgetExport.h"
 
 /*****************************************************************************/
 /* INCLUDE SECTION                                                           */
@@ -43,10 +46,9 @@
 
 //
 // OTB includes (sorted by alphabetic order)
-#include "OTBMonteverdiGUIExport.h"
+
 //
 // Monteverdi includes (sorted by alphabetic order)
-#include "mvdTypes.h"
 
 
 /*****************************************************************************/
@@ -56,27 +58,31 @@
 // External classes pre-declaration.
 namespace
 {
+
 }
 
-namespace mvd
+namespace otb
+{
+
+namespace Wrapper
 {
+
 //
 // Internal classes pre-declaration.
-class AbstractImageModel;
-class AbstractLayerModel;
-class StackedLayerModel;
+class StringListInterface;
+
 
 /*****************************************************************************/
 /* CLASS DEFINITION SECTION                                                  */
 
 /**
- * \class LayerStackItemModel
+ * \class ListEditItemModel
  *
- * \ingroup OTBMonteverdiGUI
+ * \ingroup OTBQtWidget
  *
  * \brief WIP.
  */
-class OTBMonteverdiGUI_EXPORT LayerStackItemModel :
+class OTBQtWidget_EXPORT ListEditItemModel :
     public QAbstractItemModel
 {
 
@@ -94,57 +100,29 @@ public:
   {
     COLUMN_NONE = -1,
     //
-    COLUMN_PROJ = 0,
-    COLUMN_RESOLUTION,
-    COLUMN_NAME,
-    COLUMN_EFFECT,
-    COLUMN_I,
-    COLUMN_J,
-    COLUMN_R,
-    COLUMN_G,
-    COLUMN_B,
-    COLUMN_X,
-    COLUMN_Y,
+    COLUMN_NAME = 0,
+    // COLUMN_BROWSE = 1,
     //
     COLUMN_COUNT,
   };
 
-  /*
-  enum ItemRole
+  enum UserRole
   {
-    ITEM_ROLE_INDEX = Qt::UserRole + 1
-    ITEM_ROLE_NAME,
-    ITEM_ROLE_I,
-    ITEM_ROLE_J,
-    ITEM_ROLE_R,
-    ITEM_ROLE_G,
-    ITEM_ROLE_B,
-    ITEM_ROLE_X,
-    ITEM_ROLE_Y,
-    //
-    ITEM_ROLE_NONE,
-    //
-    ITEM_ROLE_COUNT = ITEM_ROLE_NONE - Qt::UserRole,
+    USER_ROLE_NONE = Qt::UserRole,
+    USER_ROLE_DIRECTION,
+    USER_ROLE_FILTER,
   };
-  */
 
 //
 // Public methods.
 public:
 
   /** \brief Constructor. */
-  LayerStackItemModel( QObject* p =NULL );
+  ListEditItemModel( StringListInterface *,
+		     QObject * p = nullptr );
 
   /** \brief Destructor. */
-  ~LayerStackItemModel() ITK_OVERRIDE;
-
-  /**
-   */
-  static const AbstractLayerModel * GetLayer( const QModelIndex & );
-
-  /**
-   */
-  void SetStack( StackedLayerModel * );
+  ~ListEditItemModel() ITK_OVERRIDE;
 
   //
   // QAbstractItemModel overloads.
@@ -157,20 +135,9 @@ public:
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#data
    */
-  
-    QVariant
-    data( const QModelIndex & index, int role = Qt::DisplayRole ) const ITK_OVERRIDE;
-
-  /**
-   * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#dropMimeData
-   */
-  
-    bool
-    dropMimeData( const QMimeData * data,
-                  Qt::DropAction action,
-                  int row,
-                  int column,
-                  const QModelIndex & p ) ITK_OVERRIDE;
+  QVariant
+    data( const QModelIndex & index,
+	  int role = Qt::DisplayRole ) const ITK_OVERRIDE;
 
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#flags
@@ -188,35 +155,30 @@ public:
   QVariant headerData( int section,
                                Qt::Orientation orientation,
                                int role = Qt::DisplayRole ) const ITK_OVERRIDE;
+
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#index
    */
-  
-    QModelIndex
+  QModelIndex
     index( int row,
            int column,
            const QModelIndex & p = QModelIndex() ) const ITK_OVERRIDE;
 
   /**
+   * \see http://doc.qt.io/qt-4.8/qabstractitemmodel.html#insertRow
+   */
+  bool
+    insertRow( int row, const QModelIndex & parent = QModelIndex() );
+
+  /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#insertRows
    */
-  
-    bool
+  bool
     insertRows( int row,
                 int count,
                 const QModelIndex & p = QModelIndex() ) ITK_OVERRIDE;
 
   /**
-   * \see http://doc.qt.io/qt-4.8/qabstractitemmodel.html#mimeData
-   */
-  QMimeData * mimeData( const QModelIndexList & indexes ) const ITK_OVERRIDE;
-
-  /**
-   * \see http://doc.qt.io/qt-4.8/qabstractitemmodel.html#mimeTypes
-   */
-  QStringList mimeTypes() const ITK_OVERRIDE;
-
-  /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#parent
    */
   QModelIndex parent( const QModelIndex & index ) const ITK_OVERRIDE;
@@ -224,8 +186,7 @@ public:
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#removeRows
    */
-  
-    bool
+  bool
     removeRows( int row,
                 int count,
                 const QModelIndex & p = QModelIndex() ) ITK_OVERRIDE;
@@ -238,16 +199,22 @@ public:
   /**
    * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#setData
    */
-  
-    bool
+  bool
     setData( const QModelIndex & index,
              const QVariant & value,
              int role = Qt::EditRole ) ITK_OVERRIDE;
 
-  /**
-   * \see http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html#supportedDropActions
-   */
-  Qt::DropActions supportedDropActions() const ITK_OVERRIDE;
+  /** */
+  virtual bool Swap( int, int );
+
+  /** */
+  virtual bool IsInput() const;
+
+  /** */
+  virtual QString GetFilter() const;
+
+  /** */
+  virtual bool IsBrowsable() const;
 
   /*-[ PUBLIC SLOTS SECTION ]------------------------------------------------*/
 
@@ -277,44 +244,23 @@ protected:
 // Private methods.
 private:
 
-  /**
-   */
-  void Connect( AbstractLayerModel * );
-
-  /**
-   */
-  void Disconnect( AbstractLayerModel * );
-
 
 //
 // Private attributes.
 private:
-  /**
-   */
-  StackedLayerModel * m_StackedLayerModel;
+  /** */
+  StringListInterface * m_StringList;
 
   /*-[ PRIVATE SLOTS SECTION ]-----------------------------------------------*/
 
 //
 // Slots.
 private slots:
-  /**
-   */
-  // void OnContentAboutToBeChanged();
-  // void OnContentChanged();
-  // void OnModelAboutToBeReset();
-  // void OnModelReset();
-  void OnLayerAboutToBeDeleted( size_t );
-  void OnLayerAdded( size_t );
-  void OnLayerDeleted( size_t );
-  void OnLayerVisibilityChanged( AbstractLayerModel *, bool );
-  void OnReferenceChanged( size_t );
-  void OnPixelInfoChanged( const QPoint &, const PointType &, const PixelInfo::Vector & );
-  void OnImageSettingsUpdated( AbstractImageModel * );
-  void OnResolutionsChanged( const PixelInfo::Vector & );
 };
 
-} // end namespace 'mvd'.
+} // end namespace 'Wrapper'.
+
+} // end namespace 'otb'.
 
 /*****************************************************************************/
 /* INLINE SECTION                                                            */
@@ -335,8 +281,8 @@ private slots:
 //
 // Monteverdi includes (sorted by alphabetic order)
 
-namespace mvd
+namespace otb
 {
-} // end namespace 'mvd'
+} // end namespace 'otb'
 
-#endif // mvdLayerStackItemModel_h
+#endif // otbListEditItemModel_h
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetListEditWidget.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetListEditWidget.h
new file mode 100644
index 0000000..a804dbe
--- /dev/null
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetListEditWidget.h
@@ -0,0 +1,207 @@
+/*
+ * 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 otbWrapperQtWidgetListEditWidget_h
+#define otbWrapperQtWidgetListEditWidget_h
+
+//
+// Configuration include.
+//// Included at first position before any other ones.
+#include "otbConfigure.h"
+
+
+/*****************************************************************************/
+/* INCLUDE SECTION                                                           */
+
+//
+// Qt includes (sorted by alphabetic order)
+//// Must be included before system/custom includes.
+#include <QtGui>
+
+//
+// System includes (sorted by alphabetic order)
+
+//
+// ITK includes (sorted by alphabetic order)
+
+//
+// OTB includes (sorted by alphabetic order)
+#include "OTBQtWidgetExport.h"
+
+
+/*****************************************************************************/
+/* PRE-DECLARATION SECTION                                                   */
+
+//
+// External classes pre-declaration.
+namespace
+{
+}
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+//
+// Internal classes pre-declaration.
+class ListEditItemModel;
+class StringListInterface;
+
+namespace Ui
+{
+class ListEditWidget;
+};
+
+
+/*****************************************************************************/
+/* CLASS DEFINITION SECTION                                                  */
+
+/**
+ * \class ListEditWidget
+ *
+ * \ingroup OTBQtWidget
+ *
+ * \brief
+ */
+class OTBQtWidget_EXPORT ListEditWidget :
+    public QWidget
+{
+
+  /*-[ QOBJECT SECTION ]-----------------------------------------------------*/
+
+  Q_OBJECT;
+
+  /*-[ PUBLIC SECTION ]------------------------------------------------------*/
+
+//
+// Public methods.
+public:
+
+  /** \brief Constructor. */
+  ListEditWidget( StringListInterface *,
+		  QWidget * p =NULL,
+		  Qt::WindowFlags flags =0 );
+
+  /** \brief Destructor. */
+  virtual ~ListEditWidget();
+
+  /**
+   */
+  const ListEditItemModel * GetItemModel() const;
+
+  /**
+   */
+  ListEditItemModel * GetItemModel();
+
+#if 0
+
+  /** */
+  void SetBrowseEnabled( bool );
+
+  /** */
+  bool IsBrowseEnabled() const;
+#endif
+
+  /*-[ PUBLIC SLOTS SECTION ]------------------------------------------------*/
+
+//
+// Public SLOTS.
+public slots:
+  void OnFilenameDropped(const QString &);
+  /*-[ SIGNALS SECTION ]-----------------------------------------------------*/
+
+//
+// Signals.
+signals:
+  /** */
+  void Updated();
+
+  /*-[ PROTECTED SECTION ]---------------------------------------------------*/
+
+//
+// Protected methods.
+protected:
+
+  /*-[ PRIVATE SECTION ]-----------------------------------------------------*/
+
+//
+// Protected attributes.
+protected:
+
+//
+// Private types.
+private:
+  enum SwapSelection
+  {
+    LEFT = -1,
+    NONE = 0,
+    RIGHT = +1,
+  };
+
+//
+// Private methods.
+private:
+  void Swap( int, int, SwapSelection = NONE );
+
+  QStringList browseFilenames( bool multi = false, const QString & filename = QString());
+
+  QString browseFilename( const QModelIndex & );
+
+//
+// Private attributes.
+private:
+  /**
+   * \brief uic generated.
+   */
+  Ui::ListEditWidget * m_UI;
+
+  /*-[ PRIVATE SLOTS SECTION ]-----------------------------------------------*/
+
+//
+// Slots.
+private slots:
+  void on_addButton_clicked();
+  void on_browseButton_clicked();
+  void on_downButton_clicked();
+  void on_removeButton_clicked();
+  void on_removeAllButton_clicked();
+  void on_upButton_clicked();
+
+  void OnDataChanged( const QModelIndex &, const QModelIndex & );
+  void OnModelReset();
+  void OnRowsInserted( const QModelIndex &, int, int );
+  void OnRowsRemoved( const QModelIndex &, int, int );
+  void OnSelectionChanged( const QItemSelection &, const QItemSelection & );
+};
+
+} // end namespace 'Wrapper'
+
+} // end namespace 'otb'
+
+/*****************************************************************************/
+/* INLINE SECTION                                                            */
+
+namespace Wrapper
+{
+} // end namespace 'Wrapper'
+
+#endif // otbWrappersQtWidgetListEditWidget_h
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h
index 6edb46e..db88ca9 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h
@@ -42,7 +42,7 @@ class OTBQtWidget_EXPORT QtWidgetParameterBase : public QWidget
 {
   Q_OBJECT
 public:
-  QtWidgetParameterBase(Parameter *, QtWidgetModel*);
+  QtWidgetParameterBase( Parameter *, QtWidgetModel * );
   ~QtWidgetParameterBase() ITK_OVERRIDE;
 
   void CreateWidget();
@@ -61,6 +61,9 @@ signals:
 protected:
   QtWidgetModel* GetModel();
 
+  const Parameter * GetParam() const;
+
+  Parameter * GetParam();
 
 private:
   QtWidgetParameterBase(const QtWidgetParameterBase&); //purposely not implemented
@@ -70,9 +73,10 @@ private:
 
   virtual void DoCreateWidget() = 0;
 
-  QtWidgetModel* m_Model;
+private:
+  QtWidgetModel * m_Model;
 
-  Parameter*      m_Param;
+  Parameter * m_Param;
 };
 
 
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterList.h
similarity index 52%
copy from Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h
copy to Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterList.h
index 6edb46e..6176829 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterBase.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetParameterList.h
@@ -18,65 +18,65 @@
  * limitations under the License.
  */
 
-#ifndef otbWrapperQtWidgetParameterBase_h
-#define otbWrapperQtWidgetParameterBase_h
+#ifndef otbWrapperQtWidgetParameterList_h
+#define otbWrapperQtWidgetParameterList_h
 
 #include <QtGui>
 #ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
-#include "otbWrapperParameter.h"
-#include "otbWrapperQtWidgetModel.h"
+#  include "otbWrapperQtWidgetParameterBase.h"
 #endif //tag=QT4-boost-compatibility
-#include "OTBQtWidgetExport.h"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
 
-/** \class QtWidgetParameterBase
+class AbstractParameterList;
+
+/** \class QtWidgetParameterList
  * \brief
  *
  * \ingroup OTBQtWidget
  */
-class OTBQtWidget_EXPORT QtWidgetParameterBase : public QWidget
+class OTBQtWidget_EXPORT QtWidgetParameterList : public QtWidgetParameterBase
 {
   Q_OBJECT
-public:
-  QtWidgetParameterBase(Parameter *, QtWidgetModel*);
-  ~QtWidgetParameterBase() ITK_OVERRIDE;
-
-  void CreateWidget();
 
-public slots:
-  void UpdateGUI();
-  virtual void SetActivationState( bool value );
-  void Reset();
-
-protected slots:
-  void ParameterChanged(const QString& key);
+//
+// Public methods.
+public:
+  QtWidgetParameterList( AbstractParameterList *, QtWidgetModel * );
+  ~QtWidgetParameterList() override;
 
+//
+// Signals.
 signals:
-  void ParameterActiveStatus(bool value);
-
-protected:
-  QtWidgetModel* GetModel();
-
+  void NotifyUpdate();
 
+//
+// Private methods.
 private:
-  QtWidgetParameterBase(const QtWidgetParameterBase&); //purposely not implemented
-  void operator=(const QtWidgetParameterBase&); //purposely not implemented
+  QtWidgetParameterList( const QtWidgetParameterList & ); // purposely not implemented
+  void operator = (const QtWidgetParameterList & ); // purposely not implemented
 
-  virtual void DoUpdateGUI() = 0;
+  void DoCreateWidget() override;
 
-  virtual void DoCreateWidget() = 0;
+  void DoUpdateGUI() override;
 
-  QtWidgetModel* m_Model;
+//
+// Private attributes.
+private:
 
-  Parameter*      m_Param;
+//
+// Private slots.
+private slots:
 };
 
+} // Wrapper
 
-}
-}
+} // otb
 
 #endif
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetStringListParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetStringListParameter.h
index 8ae05e7..062e38e 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetStringListParameter.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetStringListParameter.h
@@ -21,52 +21,47 @@
 #ifndef otbWrapperQtWidgetStringListParameter_h
 #define otbWrapperQtWidgetStringListParameter_h
 
-#include <QtGui>
-#ifndef Q_MOC_RUN  // See: https://bugreports.qt-project.org/browse/QTBUG-22829  //tag=QT4-boost-compatibility
-#include "otbQtStringSelectionWidget.h"
-#endif //tag=QT4-boost-compatibility
+
+#include "otbWrapperQtWidgetParameterList.h"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
 
+
+class StringListParameter;
+
+
 /** \class QtWidgetStringListParameter
  * \brief
  *
  * \ingroup OTBQtWidget
  */
-class OTBQtWidget_EXPORT QtWidgetStringListParameter : public QtWidgetParameterBase
+class OTBQtWidget_EXPORT QtWidgetStringListParameter :
+    public QtWidgetParameterList
 {
-  Q_OBJECT
-public:
-  QtWidgetStringListParameter(StringListParameter*, QtWidgetModel*);
-  ~QtWidgetStringListParameter() ITK_OVERRIDE;
-
-signals:
-  void Change();
+  Q_OBJECT;
 
-protected slots:
-  void SetString( const QString& value );
-  virtual void AddString();
-  virtual void SuppressString();
-  virtual void UpdateStringList();
-
-private:
-  QtWidgetStringListParameter(const QtWidgetStringListParameter&); //purposely not implemented
-  void operator=(const QtWidgetStringListParameter&); //purposely not implemented
 
-  void DoCreateWidget() ITK_OVERRIDE;
-
-  void DoUpdateGUI() ITK_OVERRIDE;
+//
+// Public methods.
+public:
+  QtWidgetStringListParameter( StringListParameter *, QtWidgetModel * );
+  ~QtWidgetStringListParameter() override;
 
-  StringListParameter::Pointer m_StringListParam;
 
-  QHBoxLayout * m_HLayout;
-  QVBoxLayout * m_StringLayout;
-  QScrollArea * m_Scroll;
+//
+// Private methods.
+private:
+   // Purposely not implemented.
+  QtWidgetStringListParameter( const QtWidgetStringListParameter & );
 
-  std::vector<QtStringSelectionWidget *> m_LineEditList;
+  // Purposely not implemented
+  void operator = ( const QtWidgetStringListParameter & );
 };
 
 
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h
index 761973d..08857a2 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h
@@ -55,6 +55,7 @@ public:
 public slots:
   void CloseSlot();
   void UnhandledException(QString message);
+  void OnExceptionRaised(QString message);
 
 private slots:
   void UpdateMessageAfterExecuteClicked();
diff --git a/Modules/Wrappers/QtWidget/src/CMakeLists.txt b/Modules/Wrappers/QtWidget/src/CMakeLists.txt
index e567d8d..28cb58c 100644
--- a/Modules/Wrappers/QtWidget/src/CMakeLists.txt
+++ b/Modules/Wrappers/QtWidget/src/CMakeLists.txt
@@ -54,6 +54,9 @@ set(OTBQtWidget_SRC
   otbWrapperQtWidgetOutputVectorDataParameter.cxx
   otbWrapperQtWidgetInputFilenameParameter.cxx
   otbWrapperQtWidgetInputImageListParameter.cxx
+  otbWrapperQtWidgetListEditWidget.cxx
+  otbWrapperQtWidgetListEditItemModel.cxx
+  otbWrapperQtWidgetParameterList.cxx
   )
 
 set(OTBQtWidget_MOC_HDR
@@ -91,11 +94,23 @@ set(OTBQtWidget_MOC_HDR
   ../include/otbWrapperQtWidgetDirectoryParameter.h
   ../include/otbWrapperQtWidgetSimpleProgressReport.h
   ../include/otbWrapperQtWidgetRAMParameter.h
+  ../include/otbWrapperQtWidgetListEditWidget.h
+  ../include/otbWrapperQtWidgetListEditItemModel.h
+  ../include/otbWrapperQtWidgetParameterList.h
   )
 
-QT4_WRAP_CPP(OTBQtWidget_MOC_SRC ${OTBQtWidget_MOC_HDR})
+set( OTBQtWidget_FORMS
+  otbWrapperQtWidgetListEditWidget.ui
+  )
+
+qt4_wrap_cpp( OTBQtWidget_MOC_SRC ${OTBQtWidget_MOC_HDR} )
+qt4_wrap_ui( OTBQtWidget_FORMS_HEADERS ${OTBQtWidget_FORMS} )
 
-add_library(OTBQtWidget ${OTBQtWidget_SRC} ${OTBQtWidget_MOC_SRC})
+add_library( OTBQtWidget
+  ${OTBQtWidget_SRC}
+  ${OTBQtWidget_FORMS_HEADERS}
+  ${OTBQtWidget_MOC_SRC}
+  )
 
 target_link_libraries( OTBQtWidget
   ${OTBApplicationEngine_LIBRARIES}
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetChoiceParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetChoiceParameter.cxx
index e332170..078064c 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetChoiceParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetChoiceParameter.cxx
@@ -61,7 +61,9 @@ void QtWidgetChoiceParameter::DoUpdateGUI()
 void QtWidgetChoiceParameter::DoCreateWidget()
 {
   m_ComboBox = new QComboBox;
-  m_ComboBox->setToolTip(m_ChoiceParam->GetDescription());
+  m_ComboBox->setToolTip(
+    QString::fromStdString( m_ChoiceParam->GetDescription() )
+  );
 
   m_StackWidget = new QStackedWidget;
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexInputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexInputImageParameter.cxx
index 5334147..198b4a4 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexInputImageParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexInputImageParameter.cxx
@@ -60,7 +60,9 @@ void QtWidgetComplexInputImageParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_ComplexInputImageParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_ComplexInputImageParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx
index 7432d26..0cd5800 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx
@@ -57,7 +57,9 @@ void QtWidgetComplexOutputImageParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_OutputImageParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_OutputImageParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
   m_HLayout->addWidget(m_Input);
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetDirectoryParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetDirectoryParameter.cxx
index 0c5aee0..6eb0189 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetDirectoryParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetDirectoryParameter.cxx
@@ -56,7 +56,9 @@ void QtWidgetDirectoryParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_DirectoryParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_DirectoryParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetFloatParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetFloatParameter.cxx
index 2c7a2a9..6c30dd2 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetFloatParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetFloatParameter.cxx
@@ -72,7 +72,11 @@ void QtWidgetFloatParameter::DoCreateWidget()
   m_QDoubleSpinBox->setDecimals(5);
   m_QDoubleSpinBox->setSingleStep(0.1);
   m_QDoubleSpinBox->setRange(m_FloatParam->GetMinimumValue(), m_FloatParam->GetMaximumValue());
-  m_QDoubleSpinBox->setToolTip(m_FloatParam->GetDescription());
+  m_QDoubleSpinBox->setToolTip(
+    QString::fromStdString(
+      m_FloatParam->GetDescription()
+    )
+  );
 
   connect( m_QDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(SetValue(double)) );
   connect( m_QDoubleSpinBox, SIGNAL(valueChanged(double)), GetModel(), SLOT(NotifyUpdate()) );
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameListParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameListParameter.cxx
index da366b6..8aeae84 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameListParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameListParameter.cxx
@@ -18,382 +18,31 @@
  * limitations under the License.
  */
 
+#include "otbWrapperInputFilenameListParameter.h"
 #include "otbWrapperQtWidgetInputFilenameListParameter.h"
 
-namespace otb
-{
-namespace Wrapper
-{
-
-QtWidgetInputFilenameListParameter::QtWidgetInputFilenameListParameter(InputFilenameListParameter* param, QtWidgetModel* m)
-: QtWidgetParameterBase(param, m),
-  m_InputFilenameListParam(param)
-{
- connect(this, SIGNAL(Change()), GetModel(), SLOT(NotifyUpdate()));
-}
-
-QtWidgetInputFilenameListParameter::~QtWidgetInputFilenameListParameter()
-{
-}
-
-void QtWidgetInputFilenameListParameter::DoUpdateGUI()
-{
-  if(!m_InputFilenameListParam)
-    return;
-
-  std::vector<std::string> fileList = m_InputFilenameListParam->GetFileNameList();
-  for( unsigned int i = m_FileSelectionList.size(); i < fileList.size(); i++ )
-    {
-      this->AddFile();
-    }
-  int i = 0;
-  std::vector<std::string>::iterator it;
-  for (it = fileList.begin(); it != fileList.end(); ++it)
-    {
-      m_FileSelectionList[i++]->GetInput()->setText(
-	QFile::decodeName(
-	  it->c_str()
-	)
-      );
-    }
-}
-
-void QtWidgetInputFilenameListParameter::DoCreateWidget()
-{
-  m_FileSelectionList.clear();
-  const unsigned int sp(2);
-  const unsigned int buttonSize(30);
-
-  // Global layout
-  QHBoxLayout * hLayout = new QHBoxLayout;
-  hLayout->setSpacing(sp);
-  hLayout->setContentsMargins(sp, sp, sp, sp);
-
-  // Button layout
-  QVBoxLayout * buttonLayout = new QVBoxLayout;
-  buttonLayout->setSpacing(sp);
-  buttonLayout->setContentsMargins(sp, sp, sp, sp);
-
-  QHBoxLayout * addSupLayout = new QHBoxLayout;
-  addSupLayout->setSpacing(sp);
-  addSupLayout->setContentsMargins(sp, sp, sp, sp);
-
-  QHBoxLayout * upDownLayout = new QHBoxLayout;
-  upDownLayout->setSpacing(sp);
-  upDownLayout->setContentsMargins(sp, sp, sp, sp);
-
-  // Add file button
-  QPushButton * addButton = new QPushButton;
-  addButton->setText("+");
-  addButton->setFixedWidth(buttonSize);
-  addButton->setToolTip("Add a file selector...");
-  connect(addButton, SIGNAL(clicked()), this, SLOT(AddFile()));
-  addSupLayout->addWidget(addButton);
-
-  // Suppress file button
-  QPushButton * supButton = new QPushButton;
-  supButton->setText("-");
-  supButton->setFixedWidth(buttonSize);
-  supButton->setToolTip("Suppress the selected file...");
-  connect(supButton, SIGNAL(clicked()), this, SLOT(SuppressFile()));
-  addSupLayout->addWidget(supButton);
-  buttonLayout->addLayout(addSupLayout);
-
-  // Up file edit
-  QPushButton * upButton = new QPushButton;
-  upButton->setText("Up");
-  upButton->setFixedWidth(buttonSize);
-  upButton->setToolTip("Up the selected file in the list...");
-  connect(upButton, SIGNAL(clicked()), this, SLOT(UpFile()));
-  upDownLayout->addWidget(upButton);
-
-  // Down file edit
-  QPushButton * downButton = new QPushButton;
-  downButton->setText("Down");
-  downButton->setFixedWidth(buttonSize);
-  downButton->setToolTip("Down the selected file in the list...");
-  connect(downButton, SIGNAL(clicked()), this, SLOT(DownFile()));
-  upDownLayout->addWidget(downButton);
-  buttonLayout->addLayout(upDownLayout);
-
-  // Erase file edit
-  QPushButton * eraseButton = new QPushButton;
-  eraseButton->setText("Erase");
-  eraseButton->setFixedWidth(2*(buttonSize+sp));
-  eraseButton->setToolTip("Erase the selected file of the list...");
-  connect(eraseButton, SIGNAL(clicked()), this, SLOT(EraseFile()));
-  buttonLayout->addWidget(eraseButton);
-
-  QVBoxLayout * fileLayout = new QVBoxLayout();
-  fileLayout->setSpacing(0);
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  fileLayout->addWidget(fileSelection);
-  m_InputFilenameListParam->AddNullElement();
-  connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateFilenameList()));
-
-  m_FileSelectionList.push_back(fileSelection);
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(fileLayout);
-  QScrollArea * s = new QScrollArea();
-  s->setWidget(mainGroup);
-  s->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-  s->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-  s->setWidgetResizable(true);
-
-  hLayout->addWidget(s);
-  hLayout->addLayout(buttonLayout);
-
-  this->setLayout(hLayout);
-
-  m_FileLayout = fileLayout;
-  m_HLayout = hLayout;
-  m_Scroll = s;
-}
-
-void
-QtWidgetInputFilenameListParameter::UpdateFilenameList()
-{
-  for(unsigned int j = 0; j < m_InputFilenameListParam->GetFileList()->Size(); j++)
-    {
-    if(m_InputFilenameListParam->SetNthFileName(j, m_FileSelectionList[j]->GetFilename()) == false)
-      {
-      std::ostringstream oss;
-      oss << "The given file " << m_FileSelectionList[j]->GetFilename() << " is not valid.";
-      this->GetModel()->SendLogWARNING(oss.str());
-      m_FileSelectionList[j]->ClearFilename();
-      }
-    }
-
-  emit Change();
-
-  // notify of value change
-  QString key(m_InputFilenameListParam->GetKey());
-  emit ParameterChanged(key);
-}
-
-
-void
-QtWidgetInputFilenameListParameter::UpFile()
-{
- if(m_FileSelectionList.size() < 2)
-    return;
-
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(2);
-
-  // Map link between old and new index in the list
-  std::map<unsigned int, unsigned int> idMap;
-
-  // Init map
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    idMap[i] = i;
-    }
 
-  // If the first item is checked, uncheck it...
-  // It won't be moved
-  if(m_FileSelectionList[0]->IsChecked())
-    {
-    m_FileSelectionList[0]->SetChecked(false);
-    }
-
-
-  // If other item are checked, up the index
-  // Starts at 1 because the first item mustn't move
-  for(unsigned int i = 1; i < m_FileSelectionList.size(); i++)
-    {
-    if(m_FileSelectionList[i]->IsChecked())
-      {
-      unsigned int tmp = idMap[i];
-      idMap[i] = i-1;
-      idMap[idMap[i-1]] = tmp;
-      }
-    }
-
-  this->UpdateFileList(idMap);
-
-  this->RecreateFilenameList();
-}
-
-void
-QtWidgetInputFilenameListParameter::DownFile()
-{
-  if(m_FileSelectionList.size() < 2) return;
-
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-
-  // Map link between old and new index in the list
-  std::map<unsigned int, unsigned int> idMap;
-
-  // Init map
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    idMap[i] = i;
-    }
-
-  // If the last item is checked, uncheck it...
-  // It won't be moved
-  if(m_FileSelectionList[m_FileSelectionList.size() - 1]->IsChecked())
-    {
-    m_FileSelectionList[m_FileSelectionList.size() - 1]->SetChecked(false);
-    }
-
-  // If other item are checked, up the index
-  // Stops at size-1 because the last item mustn't move
-  for(int i = m_FileSelectionList.size() - 2; i >= 0; i--)
-    {
-    if(m_FileSelectionList[i]->IsChecked())
-      {
-      unsigned int tmp = idMap[i];
-      idMap[i] = i + 1;
-      idMap[idMap[i + 1]] = tmp;
-      }
-    }
-
-  this->UpdateFileList(idMap);
-
-  this->RecreateFilenameList();
-}
-
-
-void
-QtWidgetInputFilenameListParameter::UpdateFileList(std::map<unsigned int, unsigned int> idMap)
+namespace otb
 {
-  std::vector<QtFileSelectionWidget *> tmpList;
-  // Keys become values and inverse
-  std::map<unsigned int, unsigned int> idMapBis;
-  for(unsigned int i = 0; i < idMap.size(); i++)
-    {
-    idMapBis[idMap[i]] = i;
-    }
-
-  // Create the new item list
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    m_FileLayout->addWidget(m_FileSelectionList[idMapBis[i]]);
-    tmpList.push_back(m_FileSelectionList[idMapBis[i]]);
-    }
-
-  m_FileSelectionList = tmpList;
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-
-  // notify of value change
-  QString key(m_InputFilenameListParam->GetKey());
-  emit ParameterChanged(key);
-}
-
 
-void
-QtWidgetInputFilenameListParameter::AddFile()
+namespace Wrapper
 {
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    m_FileLayout->addWidget(m_FileSelectionList[i]);
-    }
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  m_FileLayout->addWidget(fileSelection);
-  m_FileSelectionList.push_back(fileSelection);
-  m_InputFilenameListParam->AddNullElement();
-  connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateFilenameList()));
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
 
-  this->update();
-
-  emit FileSelectionWidgetAdded( fileSelection );
-}
-
-void
-QtWidgetInputFilenameListParameter::SuppressFile()
+/*****************************************************************************/
+QtWidgetInputFilenameListParameter
+::QtWidgetInputFilenameListParameter( InputFilenameListParameter * param,
+				      QtWidgetModel * m ) :
+  QtWidgetParameterList( param, m )
 {
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-  std::vector<QtFileSelectionWidget *> tmpList;
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    if(!m_FileSelectionList[i]->IsChecked())
-      {
-      m_FileLayout->addWidget(m_FileSelectionList[i]);
-      tmpList.push_back(m_FileSelectionList[i]);
-      }
-    }
-
-  m_FileSelectionList = tmpList;
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-  this->RecreateFilenameList();
 }
 
 
-void
-QtWidgetInputFilenameListParameter::EraseFile()
+/*****************************************************************************/
+QtWidgetInputFilenameListParameter
+::~QtWidgetInputFilenameListParameter()
 {
-  m_FileSelectionList.clear();
-
-  m_FileLayout = new QVBoxLayout();
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  m_FileLayout->addWidget(fileSelection);
-  m_FileSelectionList.push_back(fileSelection);
-  m_InputFilenameListParam->AddNullElement();
-  connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateFilenameList()));
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-  this->RecreateFilenameList();
 }
 
-
-void QtWidgetInputFilenameListParameter::RecreateFilenameList()
-{
-  // save value
-  m_InputFilenameListParam->ClearValue();
-
-  if(m_FileSelectionList.size() == 0)
-    {
-    this->AddFile();
-    }
-  else
-    {
-    for(unsigned int j = 0; j < m_FileSelectionList.size(); j++)
-      {
-      m_InputFilenameListParam->AddFromFileName(m_FileSelectionList[j]->GetFilename());
-      connect(m_FileSelectionList[j]->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateFilenameList()));
-      }
-
-    emit Change();
-    // notify of value change
-    QString key(m_InputFilenameListParam->GetKey());
-    emit ParameterChanged(key);
-    }
 }
 
-
-}
 }
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameParameter.cxx
index 6db8cb8..93011f3 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputFilenameParameter.cxx
@@ -61,7 +61,9 @@ void QtWidgetInputFilenameParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_FilenameParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_FilenameParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx
index 8224946..218e638 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageListParameter.cxx
@@ -20,393 +20,28 @@
 
 #include "otbWrapperQtWidgetInputImageListParameter.h"
 
-namespace otb
-{
-namespace Wrapper
-{
-
-QtWidgetInputImageListParameter::QtWidgetInputImageListParameter(InputImageListParameter* param, QtWidgetModel* m)
-: QtWidgetParameterBase(param, m),
-  m_InputImageListParam(param)
-{
- connect(this, SIGNAL(Change()), GetModel(), SLOT(NotifyUpdate()));
-}
-
-QtWidgetInputImageListParameter::~QtWidgetInputImageListParameter()
-{
-}
-
-void QtWidgetInputImageListParameter::DoUpdateGUI()
-{
-  if(!m_InputImageListParam)
-    return;
-
-  //update fileSelectionList only if HasUserValue flag is set(from xml)
-  if(m_InputImageListParam->HasUserValue())
-    {
-    std::vector<std::string> fileList = m_InputImageListParam->GetFileNameList();
-
-    for( unsigned int i = m_FileSelectionList.size(); i < fileList.size(); i++ )
-      {
-      this->AddFile();
-      }
-    unsigned int i = 0;
-    std::vector<std::string>::iterator it;
-    for (it = fileList.begin(); it != fileList.end(); ++it)
-      {
-      m_FileSelectionList[i++]->GetInput()->setText(
-	QFile::decodeName( it->c_str() )
-      );
-      }
-    }
-}
-void QtWidgetInputImageListParameter::DoCreateWidget()
-{
-  m_FileSelectionList.clear();
-  const unsigned int sp(2);
-  const unsigned int buttonSize(30);
-
-  // Global layout
-  QHBoxLayout * hLayout = new QHBoxLayout;
-  hLayout->setSpacing(sp);
-  hLayout->setContentsMargins(sp, sp, sp, sp);
-
-  // Button layout
-  QVBoxLayout * buttonLayout = new QVBoxLayout;
-  buttonLayout->setSpacing(sp);
-  buttonLayout->setContentsMargins(sp, sp, sp, sp);
-
-  QHBoxLayout * addSupLayout = new QHBoxLayout;
-  addSupLayout->setSpacing(sp);
-  addSupLayout->setContentsMargins(sp, sp, sp, sp);
-
-  QHBoxLayout * upDownLayout = new QHBoxLayout;
-  upDownLayout->setSpacing(sp);
-  upDownLayout->setContentsMargins(sp, sp, sp, sp);
-
-  // Add file button
-  QPushButton * addButton = new QPushButton;
-  addButton->setText("+");
-  addButton->setFixedWidth(buttonSize);
-  addButton->setToolTip("Add a file selector...");
-  connect(addButton, SIGNAL(clicked()), this, SLOT(AddFile()));
-  addSupLayout->addWidget(addButton);
-
-  // Suppress file button
-  QPushButton * supButton = new QPushButton;
-  supButton->setText("-");
-  supButton->setFixedWidth(buttonSize);
-  supButton->setToolTip("Suppress the selected file...");
-  connect(supButton, SIGNAL(clicked()), this, SLOT(SuppressFile()));
-  addSupLayout->addWidget(supButton);
-  buttonLayout->addLayout(addSupLayout);
-
-  // Up file edit
-  QPushButton * upButton = new QPushButton;
-  upButton->setText("Up");
-  upButton->setFixedWidth(buttonSize);
-  upButton->setToolTip("Up the selected file in the list...");
-  connect(upButton, SIGNAL(clicked()), this, SLOT(UpFile()));
-  upDownLayout->addWidget(upButton);
-
-  // Down file edit
-  QPushButton * downButton = new QPushButton;
-  downButton->setText("Down");
-  downButton->setFixedWidth(buttonSize);
-  downButton->setToolTip("Down the selected file in the list...");
-  connect(downButton, SIGNAL(clicked()), this, SLOT(DownFile()));
-  upDownLayout->addWidget(downButton);
-  buttonLayout->addLayout(upDownLayout);
-
-  // Erase file edit
-  QPushButton * eraseButton = new QPushButton;
-  eraseButton->setText("Erase");
-  eraseButton->setFixedWidth(2*(buttonSize+sp));
-  eraseButton->setToolTip("Erase the selected file of the list...");
-  connect(eraseButton, SIGNAL(clicked()), this, SLOT(EraseFile()));
-  buttonLayout->addWidget(eraseButton);
-
-  QVBoxLayout * fileLayout = new QVBoxLayout();
-  fileLayout->setSpacing(0);
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  fileLayout->addWidget(fileSelection);
-  m_InputImageListParam->AddNullElement();
-  connect(fileSelection, SIGNAL(FilenameChanged()), this, SLOT(UpdateImageList()));
-
-  m_FileSelectionList.push_back(fileSelection);
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(fileLayout);
-  QScrollArea * s = new QScrollArea();
-  s->setWidget(mainGroup);
-  s->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-  s->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-  s->setWidgetResizable(true);
-
-  hLayout->addWidget(s);
-  hLayout->addLayout(buttonLayout);
-
-  this->setLayout(hLayout);
-
-  m_FileLayout = fileLayout;
-  m_HLayout = hLayout;
-  m_Scroll = s;
-
-}
-
-void
-QtWidgetInputImageListParameter::UpdateImageList()
-{
-  // Adding a NullElement so to make the m_FileSelectionList and
-  // m_InputImageList's ImageList are of same size.
-  for(unsigned int i = m_InputImageListParam->Size(); i < m_FileSelectionList.size(); i++)
-    {
-    m_InputImageListParam->AddNullElement();
-    }
-
-  for(unsigned int j = 0; j < m_InputImageListParam->Size(); j++)
-    {
-    if(m_InputImageListParam->SetNthFileName(j, m_FileSelectionList[j]->GetFilename()) == false)
-      {
-      std::ostringstream oss;
-      oss << "The given file " << m_FileSelectionList[j]->GetFilename() << " is not valid.";
-      this->GetModel()->SendLogWARNING(oss.str());
-      }
-    }
-
-  emit Change();
-
-  // notify of value change
-  QString key(m_InputImageListParam->GetKey());
-  emit ParameterChanged(key);
-}
-
-void
-QtWidgetInputImageListParameter::UpFile()
-{
- if(m_FileSelectionList.size() < 2)
-    return;
-
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(2);
-
-  // Map link between old and new index in the list
-  std::map<unsigned int, unsigned int> idMap;
 
-  // Init map
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    idMap[i] = i;
-    }
-
-  // If the first item is checked, uncheck it...
-  // It won't be moved
-  if(m_FileSelectionList[0]->IsChecked())
-    {
-    m_FileSelectionList[0]->SetChecked(false);
-    }
-
-
-  // If other item are checked, up the index
-  // Starts at 1 because the first item mustn't move
-  for(unsigned int i = 1; i < m_FileSelectionList.size(); i++)
-    {
-    if(m_FileSelectionList[i]->IsChecked())
-      {
-      unsigned int tmp = idMap[i];
-      idMap[i] = i-1;
-      idMap[idMap[i-1]] = tmp;
-      }
-    }
-
-  this->UpdateFileList(idMap);
-
-  this->RecreateImageList();
-}
-
-void
-QtWidgetInputImageListParameter::DownFile()
-{
-  if(m_FileSelectionList.size() < 2) return;
-
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-
-  // Map link between old and new index in the list
-  std::map<unsigned int, unsigned int> idMap;
-
-  // Init map
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    idMap[i] = i;
-    }
-
-  // If the last item is checked, uncheck it...
-  // It won't be moved
-  if(m_FileSelectionList[m_FileSelectionList.size() - 1]->IsChecked())
-    {
-    m_FileSelectionList[m_FileSelectionList.size() - 1]->SetChecked(false);
-    }
-
-  // If other item are checked, up the index
-  // Stops at size-1 because the last item mustn't move
-  for(int i = m_FileSelectionList.size() - 2; i >= 0; i--)
-    {
-    if(m_FileSelectionList[i]->IsChecked())
-      {
-      unsigned int tmp = idMap[i];
-      idMap[i] = i + 1;
-      idMap[idMap[i + 1]] = tmp;
-      }
-    }
-
-  this->UpdateFileList(idMap);
-
-  this->RecreateImageList();
-}
-
-
-void
-QtWidgetInputImageListParameter::UpdateFileList(std::map<unsigned int, unsigned int> idMap)
+namespace otb
 {
-  std::vector<QtFileSelectionWidget *> tmpList;
-  // Keys become values and inverse
-  std::map<unsigned int, unsigned int> idMapBis;
-  for(unsigned int i = 0; i < idMap.size(); i++)
-    {
-    idMapBis[idMap[i]] = i;
-    }
-
-  // Create the new item list
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    m_FileLayout->addWidget(m_FileSelectionList[idMapBis[i]]);
-    tmpList.push_back(m_FileSelectionList[idMapBis[i]]);
-    }
-
-  m_FileSelectionList = tmpList;
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
 
-  // notify of value change
-  QString key(m_InputImageListParam->GetKey());
-  emit ParameterChanged(key);
-}
-
-
-void
-QtWidgetInputImageListParameter::AddFile()
+namespace Wrapper
 {
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    m_FileLayout->addWidget(m_FileSelectionList[i]);
-    }
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  m_FileLayout->addWidget(fileSelection);
-  m_FileSelectionList.push_back(fileSelection);
-  /* No need of AddNullElement() here. Moved adding NullElement when updating the list  */
-  //m_InputImageListParam->AddNullElement();
-  connect(
-    fileSelection,
-    SIGNAL( FilenameChanged() ),
-    this,
-    SLOT( UpdateImageList() )
-  );
 
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-
-  emit FileSelectionWidgetAdded( fileSelection );
-}
-
-void
-QtWidgetInputImageListParameter::SuppressFile()
+/*****************************************************************************/
+QtWidgetInputImageListParameter
+::QtWidgetInputImageListParameter( InputImageListParameter * param,
+				   QtWidgetModel * m ) :
+  QtWidgetParameterList( param, m )
 {
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-  std::vector<QtFileSelectionWidget *> tmpList;
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    if(!m_FileSelectionList[i]->IsChecked())
-      {
-      m_FileLayout->addWidget(m_FileSelectionList[i]);
-      tmpList.push_back(m_FileSelectionList[i]);
-      }
-    }
-
-  m_FileSelectionList = tmpList;
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-  this->RecreateImageList();
 }
 
-void
-QtWidgetInputImageListParameter::EraseFile()
+/*****************************************************************************/
+QtWidgetInputImageListParameter
+::~QtWidgetInputImageListParameter()
 {
-  m_FileSelectionList.clear();
-
-  m_FileLayout = new QVBoxLayout();
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  m_FileLayout->addWidget(fileSelection);
-  m_FileSelectionList.push_back(fileSelection);
-  m_InputImageListParam->AddNullElement();
-  connect(fileSelection, SIGNAL(FilenameChanged()), this, SLOT(UpdateImageList()));
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-  this->RecreateImageList();
 }
 
-void QtWidgetInputImageListParameter::RecreateImageList()
-{
-  // save value
-  m_InputImageListParam->ClearValue();
-
-  if(m_FileSelectionList.size() == 0)
-    {
-    this->AddFile();
-    }
-  else
-    {
-    for(unsigned int j = 0; j < m_FileSelectionList.size(); j++)
-      {
-      m_InputImageListParam->AddFromFileName(m_FileSelectionList[j]->GetFilename());
-      connect(m_FileSelectionList[j], SIGNAL(FilenameChanged()), this, SLOT(UpdateImageList()));
-      }
-
-    emit Change();
-    // notify of value change
-    QString key(m_InputImageListParam->GetKey());
 
-    emit ParameterChanged(key);
-    }
 }
 
-
-}
 }
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx
index e41c35d..8f9873b 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputImageParameter.cxx
@@ -68,7 +68,11 @@ void QtWidgetInputImageParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_InputImageParam->GetDescription() );
+
+  m_Input->setToolTip(
+    QString::fromStdString( m_InputImageParam->GetDescription() )
+  );
+
   connect( m_Input, SIGNAL(editingFinished()), this, SLOT(OnEditingFinished()) );
   connect( this, SIGNAL(FileNameIsSet()), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputProcessXMLParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputProcessXMLParameter.cxx
index bd72303..9229d58 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputProcessXMLParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputProcessXMLParameter.cxx
@@ -60,7 +60,9 @@ void QtWidgetInputProcessXMLParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_XMLParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_XMLParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataListParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataListParameter.cxx
index fd8cdad..e4184c5 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataListParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataListParameter.cxx
@@ -20,380 +20,32 @@
 
 #include "otbWrapperQtWidgetInputVectorDataListParameter.h"
 
-namespace otb
-{
-namespace Wrapper
-{
-
-QtWidgetInputVectorDataListParameter::QtWidgetInputVectorDataListParameter(InputVectorDataListParameter* param,
-                                                                           QtWidgetModel* m)
-: QtWidgetParameterBase(param, m),
-  m_InputVectorDataListParam(param)
-{
- connect(this, SIGNAL(Change()), GetModel(), SLOT(NotifyUpdate()));
-}
-
-QtWidgetInputVectorDataListParameter::~QtWidgetInputVectorDataListParameter()
-{
-}
-
-void QtWidgetInputVectorDataListParameter::DoUpdateGUI()
-{
-  if(!m_InputVectorDataListParam)
-    return;
-
-  std::vector<std::string> fileList = m_InputVectorDataListParam->GetFileNameList();
-  for( unsigned int i = m_FileSelectionList.size(); i < fileList.size(); i++ )
-    {
-      this->AddFile();
-    }
-  int i = 0;
-  std::vector<std::string>::iterator it;
-  for (it = fileList.begin(); it != fileList.end(); ++it)
-    {
-      m_FileSelectionList[i++]->GetInput()->setText(
-	QFile::decodeName( it->c_str() )
-      );
-    }
-}
-
-void QtWidgetInputVectorDataListParameter::DoCreateWidget()
-{
-  m_FileSelectionList.clear();
-  const unsigned int sp(2);
-  const unsigned int buttonSize(30);
-
-  // Global layout
-  QHBoxLayout * hLayout = new QHBoxLayout;
-  hLayout->setSpacing(sp);
-  hLayout->setContentsMargins(sp, sp, sp, sp);
-
-  // Button layout
-  QVBoxLayout * buttonLayout = new QVBoxLayout;
-  buttonLayout->setSpacing(sp);
-  buttonLayout->setContentsMargins(sp, sp, sp, sp);
-
-  QHBoxLayout * addSupLayout = new QHBoxLayout;
-  addSupLayout->setSpacing(sp);
-  addSupLayout->setContentsMargins(sp, sp, sp, sp);
-
-  QHBoxLayout * upDownLayout = new QHBoxLayout;
-  upDownLayout->setSpacing(sp);
-  upDownLayout->setContentsMargins(sp, sp, sp, sp);
-
-  // Add file button
-  QPushButton * addButton = new QPushButton;
-  addButton->setText("+");
-  addButton->setFixedWidth(buttonSize);
-  addButton->setToolTip("Add a file selector...");
-  connect(addButton, SIGNAL(clicked()), this, SLOT(AddFile()));
-  addSupLayout->addWidget(addButton);
-
-  // Suppress file button
-  QPushButton * supButton = new QPushButton;
-  supButton->setText("-");
-  supButton->setFixedWidth(buttonSize);
-  supButton->setToolTip("Suppress the selected file...");
-  connect(supButton, SIGNAL(clicked()), this, SLOT(SuppressFile()));
-  addSupLayout->addWidget(supButton);
-  buttonLayout->addLayout(addSupLayout);
-
-  // Up file edit
-  QPushButton * upButton = new QPushButton;
-  upButton->setText("Up");
-  upButton->setFixedWidth(buttonSize);
-  upButton->setToolTip("Up the selected file in the list...");
-  connect(upButton, SIGNAL(clicked()), this, SLOT(UpFile()));
-  upDownLayout->addWidget(upButton);
-
-  // Down file edit
-  QPushButton * downButton = new QPushButton;
-  downButton->setText("Down");
-  downButton->setFixedWidth(buttonSize);
-  downButton->setToolTip("Down the selected file in the list...");
-  connect(downButton, SIGNAL(clicked()), this, SLOT(DownFile()));
-  upDownLayout->addWidget(downButton);
-  buttonLayout->addLayout(upDownLayout);
-
-  // Erase file edit
-  QPushButton * eraseButton = new QPushButton;
-  eraseButton->setText("Erase");
-  eraseButton->setFixedWidth(2*(buttonSize+sp));
-  eraseButton->setToolTip("Erase the selected file of the list...");
-  connect(eraseButton, SIGNAL(clicked()), this, SLOT(EraseFile()));
-  buttonLayout->addWidget(eraseButton);
-
-  QVBoxLayout * fileLayout = new QVBoxLayout();
-  fileLayout->setSpacing(0);
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  fileLayout->addWidget(fileSelection);
-  m_InputVectorDataListParam->AddNullElement();
-  connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateVectorDataList()));
-
-  m_FileSelectionList.push_back(fileSelection);
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(fileLayout);
-  QScrollArea * scroll2 = new QScrollArea();
-  scroll2->setWidget(mainGroup);
-  scroll2->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-  scroll2->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-  scroll2->setWidgetResizable(true);
-
-  hLayout->addWidget(scroll2);
-  hLayout->addLayout(buttonLayout);
-
-  this->setLayout(hLayout);
-
-  m_FileLayout = fileLayout;
-  m_HLayout = hLayout;
-  m_Scroll = scroll2;
-
-}
-
-void
-QtWidgetInputVectorDataListParameter::UpdateVectorDataList()
-{
-  for(unsigned int j = 0; j < m_InputVectorDataListParam->GetVectorDataList()->Size(); j++)
-    {
-    if(m_InputVectorDataListParam->SetNthFileName(j, m_FileSelectionList[j]->GetFilename()) == false)
-      {
-      std::ostringstream oss;
-      oss << "The given file " << m_FileSelectionList[j]->GetFilename() << " is not valid.";
-      this->GetModel()->SendLogWARNING(oss.str());
-      }
-    }
-
-  emit Change();
-
-  // notify of value change
-  QString key(m_InputVectorDataListParam->GetKey());
-  emit ParameterChanged(key);
-}
-
-
-void
-QtWidgetInputVectorDataListParameter::UpFile()
-{
- if(m_FileSelectionList.size() < 2)
-    return;
-
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(2);
 
-  // Map link between old and new index in the list
-  std::map<unsigned int, unsigned int> idMap;
+#include "otbWrapperInputVectorDataListParameter.h"
 
-  // Init map
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    idMap[i] = i;
-    }
-
-  // If the first item is checked, uncheck it...
-  // It won't be moved
-  if(m_FileSelectionList[0]->IsChecked())
-    {
-    m_FileSelectionList[0]->SetChecked(false);
-    }
-
-
-  // If other item are checked, up the index
-  // Starts at 1 because the first item mustn't move
-  for(unsigned int i = 1; i < m_FileSelectionList.size(); i++)
-    {
-    if(m_FileSelectionList[i]->IsChecked())
-      {
-      unsigned int tmp = idMap[i];
-      idMap[i] = i-1;
-      idMap[idMap[i-1]] = tmp;
-      }
-    }
-
-  this->UpdateFileList(idMap);
-
-  this->RecreateVectorDataList();
-}
-
-void
-QtWidgetInputVectorDataListParameter::DownFile()
-{
-  if(m_FileSelectionList.size() < 2) return;
-
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-
-  // Map link between old and new index in the list
-  std::map<unsigned int, unsigned int> idMap;
-
-  // Init map
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    idMap[i] = i;
-    }
-
-  // If the last item is checked, uncheck it...
-  // It won't be moved
-  if(m_FileSelectionList[m_FileSelectionList.size() - 1]->IsChecked())
-    {
-    m_FileSelectionList[m_FileSelectionList.size() - 1]->SetChecked(false);
-    }
-
-  // If other item are checked, up the index
-  // Stops at size-1 because the last item mustn't move
-  for(int i = m_FileSelectionList.size() - 2; i >= 0; i--)
-    {
-    if(m_FileSelectionList[i]->IsChecked())
-      {
-      unsigned int tmp = idMap[i];
-      idMap[i] = i + 1;
-      idMap[idMap[i + 1]] = tmp;
-      }
-    }
-
-  this->UpdateFileList(idMap);
-
-  this->RecreateVectorDataList();
-}
-
-
-void
-QtWidgetInputVectorDataListParameter::UpdateFileList(std::map<unsigned int, unsigned int> idMap)
+namespace otb
 {
-  std::vector<QtFileSelectionWidget *> tmpList;
-  // Keys become values and inverse
-  std::map<unsigned int, unsigned int> idMapBis;
-  for(unsigned int i = 0; i < idMap.size(); i++)
-    {
-    idMapBis[idMap[i]] = i;
-    }
-
-  // Create the new item list
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    m_FileLayout->addWidget(m_FileSelectionList[idMapBis[i]]);
-    tmpList.push_back(m_FileSelectionList[idMapBis[i]]);
-    }
 
-  m_FileSelectionList = tmpList;
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
 
-  this->update();
-
-  // notify of value change
-  QString key(m_InputVectorDataListParam->GetKey());
-  emit ParameterChanged(key);
-}
-
-
-void
-QtWidgetInputVectorDataListParameter::AddFile()
+namespace Wrapper
 {
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    m_FileLayout->addWidget(m_FileSelectionList[i]);
-    }
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  m_FileLayout->addWidget(fileSelection);
-  m_FileSelectionList.push_back(fileSelection);
-  m_InputVectorDataListParam->AddNullElement();
-  connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateVectorDataList()));
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
 
-  this->update();
 
-  emit FileSelectionWidgetAdded( fileSelection );
-}
-
-void
-QtWidgetInputVectorDataListParameter::SuppressFile()
+/*****************************************************************************/
+QtWidgetInputVectorDataListParameter
+::QtWidgetInputVectorDataListParameter( InputVectorDataListParameter * param,
+					QtWidgetModel* m ) :
+  QtWidgetParameterList( param, m )
 {
-  m_FileLayout = new QVBoxLayout();
-  m_FileLayout->setSpacing(0);
-  std::vector<QtFileSelectionWidget *> tmpList;
-  for(unsigned int i = 0; i < m_FileSelectionList.size(); i++)
-    {
-    if(!m_FileSelectionList[i]->IsChecked())
-      {
-      m_FileLayout->addWidget(m_FileSelectionList[i]);
-      tmpList.push_back(m_FileSelectionList[i]);
-      }
-    }
-
-  m_FileSelectionList = tmpList;
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-  this->RecreateVectorDataList();
 }
 
-
-void
-QtWidgetInputVectorDataListParameter::EraseFile()
+/*****************************************************************************/
+QtWidgetInputVectorDataListParameter
+::~QtWidgetInputVectorDataListParameter()
 {
-  m_FileSelectionList.clear();
-
-  m_FileLayout = new QVBoxLayout();
-
-  QtFileSelectionWidget * fileSelection = new QtFileSelectionWidget();
-  fileSelection->SetIOMode( QtFileSelectionWidget::IO_MODE_INPUT );
-  fileSelection->setFixedHeight(30);
-  m_FileLayout->addWidget(fileSelection);
-  m_FileSelectionList.push_back(fileSelection);
-  m_InputVectorDataListParam->AddNullElement();
-  connect(fileSelection->GetInput(), SIGNAL(textChanged(const QString&)), this, SLOT(UpdateVectorDataList()));
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(m_FileLayout);
-  m_Scroll->setWidget(mainGroup);
-
-  this->update();
-  this->RecreateVectorDataList();
 }
 
 
-void QtWidgetInputVectorDataListParameter::RecreateVectorDataList()
-{
-  // save value
-  m_InputVectorDataListParam->ClearValue();
-
-  if(m_FileSelectionList.size() == 0)
-    {
-    this->AddFile();
-    }
-  else
-    {
-    for(unsigned int j = 0; j < m_FileSelectionList.size(); j++)
-      {
-      m_InputVectorDataListParam->AddFromFileName(m_FileSelectionList[j]->GetFilename());
-      connect(m_FileSelectionList[j]->GetInput(), SIGNAL(textChanged(const QString&)),
-              this, SLOT(UpdateVectorDataList()));
-      }
-
-    emit Change();
-    // notify of value change
-    QString key(m_InputVectorDataListParam->GetKey());
-    emit ParameterChanged(key);
-    }
 }
 
-
-}
 }
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataParameter.cxx
index 3fd1a55..26c6e54 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetInputVectorDataParameter.cxx
@@ -61,7 +61,9 @@ void QtWidgetInputVectorDataParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_InputVectorDataParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_InputVectorDataParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetIntParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetIntParameter.cxx
index 2d4e7b1..052c919 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetIntParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetIntParameter.cxx
@@ -44,7 +44,9 @@ void QtWidgetIntParameter::DoCreateWidget()
 
   m_QSpinBox = new QSpinBox;
   m_QSpinBox->setRange(m_IntParam->GetMinimumValue(), m_IntParam->GetMaximumValue());
-  m_QSpinBox->setToolTip(m_IntParam->GetDescription());
+  m_QSpinBox->setToolTip(
+    QString::fromStdString( m_IntParam->GetDescription() )
+  );
 
   connect( m_QSpinBox, SIGNAL(valueChanged(int)), this, SLOT(SetValue(int)) );
   connect( m_QSpinBox, SIGNAL(valueChanged(int)), GetModel(), SLOT(NotifyUpdate()) );
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditItemModel.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditItemModel.cxx
new file mode 100644
index 0000000..b0ec1d5
--- /dev/null
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditItemModel.cxx
@@ -0,0 +1,483 @@
+/*
+ * 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 "otbWrapperQtWidgetListEditItemModel.h"
+
+
+/*****************************************************************************/
+/* INCLUDE SECTION                                                           */
+
+//
+// Qt includes (sorted by alphabetic order)
+//// Must be included before system/custom includes.
+
+//
+// System includes (sorted by alphabetic order)
+
+//
+// ITK includes (sorted by alphabetic order)
+
+//
+// OTB includes (sorted by alphabetic order)
+
+#include "otbWrapperStringListInterface.h"
+
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+/*
+  TRANSLATOR otb::Wapper::ListEditItemModel
+
+  Necessary for lupdate to be aware of C++ namespaces.
+
+  Context comment for translator.
+*/
+
+
+/*****************************************************************************/
+/* CONSTANTS                                                                 */
+
+namespace
+{
+
+const char * const
+HEADERS[ ListEditItemModel::COLUMN_COUNT ] =
+{
+  QT_TRANSLATE_NOOP( "otb::Wrapper::ListEditItemModel", "Name" ),
+  // QT_TRANSLATE_NOOP( "otb::Wrapper::ListEditItemModel", "Browse" ),
+};
+
+} // end of anonymous namespace.
+
+
+/*****************************************************************************/
+/* STATIC IMPLEMENTATION SECTION                                             */
+
+
+/*****************************************************************************/
+/* CLASS IMPLEMENTATION SECTION                                              */
+
+/*******************************************************************************/
+ListEditItemModel
+::ListEditItemModel( StringListInterface * sli,
+		     QObject * p ) :
+  QAbstractItemModel( p ),
+  m_StringList( sli )
+{
+  assert( sli!=nullptr );
+}
+
+/*******************************************************************************/
+ListEditItemModel
+::~ListEditItemModel()
+{
+}
+
+/*****************************************************************************/
+/* QAbstractItemModel overloads                                              */
+/*****************************************************************************/
+int
+ListEditItemModel
+::columnCount( const QModelIndex & ) const
+{
+  // qDebug() << this << "::columnCount(" << parent << ")";
+
+  return COLUMN_COUNT;
+}
+
+/*****************************************************************************/
+QVariant
+ListEditItemModel
+::data( const QModelIndex & idx, int role ) const
+{
+  // qDebug() << this << "::data(" << idx << "," << role << ")";
+
+  // Get layer.
+  assert( m_StringList!=NULL );
+
+  assert( idx.isValid() );
+  assert( !idx.parent().isValid() );
+  assert( idx.internalPointer()!=NULL );
+
+  const StringListInterface * stringList =
+    static_cast< const StringListInterface * >( idx.internalPointer() );
+
+  assert( stringList!=nullptr );
+
+  // Return data given role.
+  switch( role )
+    {
+    case Qt::CheckStateRole:
+#if 0
+      if( idx.column()!=COLUMN_NAME )
+        return QVariant();
+      else
+	{
+	assert( idx.row() >= 0 );
+	return stringList->IsActive( idx.row() );
+	}
+#endif
+      break;
+
+    case Qt::EditRole:
+    case Qt::DisplayRole:
+      switch( idx.column() )
+        {
+        case COLUMN_NAME:
+	  {
+	  assert( idx.row() >= 0 );
+
+	  std::string filename(
+	    stringList->GetNthFileName( idx.row() )
+	  );
+
+	  // qDebug() << "Filename:" << QString( "%1" ).arg( filename.c_str() );
+
+	  return
+	    filename.empty()
+	    ? ( role==Qt::EditRole ? QString() : "EMPTY" )
+	    : QFile::decodeName( filename.c_str()
+	    );
+	  }
+          break;
+
+	default:
+	  break;
+        }
+      break;
+
+    case Qt::FontRole:
+      break;
+
+    case Qt::ToolTipRole:
+      switch( idx.column() )
+	{
+	case COLUMN_NAME:
+	  assert( idx.row() >= 0 );
+	  return QString::fromStdString( stringList->GetToolTip( idx.row() ) );
+	  break;
+	}
+      break;
+
+    case USER_ROLE_DIRECTION:
+      assert( idx.row()>=0 );
+      return stringList->GetDirection( idx.row() );
+      break;
+
+    case USER_ROLE_FILTER:
+      assert( idx.row()>=0 );
+      return QString::fromStdString( stringList->GetFilenameFilter( idx.row() ) );
+      break;
+
+    default:
+      break;
+    }
+
+  return QVariant();
+}
+
+/*****************************************************************************/
+Qt::ItemFlags
+ListEditItemModel
+::flags( const QModelIndex & idx ) const
+{
+  if( !idx.isValid() )
+    return QAbstractItemModel::flags( idx );
+
+  Qt::ItemFlags iflags =
+    QAbstractItemModel::flags( idx )
+    // | Qt::ItemIsDragEnabled
+    // | Qt::ItemIsDropEnabled
+    ;
+
+  if( idx.column()==COLUMN_NAME )
+    iflags |=
+      Qt::ItemIsEditable
+      // | Qt::ItemIsUserCheckable
+      // | Qt::ItemIsDragEnabled
+      ;
+
+  return iflags;
+}
+
+/*****************************************************************************/
+bool
+ListEditItemModel
+::hasChildren( const QModelIndex & idx ) const
+{
+  return !idx.isValid();
+}
+
+/*****************************************************************************/
+QVariant
+ListEditItemModel
+::headerData( int section,
+              Qt::Orientation /**orientation*/,
+              int role ) const
+{
+  // qDebug()
+  //   << this << "::headerData("
+  //   << section << "," << orientation << "," << role
+  //   << ")";
+
+  // assert( orientation==Qt::Horizontal );
+
+  switch( role )
+    {
+    case Qt::DisplayRole:
+      assert( section>=0 && section<COLUMN_COUNT );
+      return tr( HEADERS[ section ] );
+      break;
+
+    default:
+      break;
+    }
+
+  return QVariant();
+}
+
+/*****************************************************************************/
+QModelIndex
+ListEditItemModel
+::index( int row,
+         int column,
+         const QModelIndex & p ) const
+{
+  // qDebug()
+  //   << this << "::index(" << row << "," << column << "," << parent << ")";
+
+  if( m_StringList == nullptr )
+    return QModelIndex();
+
+  // qDebug()
+  //   << "index:" << row << "," << column << "," << m_StringList->At( row );
+
+  assert( row>=0 && column>=0 );
+
+#if 0
+  AbstractLayerModel * layer = m_StringList->At( row );
+
+  if( layer==NULL || p.isValid() )
+    return QModelIndex();
+#endif
+
+  return
+    createIndex(
+      row,
+      column,
+      p.isValid()
+      ? NULL
+      : m_StringList
+    );
+}
+
+/*****************************************************************************/
+bool
+ListEditItemModel
+::insertRow( int row, const QModelIndex & idxParent )
+{
+  return insertRows( row, 1, idxParent );
+}
+
+/*****************************************************************************/
+bool
+ListEditItemModel
+::insertRows( int row, int count, const QModelIndex & idxParent )
+{
+  // qDebug() << this << "::insertRows(" << row << "," << count << "," << idxParent << ")";
+
+  assert( m_StringList!=nullptr );
+
+  beginInsertRows( idxParent, row, count );
+  {
+    for( int r=row; r<row+count; ++r )
+      m_StringList->Insert( "", r );
+  }
+  endInsertRows();
+
+  return true;
+}
+
+/*****************************************************************************/
+QModelIndex
+ListEditItemModel
+::parent( const QModelIndex & ) const
+{
+  // qDebug() << this << "::parent(" << index << ")";
+
+  return QModelIndex();
+}
+
+/*****************************************************************************/
+bool
+ListEditItemModel
+::removeRows( int row, int count, const QModelIndex & p )
+{
+  assert( !p.isValid() );
+  assert( count>=1 );
+
+  if( p.isValid() || count<1 )
+    return false;
+
+  assert( m_StringList!=nullptr );
+
+  beginRemoveRows( p, row, row + count - 1 );
+  {
+    m_StringList->Erase( row, count );
+  }
+  endRemoveRows();
+
+  return true;
+}
+
+/*****************************************************************************/
+int
+ListEditItemModel
+::rowCount( const QModelIndex & p ) const
+{
+  // qDebug() << this << "::rowCount(" << p << ")";
+
+  // qDebug() << "row-count:" <<
+  //   ( ( m_StringList==NULL || p.isValid() )
+  //     ? 0
+  //     : m_StringList->GetCount()
+  //   );
+
+  return
+    ( m_StringList==nullptr || p.isValid() )
+    ? 0
+    : m_StringList->Size();
+}
+
+/*****************************************************************************/
+bool
+ListEditItemModel
+::setData( const QModelIndex & idx,
+           const QVariant & value,
+           int role )
+{
+  // qDebug()
+  //   << this << "::setData(" << idx << "," << value << "," << role
+  //   << ");";
+
+  assert( !idx.parent().isValid() );
+  assert( idx.row()>=0 );
+  assert( idx.internalPointer()!=nullptr );
+
+  StringListInterface * stringList =
+    static_cast< StringListInterface * >( idx.internalPointer() );
+
+  switch( idx.column() )
+    {
+    case COLUMN_NAME:
+      switch( role )
+	{
+	case Qt::EditRole:
+	  stringList->SetNthFileName(
+	    idx.row(),
+	    QFile::encodeName( value.toString() ).data()
+	  );
+	  emit dataChanged( idx, idx );
+	  return true;
+	  break;
+
+	case Qt::CheckStateRole:
+	  break;
+
+	case USER_ROLE_DIRECTION:
+	  break;
+
+	default:
+	  break;
+	}
+      break;
+
+    default:
+      break;
+    }
+
+  return false;
+}
+
+/*******************************************************************************/
+bool
+ListEditItemModel
+::Swap( int row1, int row2 )
+{
+  assert( m_StringList!=nullptr );
+
+  assert( row1>=0 );
+  assert( static_cast< unsigned int >( row1 )<m_StringList->Size() );
+
+  assert( row2>=0 );
+  assert( static_cast< unsigned int >( row2 )<m_StringList->Size() );
+
+  assert( row1!=row2 );
+
+  emit layoutAboutToBeChanged();
+
+  m_StringList->Swap( row1, row2 );
+
+  emit layoutChanged();
+
+  return true;
+}
+
+/*******************************************************************************/
+bool
+ListEditItemModel
+::IsInput() const
+{
+  assert( m_StringList!=nullptr );
+
+  return m_StringList->GetDirection()==Role_Input;
+}
+
+/*******************************************************************************/
+bool
+ListEditItemModel
+::IsBrowsable() const
+{
+  assert( m_StringList!=nullptr );
+
+  return m_StringList->IsFilename();
+}
+
+/*******************************************************************************/
+QString
+ListEditItemModel
+::GetFilter() const
+{
+  assert( m_StringList!=nullptr );
+
+  return QString::fromStdString( m_StringList->GetFilenameFilter() );
+}
+
+/*******************************************************************************/
+/* SLOTS                                                                       */
+/*******************************************************************************/
+
+} // end namespace 'Wrapper'.
+
+} // end namespace 'otb'
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditWidget.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditWidget.cxx
new file mode 100644
index 0000000..f2b1524
--- /dev/null
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditWidget.cxx
@@ -0,0 +1,657 @@
+/*
+ * 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 "otbWrapperQtWidgetListEditWidget.h"
+#include "ui_otbWrapperQtWidgetListEditWidget.h"
+
+
+/*****************************************************************************/
+/* INCLUDE SECTION                                                           */
+
+//
+// Qt includes (sorted by alphabetic order)
+//// Must be included before system/custom includes.
+
+//
+// System includes (sorted by alphabetic order)
+
+//
+// ITK includes (sorted by alphabetic order)
+
+//
+// OTB includes (sorted by alphabetic order)
+#include "otbQtAdapters.h"
+#include "otbWrapperQtWidgetListEditItemModel.h"
+#include "otbWrapperTypes.h"
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+/*
+  TRANSLATOR otn::Wrappers
+
+  Necessary for lupdate to be aware of C++ namespaces.
+
+  Context comment for translator.
+*/
+
+
+/*****************************************************************************/
+/* CONSTANTS                                                                 */
+
+
+/*****************************************************************************/
+/* STATIC IMPLEMENTATION SECTION                                             */
+
+
+/*****************************************************************************/
+/* CLASS IMPLEMENTATION SECTION                                              */
+/*****************************************************************************/
+ListEditWidget
+::ListEditWidget( StringListInterface * sli,
+		  QWidget * p,
+		  Qt::WindowFlags flags ) :
+  QWidget( p, flags ),
+  m_UI( new otb::Wrapper::Ui::ListEditWidget() )
+{
+  m_UI->setupUi( this );
+
+  setAcceptDrops(true);
+
+  assert( m_UI->treeView->selectionModel()==nullptr );
+
+  //
+  // Item-model.
+  ListEditItemModel * model = new ListEditItemModel( sli, m_UI->treeView );
+
+  m_UI->treeView->setModel( model );
+
+  QObject::connect(
+    model, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ),
+    this, SLOT( OnDataChanged( const QModelIndex &, const QModelIndex & ) )
+  );
+
+  QObject::connect(
+    model, SIGNAL( modelReset() ),
+    this, SLOT( OnModelReset() )
+  );
+
+  QObject::connect(
+    model, SIGNAL( rowsInserted( const QModelIndex &, int, int ) ),
+    this, SLOT( OnRowsInserted( const QModelIndex &, int, int ) )
+  );
+
+  QObject::connect(
+    model, SIGNAL( rowsRemoved( const QModelIndex &, int, int ) ),
+    this, SLOT( OnRowsRemoved( const QModelIndex &, int, int ) )
+  );
+
+  //
+  // Selection-model.
+  assert( m_UI->treeView->selectionModel()!=nullptr );
+
+  QObject::connect(
+    m_UI->treeView->selectionModel(),
+    SIGNAL(
+      selectionChanged( const QItemSelection & , const QItemSelection & )
+    ),
+    // to:
+    this,
+    SLOT(
+      OnSelectionChanged( const QItemSelection & , const QItemSelection & )
+    )
+  );
+
+  //
+  // Browse-button.
+  assert( m_UI->browseButton!=nullptr );
+
+  m_UI->browseButton->setEnabled( model->IsBrowsable() );
+}
+
+/*******************************************************************************/
+ListEditWidget
+::~ListEditWidget()
+{
+  delete m_UI;
+  m_UI = nullptr;
+}
+
+#if 0
+
+/*****************************************************************************/
+void
+ListEditWidget
+::SetBrowseEnabled( bool enabled )
+{
+  assert( m_UI!=nullptr );
+  assert( m_UI->browseButton );
+
+  m_UI->browseButton->setEnabled( enabled );
+}
+
+/*******************************************************************************/
+bool
+ListEditWidget
+::IsBrowseEnabled() const
+{
+  assert( m_UI!=nullptr );
+  assert( m_UI->browseButton );
+
+  return m_UI->browseButton->isEnabled();
+}
+
+#endif
+
+/*******************************************************************************/
+const ListEditItemModel *
+ListEditWidget
+::GetItemModel() const
+{
+  return const_cast< ListEditWidget * >( this )->GetItemModel();
+}
+
+/*******************************************************************************/
+ListEditItemModel *
+ListEditWidget
+::GetItemModel()
+{
+  assert(
+    m_UI->treeView->model()==
+    qobject_cast< ListEditItemModel * >( m_UI->treeView->model() )
+    );
+
+  return qobject_cast< ListEditItemModel * >( m_UI->treeView->model() );
+}
+
+/*******************************************************************************/
+void
+ListEditWidget
+::Swap( int row1, int row2, SwapSelection s )
+{
+  assert( GetItemModel()!=nullptr );
+
+  assert( row1>=0 );
+  assert( row1<GetItemModel()->rowCount() );
+
+  assert( row2>=0 );
+  assert( row2<GetItemModel()->rowCount() );
+
+
+  ListEditItemModel * itemModel = GetItemModel();
+
+  assert( itemModel!=nullptr );
+
+
+  itemModel->Swap( row1, row2 );
+
+
+  {
+    int row =
+      s==LEFT
+      ? row1
+      : ( s==RIGHT
+	  ? row2
+	  : -1 );
+
+    if( row<0 )
+      return;
+
+    assert( m_UI!=nullptr );
+    assert( m_UI->treeView!=nullptr );
+    assert( m_UI->treeView->selectionModel()!=nullptr );
+
+    QItemSelectionModel * ism =  m_UI->treeView->selectionModel();
+
+    assert( ism!=nullptr );
+
+    ism->clear();
+
+    ism->setCurrentIndex(
+      itemModel->index( row, ListEditItemModel::COLUMN_NAME ),
+      QItemSelectionModel::Clear |
+      QItemSelectionModel::Select |
+      QItemSelectionModel::Current |
+      QItemSelectionModel::Rows
+    );
+  }
+}
+
+/*******************************************************************************/
+QStringList
+ListEditWidget
+::browseFilenames( bool multi , const QString & filename )
+{
+  const ListEditItemModel * itemModel = GetItemModel();
+  assert( itemModel!=nullptr );
+
+  QString filePath(
+    QDir::current().filePath(
+      filename
+    )
+  );
+
+  QString selectedFilter;
+  QStringList output;
+  if(itemModel->IsInput())
+    {
+    if (multi)
+      {
+      output = GetOpenFileNames(
+        this,
+        tr( "Select input filename..." ),
+        filePath,
+        itemModel->GetFilter(),
+        &selectedFilter
+        );
+      }
+    else
+      {
+      output.push_back(
+        GetOpenFileName(
+          this,
+          tr( "Select input filename..." ),
+          filePath,
+          itemModel->GetFilter(),
+          &selectedFilter
+          )
+        );
+      }
+    }
+  else
+    {
+    output.push_back(
+      GetSaveFileName(
+        this,
+        tr( "Select output filename..." ),
+        filePath,
+        itemModel->GetFilter(),
+        &selectedFilter
+        )
+      );
+    }
+  return output;
+}
+
+/*******************************************************************************/
+QString
+ListEditWidget
+::browseFilename( const QModelIndex & index )
+{
+  assert( index.isValid() );
+  assert( index.row()>=0 );
+  assert( index.column()>=0 );
+
+  //
+  // Get item-model.
+  const ListEditItemModel * itemModel = GetItemModel();
+  assert( itemModel!=nullptr );
+
+  //
+  // Pick-up filename.
+  assert(
+    itemModel->data( index, ListEditItemModel::USER_ROLE_DIRECTION ).isValid()
+  );
+
+  assert(
+    itemModel->data( index, ListEditItemModel::USER_ROLE_DIRECTION )==Role_Input
+    ||
+    itemModel->data( index, ListEditItemModel::USER_ROLE_DIRECTION )==Role_Output
+  );
+
+  return
+    (browseFilenames( false, itemModel->data( index ).toString() )).front();
+}
+
+
+/*******************************************************************************/
+/* SLOTS                                                                       */
+/*******************************************************************************/
+void
+ListEditWidget
+::OnFilenameDropped(const QString & filename)
+{
+  ListEditItemModel * itemModel = GetItemModel();
+  assert( itemModel!=nullptr );
+
+  if( filename.isEmpty() )
+    return;
+
+  int row = itemModel->rowCount();
+  assert( row>=0 );
+
+  if( !itemModel->insertRow( row ) )
+    return;
+
+  itemModel->setData(
+    itemModel->index( row, ListEditItemModel::COLUMN_NAME ),
+    filename
+  );
+}
+
+
+void
+ListEditWidget
+::on_addButton_clicked()
+{
+  // qDebug() << this << "::on_addButton_clicked()";
+
+  ListEditItemModel * itemModel = GetItemModel();
+  assert( itemModel!=nullptr );
+
+  //
+  // When not browsable
+  if( !itemModel->IsBrowsable() )
+    {
+    itemModel->insertRow( itemModel->rowCount() );
+
+    return;
+    }
+
+  //
+  // When browsable.
+  QStringList filenames( browseFilenames(true) );
+
+  if( filenames.isEmpty() )
+    return;
+
+  int row = itemModel->rowCount();
+  assert( row>=0 );
+
+  for (int i=0 ; i<filenames.size() ; i++)
+    {
+    if( !itemModel->insertRow( row ) )
+      return;
+
+    itemModel->setData(
+      itemModel->index( row, ListEditItemModel::COLUMN_NAME ),
+      filenames[i]
+    );
+    row++;
+    }
+}
+
+/*******************************************************************************/
+void
+ListEditWidget
+::on_removeButton_clicked()
+{
+  // qDebug() << this << "::on_removeButton_clicked()";
+
+  assert( m_UI->treeView->selectionModel()!=nullptr );
+
+
+  QModelIndexList indexes(
+    m_UI->treeView->selectionModel()->selectedRows()
+  );
+
+  if( indexes.empty() )
+    return;
+
+
+  ListEditItemModel * itemModel = GetItemModel();
+
+  assert( itemModel!=nullptr );
+
+
+  for( const QModelIndex & i : indexes )
+    {
+    assert( i.isValid() );
+
+    itemModel->removeRow( i.row() );
+    }
+}
+
+/*******************************************************************************/
+void
+ListEditWidget
+::on_removeAllButton_clicked()
+{
+  // qDebug() << this << "::on_removeAllButton_clicked()";
+
+  ListEditItemModel * model = GetItemModel();
+  assert( model );
+
+  if( model->rowCount()<1 )
+    return;
+
+  assert( qApp );
+  assert( !qApp->applicationName().isEmpty() );
+
+  if( QMessageBox::question(
+	this,
+	qApp->applicationName(),
+	tr("Are you sure you want to delete all (%1) item(s)?")
+	.arg( model->rowCount() ),
+	QMessageBox::Yes | QMessageBox::No,
+	QMessageBox::No
+      )
+      ==QMessageBox::No )
+    return;
+
+  model->removeRows( 0, model->rowCount() );
+}
+
+/*******************************************************************************/
+void
+ListEditWidget
+::on_upButton_clicked()
+{
+  // qDebug() << this << "::on_upButton_clicked()";
+
+  assert( m_UI!=nullptr );
+  assert( m_UI->treeView!=nullptr );
+  assert( m_UI->treeView->selectionModel()!=nullptr );
+
+
+  QModelIndexList indexes(
+    m_UI->treeView->selectionModel()->selectedRows()
+  );
+
+  if( indexes.empty() )
+    return;
+
+  assert( indexes.size()==1 );
+
+
+  const QModelIndex & front = indexes.front();
+
+  if( front.row()<1 )
+    return;
+
+
+  Swap(
+    front.row(),
+    front.row() - 1,
+    RIGHT
+  );
+}
+
+/*******************************************************************************/
+void
+ListEditWidget
+::on_downButton_clicked()
+{
+  // qDebug() << this << "::on_downButton_clicked()";
+
+  assert( m_UI!=nullptr );
+  assert( m_UI->treeView!=nullptr );
+  assert( m_UI->treeView->selectionModel()!=nullptr );
+
+
+  QModelIndexList indexes(
+    m_UI->treeView->selectionModel()->selectedRows()
+  );
+
+  if( indexes.empty() )
+    return;
+
+  assert( indexes.size()==1 );
+
+
+  const QModelIndex & front = indexes.front();
+
+  if( front.row() >= GetItemModel()->rowCount() - 1 )
+    return;
+
+
+  Swap(
+    front.row(),
+    front.row() + 1,
+    RIGHT
+  );
+}
+
+/*******************************************************************************/
+void
+ListEditWidget
+::on_browseButton_clicked()
+{
+  // qDebug() << this << "::on_browseButton_clicked()";
+
+  assert( m_UI!=nullptr );
+  assert( m_UI->treeView!=nullptr );
+  assert( m_UI->treeView->selectionModel()!=nullptr );
+
+
+  //
+  // Pick-up first item of selection.
+  QModelIndexList indexes(
+    m_UI->treeView->selectionModel()->selectedRows()
+  );
+
+  if( indexes.isEmpty() )
+    return;
+
+  assert( indexes.size()==1 );
+
+  const QModelIndex & front = indexes.front();
+
+  //
+  // Get item-model.
+  ListEditItemModel * itemModel = GetItemModel();
+  assert( itemModel!=nullptr );
+
+  //
+  // Pick-up filename.
+  QString selectedFilter;
+
+  QString filename( browseFilename( front ) );
+
+  if( filename.isEmpty() )
+    return;
+
+  //
+  // Foo.
+  itemModel->setData( front, filename );
+}
+
+/*******************************************************************************/
+void
+ListEditWidget
+::OnSelectionChanged( const QItemSelection & /* selected */,
+		      const QItemSelection & /* deselected */ )
+{
+  // qDebug()
+  //   << this
+  //   << "::onSelectionChanged(" << selected << "," << deselected << ")";
+
+  // Experimental code.
+  // assert( selected.indexes().size()>=0 && selected.indexes().size()<=1 );
+
+  // assert( m_UI->upButton );
+  // assert( m_UI->downButton );
+  // assert( m_UI->browseButton );
+  // assert( m_UI->removeButton );
+
+  // if( selected.empty() )
+  //   {
+  //   m_UI->browseButton->setEnabled( false );
+  //   m_UI->removeButton->setEnabled( false );
+
+  //   m_UI->upButton->setEnabled( false );
+  //   m_UI->downButton->setEnabled( false );
+
+  //   return;
+  //   }
+
+  // assert( GetItemModel() );
+
+  // m_UI->browseButton->setEnabled( GetItemModel()->IsBrowsable() );
+  // m_UI->removeButton->setEnabled( true );
+
+  // const QModelIndex & index = selected.indexes().front();
+
+  // m_UI->upButton->setEnabled( index.isValid() && index.row()>0 );
+
+  // m_UI->downButton->setEnabled(
+  //   index.isValid() &&
+  //   index.sibling( index.row() + 1, index.column() ).isValid()
+  // );
+}
+
+/*****************************************************************************/
+void
+ListEditWidget
+::OnDataChanged( const QModelIndex &, const QModelIndex & )
+{
+  // qDebug() << this << "::OnDataChanged()";
+
+  assert( GetItemModel()!=nullptr );
+
+  emit Updated();
+}
+
+/*****************************************************************************/
+void
+ListEditWidget
+::OnModelReset()
+{
+  // qDebug() << this << "::OnModelReset()";
+
+  emit Updated();
+}
+
+/*****************************************************************************/
+void
+ListEditWidget
+::OnRowsInserted( const QModelIndex &, int, int )
+{
+  // qDebug() << this << "::OnRowsInserted()";
+
+  emit Updated();
+}
+
+/*****************************************************************************/
+void
+ListEditWidget
+::OnRowsRemoved( const QModelIndex &, int, int )
+{
+  // qDebug() << this << "::OnRowsRemoved()";
+
+  emit Updated();
+}
+
+} // end namespace 'Wrapper'
+
+} // end namespace 'otb'
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditWidget.ui b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditWidget.ui
new file mode 100644
index 0000000..58a773e
--- /dev/null
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListEditWidget.ui
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>otb::Wrapper::ListEditWidget</class>
+ <widget class="QWidget" name="otb::Wrapper::ListEditWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>122</width>
+    <height>178</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="locale">
+   <locale language="C" country="AnyCountry"/>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <property name="margin">
+    <number>3</number>
+   </property>
+   <property name="spacing">
+    <number>3</number>
+   </property>
+   <item row="0" column="0">
+    <widget class="QTreeView" name="treeView"/>
+   </item>
+   <item row="0" column="1">
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <property name="spacing">
+      <number>1</number>
+     </property>
+     <item>
+      <widget class="QToolButton" name="upButton">
+       <property name="toolTip">
+        <string>Move up</string>
+       </property>
+       <property name="text">
+        <string>Up</string>
+       </property>
+       <property name="arrowType">
+        <enum>Qt::UpArrow</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="addButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Add</string>
+       </property>
+       <property name="text">
+        <string>+</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="browseButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Browse filename</string>
+       </property>
+       <property name="text">
+        <string>...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="removeAllButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Remove all items</string>
+       </property>
+       <property name="text">
+        <string>✕</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="removeButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="toolTip">
+        <string>Remove</string>
+       </property>
+       <property name="text">
+        <string>-</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="downButton">
+       <property name="toolTip">
+        <string>Move down</string>
+       </property>
+       <property name="text">
+        <string>Down</string>
+       </property>
+       <property name="arrowType">
+        <enum>Qt::DownArrow</enum>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListViewParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListViewParameter.cxx
index 7f7b3ab..f4f31d4 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListViewParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetListViewParameter.cxx
@@ -102,7 +102,9 @@ void QtWidgetListViewParameter::DoUpdateGUI()
 void QtWidgetListViewParameter::DoCreateWidget()
 {
   m_ListView = new QListWidget();
-  m_ListView->setToolTip(m_ListViewParam->GetDescription());
+  m_ListView->setToolTip(
+    QString::fromStdString( m_ListViewParam->GetDescription() )
+  );
 
   if(m_ListViewParam->GetSingleSelection())
     {
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx
index 1fa1e28..a0d6113 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetModel.cxx
@@ -70,7 +70,42 @@ QtWidgetModel
 ::NotifyUpdate()
 {
   // Update the parameters
-  m_Application->UpdateParameters();
+  try
+  {
+    m_Application->UpdateParameters();
+  }
+  catch(otb::ApplicationException& err)
+  {
+    m_Application->GetLogger()->Debug("Caught otb::ApplicationException during application update:\n");
+    m_Application->GetLogger()->Debug(string(err.what()) + "\n");
+    emit ExceptionRaised( err.what() );
+  }
+  catch(otb::ImageFileReaderException& err)
+  {
+    m_Application->GetLogger()->Debug("Caught otb::ImageFileReaderException during application update:\n");
+    m_Application->GetLogger()->Debug(string(err.what()) + "\n");
+    string message( string("Cannot open image ") + err.m_Filename + string(". ") + err.GetDescription() );
+    m_Application->GetLogger()->Fatal( message + string("\n"));
+    emit ExceptionRaised( message.c_str() );
+  }
+  catch(itk::ExceptionObject& err)
+  {
+    m_Application->GetLogger()->Debug("Caught itk::ExceptionObject during application update:\n");
+    m_Application->GetLogger()->Debug(string(err.what()) + "\n");
+    m_Application->GetLogger()->Fatal(string(err.GetDescription()) + "\n");
+    emit ExceptionRaised( err.GetDescription() );
+  }
+  catch(std::exception& err)
+  {
+    m_Application->GetLogger()->Fatal(string("Caught std::exception during application update: ") + err.what() + "\n");
+    emit ExceptionRaised( err.what() );
+  }
+  catch(...)
+  {
+    m_Application->GetLogger()->Fatal("Caught unknown exception during application update.\n");
+    emit ExceptionRaised("Unknown exception");
+  }
+
   emit UpdateGui();
 
   // Notify all
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputFilenameParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputFilenameParameter.cxx
index 78ea7f7..4f39526 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputFilenameParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputFilenameParameter.cxx
@@ -57,7 +57,9 @@ void QtWidgetOutputFilenameParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_FilenameParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_FilenameParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx
index bd47efd..140ff65 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx
@@ -58,7 +58,9 @@ void QtWidgetOutputImageParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit();
-  m_Input->setToolTip( m_OutputImageParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_OutputImageParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
   m_HLayout->addWidget(m_Input);
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputProcessXMLParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputProcessXMLParameter.cxx
index 3e67ad0..324fa4e 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputProcessXMLParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputProcessXMLParameter.cxx
@@ -55,7 +55,9 @@ void QtWidgetOutputProcessXMLParameter::DoCreateWidget()
   m_HLayout->setSpacing(0);
   m_HLayout->setContentsMargins(0, 0, 0, 0);
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_XMLParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_XMLParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputVectorDataParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputVectorDataParameter.cxx
index b605c9b..62c0604 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputVectorDataParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputVectorDataParameter.cxx
@@ -53,7 +53,9 @@ void QtWidgetOutputVectorDataParameter::DoCreateWidget()
   m_HLayout->setContentsMargins(0, 0, 0, 0);
 
   m_Input = new QLineEdit;
-  m_Input->setToolTip( m_OutputVectorDataParam->GetDescription() );
+  m_Input->setToolTip(
+    QString::fromStdString( m_OutputVectorDataParam->GetDescription() )
+  );
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetFileName(const QString&)) );
   connect( m_Input, SIGNAL(textChanged(const QString&)), GetModel(), SLOT(NotifyUpdate()) );
   m_HLayout->addWidget(m_Input);
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx
index 2efb315..eb44e1a 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterBase.cxx
@@ -103,6 +103,21 @@ void QtWidgetParameterBase::Reset(  )
   this->UpdateGUI();
 }
 
+const Parameter *
+QtWidgetParameterBase
+::GetParam() const
+{
+  return m_Param;
+}
+
+Parameter *
+QtWidgetParameterBase
+::GetParam()
+{
+  return m_Param;
+}
+
+
 }
 
 }
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx
index 5f57b48..89763c4 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterFactory.cxx
@@ -21,39 +21,45 @@
 #include "otbWrapperQtWidgetParameterFactory.h"
 
 #include "otbWrapperParameter.h"
-#include "otbWrapperQtWidgetModel.h"
-
-#include "otbWrapperQtWidgetParameterBase.h"
+#include "otbWrapperInputFilenameListParameter.h"
+#include "otbWrapperInputVectorDataListParameter.h"
+#include "otbWrapperStringListParameter.h"
 
-#include "otbWrapperQtWidgetEmptyParameter.h"
-#include "otbWrapperQtWidgetIntParameter.h"
-#include "otbWrapperQtWidgetFloatParameter.h"
-#include "otbWrapperQtWidgetStringParameter.h"
-#include "otbWrapperQtWidgetStringListParameter.h"
 #include "otbWrapperQtWidgetChoiceParameter.h"
-#include "otbWrapperQtWidgetListViewParameter.h"
-#include "otbWrapperQtWidgetInputImageParameter.h"
 #include "otbWrapperQtWidgetComplexInputImageParameter.h"
 #include "otbWrapperQtWidgetComplexOutputImageParameter.h"
-#include "otbWrapperQtWidgetInputImageListParameter.h"
-#include "otbWrapperQtWidgetOutputImageParameter.h"
-#include "otbWrapperQtWidgetOutputVectorDataParameter.h"
+#include "otbWrapperQtWidgetDirectoryParameter.h"
+#include "otbWrapperQtWidgetEmptyParameter.h"
+#include "otbWrapperQtWidgetFloatParameter.h"
+#include "otbWrapperQtWidgetIntParameter.h"
 #include "otbWrapperQtWidgetInputFilenameParameter.h"
 #include "otbWrapperQtWidgetInputFilenameListParameter.h"
-#include "otbWrapperQtWidgetOutputFilenameParameter.h"
-#include "otbWrapperQtWidgetDirectoryParameter.h"
-#include "otbWrapperQtWidgetParameterGroup.h"
+#include "otbWrapperQtWidgetInputImageParameter.h"
+#include "otbWrapperQtWidgetInputImageListParameter.h"
+#include "otbWrapperQtWidgetInputProcessXMLParameter.h"
 #include "otbWrapperQtWidgetInputVectorDataListParameter.h"
 #include "otbWrapperQtWidgetInputVectorDataParameter.h"
-#include "otbWrapperQtWidgetRAMParameter.h"
+#include "otbWrapperQtWidgetListViewParameter.h"
+#include "otbWrapperQtWidgetModel.h"
+#include "otbWrapperQtWidgetOutputFilenameParameter.h"
+#include "otbWrapperQtWidgetOutputImageParameter.h"
 #include "otbWrapperQtWidgetOutputProcessXMLParameter.h"
-#include "otbWrapperQtWidgetInputProcessXMLParameter.h"
+#include "otbWrapperQtWidgetOutputVectorDataParameter.h"
+#include "otbWrapperQtWidgetParameterBase.h"
+#include "otbWrapperQtWidgetParameterGroup.h"
+#include "otbWrapperQtWidgetRAMParameter.h"
+#include "otbWrapperQtWidgetStringParameter.h"
+#include "otbWrapperQtWidgetStringListParameter.h"
+
 
 namespace otb
 {
+
+
 namespace Wrapper
 {
 
+
 template <class TParameterType, class TQtWidget>
 class QtWidgetParameterGenericFactory
 {
@@ -66,13 +72,14 @@ public:
 
   static QtWidgetParameterBase* Create( Parameter* param, QtWidgetModel* model )
   {
-    QtWidgetParameterBase* widget = ITK_NULLPTR;
-    TParameterType* specificParam = dynamic_cast<TParameterType *>(param);
+    QtWidgetParameterBase * widget = ITK_NULLPTR;
+    TParameterType * specificParam = dynamic_cast< TParameterType * >( param );
+
+    // Code should break if param is not a TParameterType and not be silent!
+    assert( specificParam!=nullptr );
+
+    widget = new TQtWidget( specificParam, model );
 
-    if (specificParam)
-      {
-      widget = new TQtWidget(specificParam, model);
-      }
     return widget;
   }
 };
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterList.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterList.cxx
new file mode 100644
index 0000000..5770106
--- /dev/null
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetParameterList.cxx
@@ -0,0 +1,94 @@
+/*
+ * 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 "otbWrapperParameterList.h"
+#include "otbWrapperQtWidgetListEditItemModel.h"
+#include "otbWrapperQtWidgetListEditWidget.h"
+#include "otbWrapperQtWidgetParameterList.h"
+
+
+namespace otb
+{
+
+namespace Wrapper
+{
+
+
+/*****************************************************************************/
+QtWidgetParameterList
+::QtWidgetParameterList( AbstractParameterList * param, QtWidgetModel * m ) :
+  QtWidgetParameterBase( param, m )
+{
+  assert( m!=nullptr );
+
+  QObject::connect(
+    this, SIGNAL( NotifyUpdate() ),
+    m, SLOT( NotifyUpdate() )
+  );
+}
+
+/*****************************************************************************/
+QtWidgetParameterList
+::~QtWidgetParameterList()
+{
+}
+
+/*****************************************************************************/
+void
+QtWidgetParameterList
+::DoUpdateGUI()
+{
+}
+
+/*****************************************************************************/
+void
+QtWidgetParameterList
+::DoCreateWidget()
+{
+  //
+  // List-edit widget.
+  assert( dynamic_cast< StringListInterface * >( GetParam() )!=nullptr );
+
+  ListEditWidget * widget = new ListEditWidget(
+    dynamic_cast< StringListInterface * >( GetParam() )
+  );
+
+  //
+  // Global Layout
+  QGridLayout * gLayout = new QGridLayout();
+
+  gLayout->setSpacing( 1 );
+  gLayout->setContentsMargins( 2, 2, 2, 2 );
+
+  gLayout->addWidget( widget );
+
+  setLayout( gLayout );
+
+  //
+  // Connections.
+  QObject::connect(
+    widget, SIGNAL( Updated() ),
+    this, SIGNAL( NotifyUpdate() )
+  );
+}
+
+}
+
+}
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetRAMParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetRAMParameter.cxx
index ffe5336..be73e12 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetRAMParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetRAMParameter.cxx
@@ -43,7 +43,9 @@ void QtWidgetRAMParameter::DoCreateWidget()
   m_QHBoxLayout->setContentsMargins(0, 0, 0, 0);
 
   m_QSpinBox = new QSpinBox;
-  m_QSpinBox->setToolTip(m_RAMParam->GetDescription());
+  m_QSpinBox->setToolTip(
+    QString::fromStdString( m_RAMParam->GetDescription() )
+  );
 
   connect( m_QSpinBox, SIGNAL(valueChanged(int)), this, SLOT(SetValue(int)) );
   connect( m_QSpinBox, SIGNAL(valueChanged(int)), GetModel(), SLOT(NotifyUpdate()) );
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetSimpleProgressReport.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetSimpleProgressReport.cxx
index cb595eb..c8347b2 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetSimpleProgressReport.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetSimpleProgressReport.cxx
@@ -45,7 +45,9 @@ QtWidgetSimpleProgressReport::QtWidgetSimpleProgressReport(QtWidgetModel * model
   m_AddProcessCommand->SetCallbackFunction( this, &QtWidgetSimpleProgressReport::ProcessEvent );
 
   m_Bar =  new itk::QtProgressBar(this);
+
   m_Label = new QLabel("No process");
+  m_Label->setWordWrap(true);
   connect( m_Bar, SIGNAL(SetValueChanged(int)), m_Bar, SLOT(setValue(int)) );
   connect( m_Model, SIGNAL(SetProgressReportDone()), m_Bar, SLOT(reset()) );
 
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringListParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringListParameter.cxx
index 04667ea..60a9073 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringListParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringListParameter.cxx
@@ -20,110 +20,35 @@
 
 #include "otbWrapperQtWidgetStringListParameter.h"
 
-namespace otb
-{
-namespace Wrapper
-{
 
-QtWidgetStringListParameter::QtWidgetStringListParameter(StringListParameter* param, QtWidgetModel* m)
-: QtWidgetParameterBase(param, m),
-  m_StringListParam(param)
-{
- connect( this,
-          SIGNAL(Change()),
-          GetModel(),
-          SLOT(NotifyUpdate()) );
-}
+#include "otbWrapperStringListParameter.h"
 
-QtWidgetStringListParameter::~QtWidgetStringListParameter()
-{
-}
 
-void QtWidgetStringListParameter::DoUpdateGUI()
+namespace otb
 {
-  if(!m_StringListParam)
-    return;
 
-  std::vector<std::string> strList = m_StringListParam->GetValue();
-  for( unsigned int i = m_LineEditList.size(); i < strList.size(); i++ )
-    {
-      this->AddString();
-    }
-  int i = 0;
-  std::vector<std::string>::iterator it;
-  for (it = strList.begin(); it != strList.end(); ++it)
-    {
-      m_LineEditList[i++]->SetText(QString( (*it).c_str() ));
-    }
-}
 
-void QtWidgetStringListParameter::DoCreateWidget()
+namespace Wrapper
 {
-  m_LineEditList.clear();
-  const unsigned int sp(2);
-  const unsigned int buttonSize(30);
 
-  // Global layout
-  QHBoxLayout * hLayout = new QHBoxLayout;
-  hLayout->setSpacing(sp);
-  hLayout->setContentsMargins(sp, sp, sp, sp);
 
-  if( m_StringListParam->GetRole() != Role_Output )
-    {
-    // Button layout
-    QVBoxLayout * buttonLayout = new QVBoxLayout;
-    buttonLayout->setSpacing(sp);
-    buttonLayout->setContentsMargins(sp, sp, sp, sp);
-
-    QHBoxLayout * addSupLayout = new QHBoxLayout;
-    addSupLayout->setSpacing(sp);
-    addSupLayout->setContentsMargins(sp, sp, sp, sp);
-
-    QHBoxLayout * upDownLayout = new QHBoxLayout;
-    upDownLayout->setSpacing(sp);
-    upDownLayout->setContentsMargins(sp, sp, sp, sp);
-
-    // Add file button
-    QPushButton * addButton = new QPushButton;
-    addButton->setText("+");
-    addButton->setFixedWidth(buttonSize);
-    addButton->setToolTip("Add a string selector...");
-    connect( addButton, SIGNAL(clicked()), this, SLOT(AddString()) );
-    addSupLayout->addWidget(addButton);
-
-    // Suppress file button
-    QPushButton * supButton = new QPushButton;
-    supButton->setText("-");
-    supButton->setFixedWidth(buttonSize);
-    supButton->setToolTip("Suppress the selected string...");
-    connect( supButton, SIGNAL(clicked()), this, SLOT(SuppressString()) );
-    addSupLayout->addWidget(supButton);
-    buttonLayout->addLayout(addSupLayout);
-
-    hLayout->addLayout(buttonLayout);
-    }
-
-  QVBoxLayout * fileLayout = new QVBoxLayout();
-  fileLayout->setSpacing(0);
-
-  QGroupBox *mainGroup = new QGroupBox();
-  mainGroup->setLayout(fileLayout);
-  QScrollArea * s = new QScrollArea();
-  s->setWidget(mainGroup);
-  s->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-  s->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-  s->setWidgetResizable(true);
-
-  hLayout->addWidget(s);
-
-
-  this->setLayout(hLayout);
+/*****************************************************************************/
+QtWidgetStringListParameter
+::QtWidgetStringListParameter( StringListParameter * param,
+			       QtWidgetModel * m ) :
+  QtWidgetParameterList( param, m )
+{
+}
 
-  m_HLayout = hLayout;
-  m_Scroll = s;
 
+/*****************************************************************************/
+QtWidgetStringListParameter
+::~QtWidgetStringListParameter()
+{
 }
 
+#if 0
+
 void
 QtWidgetStringListParameter::UpdateStringList()
 {
@@ -206,5 +131,8 @@ QtWidgetStringListParameter::SuppressString()
   this->update();
 }
 
+#endif
+
 }
+
 }
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringParameter.cxx
index b48616d..54ffc7f 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringParameter.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetStringParameter.cxx
@@ -37,7 +37,9 @@ QtWidgetStringParameter::~QtWidgetStringParameter()
 
 void QtWidgetStringParameter::DoUpdateGUI()
 {
-  m_Input->setToolTip(m_StringParam->GetDescription());
+  m_Input->setToolTip(
+    QString::fromStdString( m_StringParam->GetDescription() )
+  );
 
   // Update the lineEdit only if there is a change and that's not empty or whitespaces
   QString text( m_StringParam->GetValue().c_str() );
@@ -55,7 +57,9 @@ void QtWidgetStringParameter::DoCreateWidget()
   m_HLayout->setContentsMargins(0, 0, 0, 0);
 
   m_Input = new QLineEdit;
-  m_Input->setToolTip(m_StringParam->GetDescription());
+  m_Input->setToolTip(
+    QString::fromStdString( m_StringParam->GetDescription() )
+  );
   m_HLayout->addWidget(m_Input);
 
   connect( m_Input, SIGNAL(textChanged(const QString&)), this, SLOT(SetValue(const QString&)) );
diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx
index ae64ff4..39c9d80 100644
--- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx
@@ -82,6 +82,8 @@ void QtWidgetView::CreateGui()
   QVBoxLayout  *finalLayout = new QVBoxLayout();
   finalLayout->addWidget(mainGroup);
 
+  connect( m_Model, SIGNAL(ExceptionRaised(QString)), this, SLOT(OnExceptionRaised(QString)) );
+
   // Make the final layout to the widget
   this->setLayout(finalLayout);
 }
@@ -95,11 +97,11 @@ void QtWidgetView::UpdateMessageAfterExecution(int status)
 {
   if (status >= 0)
     {
-    m_Message->setText("<center><font color=\"#00A000\">DONE</font></center>");
+    m_Message->setText("<center><font color=\"#00A000\">Done</font></center>");
     }
   else
     {
-    m_Message->setText("<center><font color=\"#FF0000\">FAILED !</font></center>");
+    m_Message->setText("<center><font color=\"#FF0000\">Failed</font></center>");
     }
 }
 
@@ -188,9 +190,14 @@ void QtWidgetView::CloseSlot()
 
 void QtWidgetView::UnhandledException(QString message)
 {
-  m_TabWidget->setCurrentIndex(1);
+  this->OnExceptionRaised(message);
   m_LogText->append(message);
 }
 
+void QtWidgetView::OnExceptionRaised(QString /*message*/)
+{
+  m_TabWidget->setCurrentIndex(1);
+}
+
 }
 }
diff --git a/Modules/Wrappers/SWIG/otb-module-init.cmake b/Modules/Wrappers/SWIG/otb-module-init.cmake
index 413ba56..8f02b52 100644
--- a/Modules/Wrappers/SWIG/otb-module-init.cmake
+++ b/Modules/Wrappers/SWIG/otb-module-init.cmake
@@ -19,9 +19,10 @@
 #
 
 option ( OTB_WRAP_PYTHON "Wrap Python" OFF )
+option ( OTB_WRAP_PYTHON3 "Wrap Python 3" OFF )
 option ( OTB_WRAP_JAVA   "Wrap Java"   OFF )
 
-if ( OTB_WRAP_PYTHON OR OTB_WRAP_JAVA )
+if ( OTB_WRAP_PYTHON OR OTB_WRAP_JAVA OR OTB_WRAP_PYTHON3)
   find_package ( SWIG REQUIRED )
   mark_as_advanced(SWIG_DIR)
   mark_as_advanced(SWIG_EXECUTABLE)
@@ -43,11 +44,67 @@ endmacro()
 
 if ( OTB_WRAP_PYTHON )
   check_PIC_flag ( Python )
-  find_package ( PythonLibs REQUIRED )
   find_package ( PythonInterp REQUIRED )
+  find_package ( PythonLibs REQUIRED )
   find_package ( Numpy )
 endif()
 
+macro(swap_cache_variable var1 var2)
+  set(_backup ${${var1}})
+  get_property(_var1_type CACHE ${var1} PROPERTY TYPE)
+  get_property(_var1_help CACHE ${var1} PROPERTY HELPSTRING)
+  get_property(_var2_type CACHE ${var2} PROPERTY TYPE)
+  get_property(_var2_help CACHE ${var2} PROPERTY HELPSTRING)
+  set(${var1} ${${var2}} CACHE ${_var1_type} "${_var1_help}" FORCE)
+  set(${var2} ${_backup} CACHE ${_var2_type} "${_var2_help}" FORCE)
+endmacro()
+
+macro(swap_variable var1 var2)
+  set(_backup ${${var1}})
+  set(${var1} ${${var2}})
+  set(${var2} ${_backup})
+endmacro()
+
+if ( OTB_WRAP_PYTHON3 )
+  set(PYTHON3_EXECUTABLE "PYTHON3_EXECUTABLE-NOTFOUND" CACHE FILEPATH "Path to python 3 interpreter")
+  set(PYTHON3_INCLUDE_DIR "PYTHON3_INCLUDE_DIR-NOTFOUND" CACHE PATH "Path to python 3 include directory")
+  set(PYTHON3_LIBRARY "PYTHON3_LIBRARY-NOTFOUND" CACHE FILEPATH "Path to python 3 library")
+  set(PYTHON3_LIBRARY_DEBUG "PYTHON3_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to python 3 library (debug)")
+  set(PYTHON3_LIBRARY_RELEASE "PYTHON3_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to python 3 library (release)")
+  set(NUMPY_PYTHON3_INCLUDE_DIR "NUMPY_PYTHON3_INCLUDE_DIR" CACHE PATH "Path to numpy module for Python 3")
+
+  # Swap cache variables between python and python3
+  swap_cache_variable(PYTHON_EXECUTABLE PYTHON3_EXECUTABLE)
+  swap_cache_variable(PYTHON_INCLUDE_DIR PYTHON3_INCLUDE_DIR)
+  swap_cache_variable(PYTHON_LIBRARY PYTHON3_LIBRARY)
+  swap_cache_variable(PYTHON_LIBRARY_DEBUG PYTHON3_LIBRARY_DEBUG)
+  swap_cache_variable(PYTHON_LIBRARY_RELEASE PYTHON3_LIBRARY_RELEASE)
+  swap_cache_variable(NUMPY_INCLUDE_DIR NUMPY_PYTHON3_INCLUDE_DIR)
+
+  swap_variable(PYTHON_LIBRARIES PYTHON3_LIBRARIES)
+  swap_variable(NUMPY_INCLUDE_DIRS NUMPY_PYTHON3_INCLUDE_DIRS)
+  swap_variable(NUMPY_FOUND NUMPY_PYTHON3_FOUND)
+  swap_variable(PYTHON_VERSION_STRING PYTHON3_VERSION_STRING)
+
+  check_PIC_flag ( Python )
+  find_package ( PythonInterp 3 REQUIRED )
+  find_package ( PythonLibs 3 REQUIRED )
+  find_package ( Numpy )
+
+  # Swap cache variables between python and python3
+  swap_cache_variable(PYTHON_EXECUTABLE PYTHON3_EXECUTABLE)
+  swap_cache_variable(PYTHON_INCLUDE_DIR PYTHON3_INCLUDE_DIR)
+  swap_cache_variable(PYTHON_LIBRARY PYTHON3_LIBRARY)
+  swap_cache_variable(PYTHON_LIBRARY_DEBUG PYTHON3_LIBRARY_DEBUG)
+  swap_cache_variable(PYTHON_LIBRARY_RELEASE PYTHON3_LIBRARY_RELEASE)
+  swap_cache_variable(NUMPY_INCLUDE_DIR NUMPY_PYTHON3_INCLUDE_DIR)
+
+  swap_variable(PYTHON_LIBRARIES PYTHON3_LIBRARIES)
+  swap_variable(NUMPY_INCLUDE_DIRS NUMPY_PYTHON3_INCLUDE_DIRS)
+  swap_variable(NUMPY_FOUND NUMPY_PYTHON3_FOUND)
+  swap_variable(PYTHON_VERSION_STRING PYTHON3_VERSION_STRING)
+endif()
+
 #
 # JAVA SWIG configuration
 #
diff --git a/Modules/Wrappers/SWIG/src/CMakeLists.txt b/Modules/Wrappers/SWIG/src/CMakeLists.txt
index 8c0b302..34a3d58 100644
--- a/Modules/Wrappers/SWIG/src/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/src/CMakeLists.txt
@@ -18,124 +18,28 @@
 # limitations under the License.
 #
 
-if ( OTB_WRAP_PYTHON OR OTB_WRAP_JAVA )
+if ( OTB_WRAP_PYTHON OR OTB_WRAP_JAVA OR OTB_WRAP_PYTHON3)
   include ( UseSWIGLocal )
-  set_source_files_properties ( otbApplication.i PROPERTIES CPLUSPLUS ON )
-
   list(APPEND SWIG_EXTRA_DEPS
        otbWrapperSWIGIncludes.h
        itkBase.includes
        ${CMAKE_CURRENT_SOURCE_DIR}/itkBase.i
        ${CMAKE_CURRENT_SOURCE_DIR}/itkMacro.i
        )
-
   include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} )
 endif()
 
-
-#
 # Python SWIG configuration
-#
 if ( OTB_WRAP_PYTHON )
-  include_directories ( ${PYTHON_INCLUDE_DIR} )
-
-  # Run swig
-  set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_GLOBAL_FLAGS})
-  if(NUMPY_FOUND)
-    include_directories(${NUMPY_INCLUDE_DIRS})
-    list(APPEND CMAKE_SWIG_FLAGS  "-DOTB_SWIGNUMPY=1")
-  endif()
-  set(CMAKE_SWIG_OUTDIR ${CMAKE_BINARY_DIR}/${OTB_INSTALL_PYTHON_DIR})
-  set(SWIG_MODULE_otbApplication_EXTRA_DEPS
-       ${CMAKE_CURRENT_SOURCE_DIR}/Python.i
-       ${CMAKE_CURRENT_SOURCE_DIR}/PyCommand.i
-       itkPyCommand.h
-       OTBApplicationEngine)
-  SWIG_add_module( otbApplication python otbApplication.i otbApplicationPYTHON_wrap.cxx itkPyCommand.cxx )
-  SWIG_link_libraries( otbApplication ${PYTHON_LIBRARIES} OTBApplicationEngine )
-  set_target_properties(_otbApplication PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SWIG_OUTDIR})
-  if(MSVC)
-    set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationPYTHON_wrap.cxx COMPILE_FLAGS "/wd4005" )
-  else()
-    set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationPYTHON_wrap.cxx COMPILE_FLAGS "-w" )
-  endif()
-
-  # byte-compile the resulting python file
-  add_custom_command(
-      TARGET _otbApplication
-      POST_BUILD
-      COMMAND ${CMAKE_COMMAND} -E echo "Byte-compiling otbApplication.py"
-      COMMAND ${PYTHON_EXECUTABLE}
-      ${CMAKE_SOURCE_DIR}/CMake/PythonCompile.py
-      ${CMAKE_SWIG_OUTDIR}/otbApplication.py
-      DEPENDS _otbApplication
-    )
-
-  otb_module_target_label( _otbApplication )
-
-  install( TARGETS _otbApplication
-           DESTINATION ${OTB_INSTALL_PYTHON_DIR}
-           COMPONENT RuntimeLibraries )
-
-  install( FILES ${CMAKE_SWIG_OUTDIR}/otbApplication.py
-                 ${CMAKE_SWIG_OUTDIR}/otbApplication.pyc
-           DESTINATION ${OTB_INSTALL_PYTHON_DIR}
-           COMPONENT RuntimeLibraries )
+  add_subdirectory(python)
+endif()
 
+# Python 3 SWIG configuration
+if ( OTB_WRAP_PYTHON3 )
+  add_subdirectory(python3)
 endif()
 
-#
 # JAVA SWIG configuration
-#
 if ( OTB_WRAP_JAVA )
-  include_directories ( ${JAVA_INCLUDE_PATH} ${JNI_INCLUDE_DIRS} )
-
-  # Make sure the nested directory structure exists
-  set(JAVA_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/org/otb/application)
-  set(JAVA_BINARY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build)
-  file(MAKE_DIRECTORY ${JAVA_SOURCE_DIRECTORY})
-  file(MAKE_DIRECTORY ${JAVA_BINARY_DIRECTORY})
-
-  # Nicely write the bridge code in org/itk/simple
-  set(CMAKE_SWIG_OUTDIR ${JAVA_SOURCE_DIRECTORY})
-  set(CMAKE_SWIG_FLAGS -package "org.otb.application" ${CMAKE_SWIG_GLOBAL_FLAGS})
-  set(SWIG_MODULE_otbApplicationJava_EXTRA_DEPS
-       ${CMAKE_CURRENT_SOURCE_DIR}/Java.i
-       OTBApplicationEngine)
-  SWIG_add_module ( otbApplicationJava java otbApplication.i otbApplicationJAVA_wrap.cxx)
-  SWIG_link_libraries(otbApplicationJava OTBApplicationEngine )
-  
-  if(MSVC)
-    set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationJAVA_wrap.cxx COMPILE_FLAGS "/wd4005" )
-  else()
-    set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/otbApplicationJAVA_wrap.cxx COMPILE_FLAGS "-w")
-  endif()
-
-  # Add target for org.otb.Application.jar
-  add_custom_target(org_otb_Application_jar ALL DEPENDS org.otb.application.jar)
-
-  otb_module_target_label( org_otb_Application_jar )
-
-  # Add custom command and target to compile the generated files and put them in a jar file
-  # Make sure the commands depend on the output library from SWIG
-  add_custom_command(
-    OUTPUT org.otb.application.jar
-    COMMENT "Creating jar file..."
-    COMMAND ${Java_JAVAC_EXECUTABLE} -d ${JAVA_BINARY_DIRECTORY} ${JAVA_SOURCE_DIRECTORY}/*.java
-    COMMAND ${Java_JAR_EXECUTABLE} cf ${CMAKE_CURRENT_BINARY_DIR}/org.otb.application.jar -C ${JAVA_BINARY_DIRECTORY} org
-    DEPENDS ${SWIG_MODULE_otbApplication_REAL_NAME} otbApplicationJava OTBApplicationEngine
-    )
-
-  # Get the location of the extension directory
-  string(REGEX REPLACE "include"  "jre/lib/ext" JAVA_EXTENSION_DIR ${JAVA_INCLUDE_PATH} )
-
-  # Add the install target
-  # -- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.otb.application.jar DESTINATION ${JAVA_EXTENSION_DIR})
-  # Prefer using OTB_INSTALL_JAVA_DIR which defaults to something that honors CMAKE_INSTALL_PREFIX
-  # Using the system-wide Java extension dir usually require admin privileges,
-  # and shall better be left to packagers.
-  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.otb.application.jar
-          DESTINATION ${OTB_INSTALL_JAVA_DIR}
-          COMPONENT RuntimeLibraries )
-
+  add_subdirectory(java)
 endif()
diff --git a/Modules/Wrappers/SWIG/src/java/CMakeLists.txt b/Modules/Wrappers/SWIG/src/java/CMakeLists.txt
new file mode 100644
index 0000000..a4df75c
--- /dev/null
+++ b/Modules/Wrappers/SWIG/src/java/CMakeLists.txt
@@ -0,0 +1,70 @@
+#
+# Copyright (C) 2005-2017 CS Systemes d'Information (CS SI)
+#
+# 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_directories ( ${JAVA_INCLUDE_PATH} ${JNI_INCLUDE_DIRS} )
+set_source_files_properties ( ../otbApplication.i PROPERTIES CPLUSPLUS ON )
+
+# Make sure the nested directory structure exists
+set(JAVA_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/org/otb/application)
+set(JAVA_BINARY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build)
+file(MAKE_DIRECTORY ${JAVA_SOURCE_DIRECTORY})
+file(MAKE_DIRECTORY ${JAVA_BINARY_DIRECTORY})
+
+# Nicely write the bridge code in org/itk/simple
+set(CMAKE_SWIG_OUTDIR ${JAVA_SOURCE_DIRECTORY})
+set(CMAKE_SWIG_FLAGS -package "org.otb.application" ${CMAKE_SWIG_GLOBAL_FLAGS})
+set(SWIG_MODULE_otbApplicationJava_EXTRA_DEPS
+     ${CMAKE_CURRENT_SOURCE_DIR}/../Java.i
+     OTBApplicationEngine)
+SWIG_add_module ( otbApplicationJava java ../otbApplication.i otbApplicationJAVA_wrap.cxx)
+SWIG_link_libraries(otbApplicationJava OTBApplicationEngine )
+
+if(MSVC)
+  set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationJAVA_wrap.cxx COMPILE_FLAGS "/wd4005" )
+else()
+  set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/otbApplicationJAVA_wrap.cxx COMPILE_FLAGS "-w")
+endif()
+
+# Add target for org.otb.Application.jar
+add_custom_target(org_otb_Application_jar ALL DEPENDS org.otb.application.jar)
+
+otb_module_target_label( org_otb_Application_jar )
+
+# Add custom command and target to compile the generated files and put them in a jar file
+# Make sure the commands depend on the output library from SWIG
+add_custom_command(
+  OUTPUT org.otb.application.jar
+  COMMENT "Creating jar file..."
+  COMMAND ${Java_JAVAC_EXECUTABLE} -d ${JAVA_BINARY_DIRECTORY} ${JAVA_SOURCE_DIRECTORY}/*.java
+  COMMAND ${Java_JAR_EXECUTABLE} cf ${CMAKE_CURRENT_BINARY_DIR}/org.otb.application.jar -C ${JAVA_BINARY_DIRECTORY} org
+  DEPENDS ${SWIG_MODULE_otbApplication_REAL_NAME} otbApplicationJava OTBApplicationEngine
+  )
+
+# Get the location of the extension directory
+string(REGEX REPLACE "include"  "jre/lib/ext" JAVA_EXTENSION_DIR ${JAVA_INCLUDE_PATH} )
+
+# Add the install target
+# -- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.otb.application.jar DESTINATION ${JAVA_EXTENSION_DIR})
+# Prefer using OTB_INSTALL_JAVA_DIR which defaults to something that honors CMAKE_INSTALL_PREFIX
+# Using the system-wide Java extension dir usually require admin privileges,
+# and shall better be left to packagers.
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.otb.application.jar
+        DESTINATION ${OTB_INSTALL_JAVA_DIR}
+        COMPONENT RuntimeLibraries )
diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i
index 72adde8..d945d52 100644
--- a/Modules/Wrappers/SWIG/src/otbApplication.i
+++ b/Modules/Wrappers/SWIG/src/otbApplication.i
@@ -128,7 +128,7 @@ namespace Wrapper
 
   typedef enum
   {
-    Role_Input,
+    Role_Input = 0,
     Role_Output
   } Role;
 
@@ -198,7 +198,7 @@ public:
   std::string GetParameterString(std::string parameter);
   std::vector<std::string> GetParameterStringList(std::string parameter);
   std::string GetParameterAsString(std::string paramKey);
-  
+
   InputImageParameter::ImageBaseType * GetParameterOutputImage(std::string parameter);
   void SetParameterInputImage(std::string parameter, InputImageParameter::ImageBaseType * inputImage);
   ComplexInputImageParameter::ImageBaseType * GetParameterComplexOutputImage(std::string parameter);
@@ -211,7 +211,7 @@ public:
   unsigned int GetNumberOfElementsInParameterInputImageList(std::string parameter);
 
 
-  
+
   itkProcessObject* GetProgressSource() const;
 
   std::string GetProgressDescription() const;
@@ -279,7 +279,7 @@ public:
         spacing.Fill( 1.0 );                                            \
         direction.SetIdentity();                                        \
         output->SetOrigin( origin );                                    \
-        output->SetSpacing( spacing );                                  \
+        output->SetSignedSpacing( spacing );                                  \
         output->SetDirection(direction);                                \
         output->SetLargestPossibleRegion(region);                       \
         output->SetRequestedRegion(output->GetLargestPossibleRegion()); \
@@ -562,38 +562,53 @@ class ApplicationProxy(object):
 			  print ("Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey))
 			return None
 
-		def __getattr__(self,attr):
-		  """
-		  __get_attribute__ is called whenever an instance request an attribute.
-		  eg: App.SetParameterString(), App.GetName() ..
-		  __getattr__ is only called if the attribute is not found by __get_attribute__ call
-		  So we keep hide the GetParameter** calls within this method so that it seems like
-		  an obivous call for users. App.IN , App.OUT , where 'in' and 'out' are
-		  parameters in the 'otb application' with instance App
-		  """
-		  if attr is not None:
-		    key_list = [k.upper() for k in self.GetParametersKeys(True)]
-		    if attr in key_list:
-		      return self.GetParameterValue(attr.lower())
-		    else:
-		      raise AttributeError("Parameter {} does not exist in the application.".format(attr.lower()))
-
-		def __setattr__(self, attr, value):
-		  """
-		  __setattr__ is called if the attribute requested is not found in the attribute list.
-		  So these attributes are supposed to be 'key' of parameters used. Here we
-		  keep hide the SetParameter** calls within this method so that it seems like
-		  an obivous call for users. App.IN='my-input-file-name' , App.OUT='my-output-file-name'w
-		  here 'in' and 'out' are    parameters in the 'otb application' with instance App
-		  Ofcourse, we don't blindly accept any attributes as python, we check them against
-		  list of existing parameters for application with 'self.GetParametersKeys(True)'
-		  """
-		  if attr is not None:
-		    key_list = [k.upper() for k in self.GetParametersKeys(True)]
-		    if attr in key_list:
-		      self.SetParameterValue(attr.lower(), value)
-		    else:
-		      raise AttributeError("Parameter {} does not exist in the application.".format(attr.lower()))
+		def __getattr__(self,name):
+			"""
+			__get_attribute__ is called whenever an instance request an attribute.
+			eg: App.SetParameterString(), App.GetName() ..
+			__getattr__ is only called if the attribute is not found by __get_attribute__ call
+			So we keep hide the GetParameter** calls within this method so that it seems like
+			an obivous call for users. App.IN , App.OUT , where 'in' and 'out' are
+			parameters in the 'otb application' with instance App
+			Since SWIG also uses this function, we have to copy their code before
+			using custom OTB behaviour
+			"""
+			if (name == "thisown"):
+				return self.this.own()
+			method = Application.__swig_getmethods__.get(name, None)
+			if method:
+				return method(self)
+			key_list = [k.upper() for k in self.GetParametersKeys(True)]
+			if name in key_list:
+				return self.GetParameterValue(name.lower())
+			raise AttributeError("'%s' object has no attribute '%s'" % (Application.__name__, name))
+
+		def __setattr__(self, name, value):
+			"""
+			__setattr__ is called if the attribute requested is not found in the attribute list.
+			So these attributes are supposed to be 'key' of parameters used. Here we
+			keep hide the SetParameter** calls within this method so that it seems like
+			an obivous call for users. App.IN='my-input-file-name' , App.OUT='my-output-file-name'w
+			here 'in' and 'out' are    parameters in the 'otb application' with instance App
+			Ofcourse, we don't blindly accept any attributes as python, we check them against
+			list of existing parameters for application with 'self.GetParametersKeys(True)'
+			Since SWIG also uses this function, we have to copy their code before
+			using custom OTB behaviour
+			"""
+			if (name == "thisown"):
+				return self.this.own(value)
+			if (name == "this"):
+				if type(value).__name__ == 'SwigPyObject':
+					self.__dict__[name] = value
+					return
+			method = Application.__swig_setmethods__.get(name, None)
+			if method:
+				return method(self, value)
+			key_list = [k.upper() for k in self.GetParametersKeys(True)]
+			if name in key_list:
+				self.SetParameterValue(name.lower(), value)
+			else:
+				raise AttributeError("You cannot add attributes to %s" % self)
 
     }
 }
@@ -732,13 +747,13 @@ class ApplicationProxy(object):
         print ("int8, int16, int32, uint8, uint16, uint32, float, double")
         numpy_vector_image = self.GetVectorImageAsFloatNumpyArray_(paramKey)
 
-      if len(numpy_vector_image.shape) > 2:
-        raise ValueError("len(numpy_vector_image.shape) > 2\n"
-                         "Output image from application is of 3 dimension (len(nparray.shape) > 2). \n"
-                         "GetImageFromNumpyArray returns an numpy array of dimension 2 that will result is loss of data.\n"
+      if numpy_vector_image.shape[2] > 1:
+        raise ValueError("numpy_vector_image.shape[2] > 1\n"
+                         "Output image from application has more than 1 band\n"
+                         "GetImageFromNumpyArray only returns the first band, which will result in a loss of data.\n"
                          "In this case you must use GetVectorImageFromNumpyArray which is capable of return a 3 dimension image.\n")
 
-      numpy_vector_image = numpy_vector_image[:,:,1]
+      numpy_vector_image = numpy_vector_image[:,:,0]
       return numpy_vector_image
 
 
diff --git a/Modules/Wrappers/SWIG/src/python/CMakeLists.txt b/Modules/Wrappers/SWIG/src/python/CMakeLists.txt
new file mode 100644
index 0000000..6177a66
--- /dev/null
+++ b/Modules/Wrappers/SWIG/src/python/CMakeLists.txt
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2005-2017 CS Systemes d'Information (CS SI)
+#
+# 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_directories ( ${PYTHON_INCLUDE_DIR} )
+include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} )
+set_source_files_properties ( ../otbApplication.i PROPERTIES CPLUSPLUS ON )
+# Run swig
+set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_GLOBAL_FLAGS})
+if(NUMPY_FOUND)
+  include_directories(${NUMPY_INCLUDE_DIRS})
+  list(APPEND CMAKE_SWIG_FLAGS  "-DOTB_SWIGNUMPY=1")
+endif()
+set(CMAKE_SWIG_OUTDIR ${CMAKE_BINARY_DIR}/${OTB_INSTALL_PYTHON_DIR})
+set(SWIG_MODULE_otbApplication_EXTRA_DEPS
+     ${CMAKE_CURRENT_SOURCE_DIR}/../Python.i
+     ${CMAKE_CURRENT_SOURCE_DIR}/../PyCommand.i
+     itkPyCommand.h
+     OTBApplicationEngine)
+SWIG_add_module( otbApplication python ../otbApplication.i otbApplicationPYTHON_wrap.cxx itkPyCommand.cxx )
+SWIG_link_libraries( otbApplication ${PYTHON_LIBRARIES} OTBApplicationEngine )
+set_target_properties(_otbApplication PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SWIG_OUTDIR})
+if(MSVC)
+  set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationPYTHON_wrap.cxx COMPILE_FLAGS "/wd4005" )
+else()
+  set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationPYTHON_wrap.cxx COMPILE_FLAGS "-w" )
+endif()
+
+# byte-compile the resulting python file
+add_custom_command(
+    TARGET _otbApplication
+    POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E echo "Byte-compiling otbApplication.py"
+    COMMAND ${PYTHON_EXECUTABLE}
+    ${CMAKE_SOURCE_DIR}/CMake/PythonCompile.py
+    ${CMAKE_SWIG_OUTDIR}/otbApplication.py
+    DEPENDS _otbApplication
+  )
+
+otb_module_target_label( _otbApplication )
+
+install( TARGETS _otbApplication
+         DESTINATION ${OTB_INSTALL_PYTHON_DIR}
+         COMPONENT RuntimeLibraries )
+
+install( FILES ${CMAKE_SWIG_OUTDIR}/otbApplication.py
+         DESTINATION ${OTB_INSTALL_PYTHON_DIR}
+         COMPONENT RuntimeLibraries )
+
+if(PYTHON_VERSION_STRING VERSION_LESS "3.2.0")
+  install( FILES ${CMAKE_SWIG_OUTDIR}/otbApplication.pyc
+         DESTINATION ${OTB_INSTALL_PYTHON_DIR}
+         COMPONENT RuntimeLibraries )
+else()
+  # TODO : pyc file is in a subfolder.
+endif()
diff --git a/Modules/Wrappers/SWIG/src/itkPyCommand.cxx b/Modules/Wrappers/SWIG/src/python/itkPyCommand.cxx
similarity index 100%
rename from Modules/Wrappers/SWIG/src/itkPyCommand.cxx
rename to Modules/Wrappers/SWIG/src/python/itkPyCommand.cxx
diff --git a/Modules/Wrappers/SWIG/src/itkPyCommand.h b/Modules/Wrappers/SWIG/src/python/itkPyCommand.h
similarity index 100%
rename from Modules/Wrappers/SWIG/src/itkPyCommand.h
rename to Modules/Wrappers/SWIG/src/python/itkPyCommand.h
diff --git a/Modules/Wrappers/SWIG/src/python3/CMakeLists.txt b/Modules/Wrappers/SWIG/src/python3/CMakeLists.txt
new file mode 100644
index 0000000..9795371
--- /dev/null
+++ b/Modules/Wrappers/SWIG/src/python3/CMakeLists.txt
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2005-2017 CS Systemes d'Information (CS SI)
+#
+# 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_directories ( ${PYTHON3_INCLUDE_DIR} )
+include_directories ( ${CMAKE_CURRENT_SOURCE_DIR}/../python )
+set_source_files_properties ( ../otbApplication.i PROPERTIES CPLUSPLUS ON )
+# Run swig
+set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_GLOBAL_FLAGS})
+if(NUMPY_PYTHON3_FOUND)
+  include_directories(${NUMPY_PYTHON3_INCLUDE_DIRS})
+  list(APPEND CMAKE_SWIG_FLAGS  "-DOTB_SWIGNUMPY=1")
+endif()
+set(CMAKE_SWIG_OUTDIR ${CMAKE_BINARY_DIR}/${OTB_INSTALL_PYTHON3_DIR})
+set(SWIG_MODULE_otbApplication_EXTRA_DEPS
+     ${CMAKE_CURRENT_SOURCE_DIR}/../Python.i
+     ${CMAKE_CURRENT_SOURCE_DIR}/../PyCommand.i
+     itkPyCommand.h
+     OTBApplicationEngine)
+SWIG_add_module( otbApplicationPy3 python ../otbApplication.i otbApplicationPYTHON_wrap.cxx ../python/itkPyCommand.cxx )
+SWIG_link_libraries( otbApplicationPy3 ${PYTHON3_LIBRARIES} OTBApplicationEngine )
+set_target_properties(_otbApplicationPy3 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SWIG_OUTDIR})
+set_target_properties(_otbApplicationPy3 PROPERTIES LIBRARY_OUTPUT_NAME _otbApplication)
+if(MSVC)
+  set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationPYTHON_wrap.cxx COMPILE_FLAGS "/wd4005" )
+else()
+  set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/otbApplicationPYTHON_wrap.cxx COMPILE_FLAGS "-w" )
+endif()
+
+# byte-compile the resulting python file
+add_custom_command(
+    TARGET _otbApplicationPy3
+    POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E echo "Byte-compiling otbApplication.py"
+    COMMAND ${PYTHON3_EXECUTABLE}
+    ${CMAKE_SOURCE_DIR}/CMake/PythonCompile.py
+    ${CMAKE_SWIG_OUTDIR}/otbApplication.py
+    DEPENDS _otbApplicationPy3
+  )
+
+otb_module_target_label( _otbApplicationPy3 )
+
+install( TARGETS _otbApplicationPy3
+         DESTINATION ${OTB_INSTALL_PYTHON3_DIR}
+         COMPONENT RuntimeLibraries )
+
+install( FILES ${CMAKE_SWIG_OUTDIR}/otbApplication.py
+         DESTINATION ${OTB_INSTALL_PYTHON3_DIR}
+         COMPONENT RuntimeLibraries )
+
+if(PYTHON3_VERSION_STRING VERSION_LESS "3.2.0")
+  install( FILES ${CMAKE_SWIG_OUTDIR}/otbApplication.pyc
+         DESTINATION ${OTB_INSTALL_PYTHON3_DIR}
+         COMPONENT RuntimeLibraries )
+else()
+  # TODO : pyc file is in a subfolder.
+endif()
diff --git a/Modules/Wrappers/SWIG/test/java/CMakeLists.txt b/Modules/Wrappers/SWIG/test/java/CMakeLists.txt
index 1183e5f..597fde1 100644
--- a/Modules/Wrappers/SWIG/test/java/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/java/CMakeLists.txt
@@ -33,7 +33,7 @@ if (WIN32)
     --add-before-env PATH ${OTB_BINARY_DIR}/bin)
 endif()
 
-set( CMAKE_JAVA_INCLUDE_PATH ${OTBSWIGWrapper_BINARY_DIR}/src/org.otb.application.jar )
+set( CMAKE_JAVA_INCLUDE_PATH ${OTBSWIGWrapper_BINARY_DIR}/src/java/org.otb.application.jar )
 set( JAVA_COMMAND "${Java_JAVA_EXECUTABLE}"
                   "-Djava.library.path=${OTB_BINARY_DIR}/Code/Wrappers/SWIG${PATH_SEPARATOR}$<TARGET_FILE_DIR:otbApplicationJava>" )
 
diff --git a/Modules/Wrappers/SWIG/test/python/Bug1498.py b/Modules/Wrappers/SWIG/test/python/Bug1498.py
new file mode 100644
index 0000000..ab0fb77
--- /dev/null
+++ b/Modules/Wrappers/SWIG/test/python/Bug1498.py
@@ -0,0 +1,38 @@
+import otbApplication as otb
+
+# TO RUN WITH PYTHON3
+# try:
+#    unicode = unicode
+# except NameError:
+#    # 'unicode' is undefined, must be Python 3
+#    str = str
+#    unicode = str
+#    bytes = bytes
+#    basestring = (str,bytes)
+# else:
+#    # 'unicode' exists, must be Python 2
+#    str = str
+#    unicode = unicode
+#    bytes = str
+#    basestring = basestring
+  
+
+# This test checks that UpdateOutputInformation() has been called on output image pointers when connecting pipeline in-memory
+# This code snippet has been used to reproduce bug #1498
+
+if __name__ == '__main__':
+    inimage = sys.argv[2]
+    outimage = sys.argv[3]
+
+    ext1 = otb.Registry.CreateApplication("ExtractROI")
+    ext2 = otb.Registry.CreateApplication("ExtractROI")
+
+    ext1.SetParameterString('in',inimage)
+    ext1.Execute()
+    ext1.UpdateParameters()
+    
+    ext2.SetParameterInputImage('in',ext2.GetParameterOutputImage('out'))
+    ext2.UpdateParameters()
+    ext2.SetParameterStringList('cl',['Channel1'])
+    ext2.SetParameterString("out",outimage)
+    ext2.ExecuteAndWriteOutput()
diff --git a/Modules/Wrappers/SWIG/test/python/Bug823.py b/Modules/Wrappers/SWIG/test/python/Bug823.py
index 96c9ed5..35604ec 100644
--- a/Modules/Wrappers/SWIG/test/python/Bug823.py
+++ b/Modules/Wrappers/SWIG/test/python/Bug823.py
@@ -24,7 +24,7 @@ def test(otb, argv):
 	app = otb.Registry.CreateApplication('Rasterization')
 	try:
 		app.GetParameterInt('szx')
-	except RuntimeError, e:
+	except RuntimeError as e:
 		print( "Exception message : " + e.args[0] )
 		if e.args[0].startswith("boost::bad_any_cast"):
 			exit(1)
diff --git a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
index 2342234..d1e4a50 100644
--- a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
@@ -135,3 +135,11 @@ add_test( NAME pyTvConnectApplications
   PythonConnectApplications
   ${OTB_DATA_ROOT}/Input/poupees.tif
   ${TEMP}/pyTvConnectApplicationsOutput.tif)
+
+add_test( NAME pyTvBug1498
+  COMMAND ${TEST_DRIVER} Execute
+  ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/PythonTestDriver.py
+  Bug823
+  ${OTB_DATA_ROOT}/Input/poupees.tif
+  ${TEMP}/Bu1498-output.tif)  
+
diff --git a/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py b/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py
index 0e14f65..34e48db 100644
--- a/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py
+++ b/Modules/Wrappers/SWIG/test/python/PythonConnectApplications.py
@@ -42,7 +42,7 @@ def test(otb, argv):
 
 	app4.AddImageToParameterInputImageList("il",app2.GetParameterOutputImage("out"));
 	app4.AddImageToParameterInputImageList("il",app3.GetParameterOutputImage("out"));
-        app4.AddParameterStringList("il",argv[1])
+	app4.AddParameterStringList("il",argv[1])
 
 	app4.OUT = argv[2]
 	app4.ExecuteAndWriteOutput()
diff --git a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
index d8aab34..4cb17b6 100644
--- a/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
+++ b/Modules/Wrappers/SWIG/test/python/PythonNewStyleParametersTest.py
@@ -22,7 +22,7 @@
 #  Example on the use of otb "pythonization"
 #
 def cm_assert(a,b):
-	print "debug print before assert check: '%s'== '%s'" %(a, b)
+	print("debug print before assert check: '%s'== '%s'" %(a, b))
 	assert a == b
 
 def test(otb, argv):
diff --git a/Packaging/CMakeLists.txt b/Packaging/CMakeLists.txt
index e2ef02d..83d8487 100644
--- a/Packaging/CMakeLists.txt
+++ b/Packaging/CMakeLists.txt
@@ -140,6 +140,7 @@ include(cleanup_package)
 include(install_include_dirs)
 include(install_importlibs)
 include(install_python_bindings)
+include(install_java_bindings)
 include(install_share_dirs)
 include(install_cmake_files)
 include(install_qtdev_files)
@@ -176,11 +177,21 @@ if(EXISTS "${SUPERBUILD_INSTALL_DIR}/bin/monteverdi${EXE_EXT}")
   set(HAVE_MVD TRUE)
 endif()
 
-set(HAVE_PYTHON FALSE CACHE INTERNAL "HAVE_PYTHON")
+set(HAVE_PYTHON FALSE CACHE INTERNAL "Python wrappings")
 if(EXISTS "${SUPERBUILD_INSTALL_DIR}/lib/otb/python/_otbApplication${PYMODULE_EXT}")
   set(HAVE_PYTHON TRUE)
 endif()
 
+set(HAVE_PYTHON3 FALSE CACHE INTERNAL "Python3 wrappings")
+if(EXISTS "${SUPERBUILD_INSTALL_DIR}/lib/otb/python3/_otbApplication${PYMODULE_EXT}")
+  set(HAVE_PYTHON3 TRUE)
+endif()
+
+set(HAVE_JAVA FALSE CACHE INTERNAL "Java wrappings")
+if(EXISTS "${SUPERBUILD_INSTALL_DIR}/lib/otb/java/org.otb.application.jar")
+  set(HAVE_JAVA TRUE)
+endif()
+
   #only for *nix
 if(UNIX)
   file(WRITE ${CMAKE_BINARY_DIR}/make_symlinks   "#!/bin/sh\n")
@@ -204,6 +215,8 @@ install_importlibs()
 
 install_python_bindings()
 
+install_java_bindings()
+
 install_share_dirs()
 
 install_cmake_files()
diff --git a/Packaging/Files/mapla.bat b/Packaging/Files/mapla.bat
index 1823697..9b1a3a1 100644
--- a/Packaging/Files/mapla.bat
+++ b/Packaging/Files/mapla.bat
@@ -23,16 +23,13 @@
 @echo off
 setlocal
 
-:: Get the directory of the current script
-set CURRENT_SCRIPT_DIR=%~dp0
-
 :: Setup environment
-call "%CURRENT_SCRIPT_DIR%otbenv.bat"
+call "%~dp0%otbenv.bat"
 
 :: Set current dir to HOME dir because Monteverdi generates temporary files and need write access
 cd %HOMEDRIVE%%HOMEPATH%
 
 :: Start Monteverdi
-start "Monteverdi Application Launcher" /B "%CURRENT_SCRIPT_DIR%bin\mapla.exe" %*
+start "Monteverdi Application Launcher" /MIN "CMD.EXE" /C mapla.exe %*
 
 endlocal
diff --git a/Packaging/Files/monteverdi.bat b/Packaging/Files/monteverdi.bat
index 4ffe603..382c30b 100644
--- a/Packaging/Files/monteverdi.bat
+++ b/Packaging/Files/monteverdi.bat
@@ -23,16 +23,13 @@
 @echo off
 setlocal
 
-:: Get the directory of the current script
-set CURRENT_SCRIPT_DIR=%~dp0
-
 :: Setup environment
-call "%CURRENT_SCRIPT_DIR%otbenv.bat"
+call "%~dp0%otbenv.bat"
 
 :: Set current dir to HOME dir because Monteverdi generates temporary files and need write access
 cd %HOMEDRIVE%%HOMEPATH%
 
 :: Start Monteverdi
-start "Monteverdi Viewer" /B "%CURRENT_SCRIPT_DIR%bin\monteverdi.exe" %*
+start "Monteverdi Viewer" /MIN "CMD.EXE" /C monteverdi.exe %*
 
 endlocal
diff --git a/Packaging/Files/otbenv.profile b/Packaging/Files/otbenv.profile
index 191121e..47f3a7e 100644
--- a/Packaging/Files/otbenv.profile
+++ b/Packaging/Files/otbenv.profile
@@ -23,24 +23,9 @@
 # So if you run again from a terminal. you need to run the script again
 # see how this is sourced in monteverdi.sh and mapla.sh
 
-# unset any existing LD_LIBRARY_PATH
-unset LD_LIBRARY_PATH
-
 CMAKE_PREFIX_PATH=OUT_DIR
 export CMAKE_PREFIX_PATH
 
-
-# if OTB_USE_LOCAL_GTK is set to one,
-# we must include ./lib/gtk because gtklibs are installed there. 
-# OTB_USE_LOCAL_GTK is not set by default (use GTK system)
-#This code only affect linux system. for osx OUT_DIR/lib/gtk does not exists
-if [ "$OTB_USE_LOCAL_GTK" = "1" ]; then
-    if [ -d "OUT_DIR/lib/gtk" ]; then
-	LD_LIBRARY_PATH=OUT_DIR/lib/gtk
-	export LD_LIBRARY_PATH
-    fi
-fi
-
 # check and set OTB_APPLICATION_PATH
 if [ -z "$OTB_APPLICATION_PATH" ] || [ "$OTB_APPLICATION_PATH" = "" ]; then
     OTB_APPLICATION_PATH=OUT_DIR/lib/otb/applications
diff --git a/Packaging/Files/selftester.sh b/Packaging/Files/selftester.sh
index 3d3a83c..8137cfa 100755
--- a/Packaging/Files/selftester.sh
+++ b/Packaging/Files/selftester.sh
@@ -122,25 +122,32 @@ for app in $OTB_APPS; do
     echo "" >tmp.log
     "bin/otbgui_$app" >tmp.log 2>&1 &
     GUI_PID=$!
-    sleep 5s
-    # Check process tree
-    CHILD_PROC=$(ps_children $GUI_PID | grep "bin/otbgui $app")
-    if [ -n "$CHILD_PROC" ]; then
-      CHILD_PID=$(echo "$CHILD_PROC" | cut -d ' ' -f 1)
-      NEXT_CHILD_PROC=$(ps_children "$CHILD_PID" | grep 'otbApplicationLauncherQt')
-      if [ -n "$NEXT_CHILD_PROC" ]; then
-        NEXT_CHILD_PID=$(echo "$NEXT_CHILD_PROC" | cut -d ' ' -f 1)
-        kill -9 "$NEXT_CHILD_PID"
-        wait "$NEXT_CHILD_PID" 2>/dev/null
-      else
-        echo "ERROR: otbApplicationLauncherQt $app failed to launch"
-        tee -a selftest_report.log < tmp.log
-	exit_if
+    CHILD_PID=""
+    NEXT_CHILD_PID=""
+    nb_try=0
+    while [ -z "$NEXT_CHILD_PID" -a $nb_try -lt 10 ]; do
+      sleep 1s
+      CHILD_PROC=$(ps_children $GUI_PID | grep "bin/otbgui $app")
+      if [ -n "$CHILD_PROC" ]; then
+        CHILD_PID=$(echo "$CHILD_PROC" | cut -d ' ' -f 1)
+        NEXT_CHILD_PROC=$(ps_children "$CHILD_PID" | grep 'otbApplicationLauncherQt')
+        if [ -n "$NEXT_CHILD_PROC" ]; then
+          NEXT_CHILD_PID=$(echo "$NEXT_CHILD_PROC" | cut -d ' ' -f 1)
+        fi
       fi
+      nb_try=$(( nb_try + 1 ))
+    done
+    if [ -n "$NEXT_CHILD_PID" ]; then
+      kill -9 "$NEXT_CHILD_PID"
+      wait "$NEXT_CHILD_PID" 2>/dev/null
+    elif [ -n "$CHILD_PID" ]; then
+      echo "ERROR: otbApplicationLauncherQt $app failed to launch"
+      tee -a selftest_report.log < tmp.log
+      exit_if
     else
-	echo "ERROR: bin/otbgui_$app failed to launch"
-	tee -a selftest_report.log < tmp.log
-	exit_if
+      echo "ERROR: bin/otbgui_$app failed to launch"
+      tee -a selftest_report.log < tmp.log
+      exit_if
     fi
   fi
   app_index=$(( app_index + 1 ))
diff --git a/Packaging/Files/uninstall_otb.bat b/Packaging/Files/uninstall_otb.bat
index b437444..3389fd1 100644
--- a/Packaging/Files/uninstall_otb.bat
+++ b/Packaging/Files/uninstall_otb.bat
@@ -1,39 +1,53 @@
-:: 
-:: 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.
-
-:: script to uninstall OTB
-
-setlocal
-set CUR_DIR=%~dp0
-cd %CUR_DIR%..
-set MY_INSTALL_DIR=%cd%
-del /S /Q %MY_INSTALL_DIR%\include\OTB* || exit 1
-del /S /Q %MY_INSTALL_DIR%\lib\cmake\OTB* || exit 1
-del /S /Q %MY_INSTALL_DIR%\lib\otb* || exit 1
-del /S /Q %MY_INSTALL_DIR%\lib\python\_otbApplication.* || exit 1
-del /S /Q %MY_INSTALL_DIR%\bin\otb* || exit 1
-del /S /Q %MY_INSTALL_DIR%\bin\monteverdi.exe || exit 1
-del /S /Q %MY_INSTALL_DIR%\bin\mapla.exe || exit 1
-del /S /Q %MY_INSTALL_DIR%\mapla.bat || exit 1
-del /S /Q %MY_INSTALL_DIR%\monteverdi.bat || exit 1
-del /S /Q %MY_INSTALL_DIR%\share\OTB* || exit 1
-del /S /Q "%MY_INSTALL_DIR%\OTB Project.zip" || exit 1
-endlocal
-
-
+ at echo off
+:: 
+:: 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.
+
+:: script to uninstall OTB
+
+setlocal
+cd %~dp0%..
+
+echo - Clean include\OTB*
+for /f %%i in ('dir /b include\OTB*') do rd /S /Q include\%%i
+
+echo - Clean lib\cmake\OTB*
+for /f %%i in ('dir /b lib\cmake\OTB*') do rd /S /Q lib\cmake\%%i
+
+echo - Clean share\OTB*
+for /f %%i in ('dir /b share\OTB*') do rd /S /Q share\%%i
+
+echo - Clean lib\otb
+rd /S /Q lib\otb
+
+del /S /Q lib\otb*
+del /S /Q lib\python\*otbApplication.* || exit 1
+del /S /Q lib\python3\*otbApplication.* || exit 1
+del /S /Q lib\java\org.otb.application.jar || exit 1
+del /S /Q bin\otb* || exit 1
+del /S /Q bin\monteverdi.exe || exit 1
+del /S /Q bin\mapla.exe || exit 1
+del /S /Q mapla.bat || exit 1
+del /S /Q monteverdi.bat || exit 1
+del /S /Q otbenv.* || exit 1
+del /S /Q start_devenv.bat || exit 1
+del /S /Q "OTB Project.zip" || exit 1
+
+echo OTB is now uninstalled from %cd%
+
+endlocal
diff --git a/Packaging/Files/uninstall_otb.sh b/Packaging/Files/uninstall_otb.sh
index 4f596f3..1b5030c 100755
--- a/Packaging/Files/uninstall_otb.sh
+++ b/Packaging/Files/uninstall_otb.sh
@@ -21,9 +21,11 @@
 set -e
 rm -fr OUT_DIR/include/OTB-*
 rm -f OUT_DIR/lib/{libotb*,libOTB*}
-rm -fr OUT_DIR/lib/{otb,python/_otbApplication*}
+rm -fr OUT_DIR/lib/{otb,python/*otbApplication*,python3/*otbApplication*,java/org.otb.application.jar}
+rm -fr OUT_DIR/lib/cmake/OTB-*
 rm -fr OUT_DIR/share/OTB*
 rm -fv OUT_DIR/bin/{otb*,monteverdi,mapla}
 rm -fv OUT_DIR/{mapla.sh,monteverdi.sh}
+rm -fv OUT_DIR/otbenv.*
 
 echo "OTB is now uninstalled from OUT_DIR"
diff --git a/Packaging/install_python_bindings.cmake b/Packaging/install_java_bindings.cmake
similarity index 79%
copy from Packaging/install_python_bindings.cmake
copy to Packaging/install_java_bindings.cmake
index 451894b..aa3a632 100644
--- a/Packaging/install_python_bindings.cmake
+++ b/Packaging/install_java_bindings.cmake
@@ -17,11 +17,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-function(install_python_bindings)
-  if(HAVE_PYTHON)
-    install(DIRECTORY ${SUPERBUILD_INSTALL_DIR}/lib/otb/python
-      DESTINATION ${PKG_STAGE_DIR}/lib
-      PATTERN "*.pyc" EXCLUDE
+
+function(install_java_bindings)
+  if(HAVE_JAVA)
+    install(FILES ${SUPERBUILD_INSTALL_DIR}/lib/otb/java/org.otb.application.jar
+      DESTINATION ${PKG_STAGE_DIR}/lib/java
       )
   endif()
 endfunction()
diff --git a/Packaging/install_python_bindings.cmake b/Packaging/install_python_bindings.cmake
index 451894b..9c62934 100644
--- a/Packaging/install_python_bindings.cmake
+++ b/Packaging/install_python_bindings.cmake
@@ -22,6 +22,14 @@ function(install_python_bindings)
     install(DIRECTORY ${SUPERBUILD_INSTALL_DIR}/lib/otb/python
       DESTINATION ${PKG_STAGE_DIR}/lib
       PATTERN "*.pyc" EXCLUDE
+      PATTERN "__pycache__" EXCLUDE
+      )
+  endif()
+  if(HAVE_PYTHON3)
+    install(DIRECTORY ${SUPERBUILD_INSTALL_DIR}/lib/otb/python3
+      DESTINATION ${PKG_STAGE_DIR}/lib
+      PATTERN "*.pyc" EXCLUDE
+      PATTERN "__pycache__" EXCLUDE
       )
   endif()
 endfunction()
diff --git a/Packaging/install_rule.cmake b/Packaging/install_rule.cmake
index b4d40f0..adfdf03 100644
--- a/Packaging/install_rule.cmake
+++ b/Packaging/install_rule.cmake
@@ -80,6 +80,8 @@ function(install_rule src_file)
       continue()
     elseif("${sfile_ABS_LOWER}" MATCHES "\\.settings$")
       continue()
+    elseif("${sfile_ABS_LOWER}" MATCHES "-config$")
+      continue()
     else()
       if(UNIX)
         #the last else() loop where we run a 'file' command to find file type and directory
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 1f7046b..2421280 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -1,3 +1,44 @@
+OTB-v.6.4.0 - Changes since version 6.2.0 (January 17th, 2018)
+----------------------------------------------------------
+
+* Request for Changes (http://wiki.orfeo-toolbox.org/index.php/Requests_for_Changes):
+  * Request for changes-104: Refactor OTB-applications input/output string/filename lists (adopted, merged)
+  * Request for changes-110: Histogram Equalization (adopted, merged)
+  * Request for changes-117: Merge Convert and Rescale applications (adopted, merged)
+  * Request for changes-118: Enable use of ossimSarSensorModel through geom file (adopted, merged)
+  * Request for changes-119: Install ossimPlugins headers related to ossimSarSensorModel (adopted, merged)
+  * Request for changes-120: Replacing itk::TimeProbe (adopted, merged)
+  * Request for changes-121: Add Laurențiu Nicola as a new committer (adopted, merged)
+  * Request for changes-122: Positive spacing enforcement (adopted, merged)
+  * Request for changes-123: Improve OTB Applications documentation (part 2) (adopted, merged)
+  * Request for changes-124: Add GSL to Superbuild (adopted,merged)
+  * Request for changes-126: Support python 2.7 and 3 wrappings (adopted, merged)
+
+* Bugfixes:
+  * Orfeo Toolbox (OTB)
+    * 0001501: Does Java wrapping works on Windows?
+    * 0001495: Crash when setting Orthorectification input field
+    * 0001489: BandMath and BandMathX are missing important documentation on expression syntax
+    * 0001479: Monteverdi try to create overviews with /vsicurl file
+    * 0001502: OTB configuration step does not properly check for c++14 availability
+    * 0001497: Some optional parameters are ON by default in otbgui
+    * 0001483: Monteverdi shows a pop up terminal on windows
+    * 0001496: Monteverdi 'build overviews' pop-up trigger condition is unclear or incorrect
+    * 0001494: Segmentation app shows 'Select parameters' instead of 'Running'
+    * 0001504: OTB does not compile with ITK last stable release 4.13
+    * 0001492: Monteverdi 6.2 is missing some French translations
+    * 0001503: Fix new coverity issues in release 6.4
+    * 0001499: OSSIMAdapters fails to build with OSSIM 2.2.0 (error: 'class ossimRpcSolver' has no member named 'createRpcProjection')
+    * 0001498: ExtractROI Channel list empty when application is chained in memory
+    * 0001476: Python wrapping not working with Python >= 3.4
+
+  * Documentation
+    * 0001500: Application example in OTB software guide is confusing
+
+  * OTB-applications
+    * 0001481: KMeansClassification application should be compiled only if OTB_USE_SHARK=ON
+
+
 OTB-v.6.2.0 - Changes since version 6.0.0 (October 26th, 2017)
 ----------------------------------------------------------
 
@@ -46,7 +87,7 @@ OTB-v.6.2.0 - Changes since version 6.0.0 (October 26th, 2017)
     * 0001460: Unable to compile OTB  6.2.0 RC1 with superbuild (CURL issue)
 
   * Orfeo Toolbox (OTB)
-    * 0001453: Applications crash with inxml paramter (GUI mode)
+    * 0001453: Applications crash with inxml parameter (GUI mode)
     * 0001405: Crash on optical calibration, TOC mode, GUI only (command line works), only on Mac
     * 0001422: Optical Calibration application crash on MacOSX
     * 0001401: ktrace reports too many file open for any otbapplication
diff --git a/Utilities/Data/Icons/forbidden-24x24.png b/Utilities/Data/Icons/forbidden-24x24.png
new file mode 100644
index 0000000..c910740
Binary files /dev/null and b/Utilities/Data/Icons/forbidden-24x24.png differ
diff --git a/Utilities/Maintenance/SuperbuildDownloadList.sh b/Utilities/Maintenance/SuperbuildDownloadList.sh
index da5c4cb..48f693c 100755
--- a/Utilities/Maintenance/SuperbuildDownloadList.sh
+++ b/Utilities/Maintenance/SuperbuildDownloadList.sh
@@ -46,30 +46,33 @@ else
     VERSION="develop"
 fi
 CMAKE_FILES=$(find "${SB_CMAKE_DIR}" -maxdepth 1 -type f -name "External_*")
-DOWNLOAD_LIST=$(grep -h -E '^[^#]*\"(ftp|http|https)://.*(\.tar\.gz|\.tar\.bz2|\.tgz|\.tar\.xz|\.zip|export=download).*\"' ${CMAKE_FILES} |
-		    grep -o -E '(ftp|http|https)://[^\"]*' | sort | uniq)
 
 DOWNLOAD_NAMES=
 
-#echo "DOWNLOAD_LIST=$DOWNLOAD_LIST"
-
 mkdir -p "${DOWNLOAD_DIR}"
 cd "${DOWNLOAD_DIR}" || echo "cannot cd to DOWNLOAD_DIR"
 echo "Downloading files to ${DOWNLOAD_DIR}/"
-for url in ${DOWNLOAD_LIST}; do
-  file_name=$(echo "${url}" | grep -o -E '[^\/]+$')
-  $WGET -N "${url}"
-  ret="$?"
-  if [ $ret -gt 0 ] && [ $ret -ne 8 ]; then
-     echo "Download failed for URL: '${url}'. wget finished with exit status '$ret'."
-     exit 1;
-  fi
-
-  if [ "$file_name" != "" ]; then
-     DOWNLOAD_NAMES="${DOWNLOAD_NAMES} ${file_name}"
-  else
-     echo "invalid filename for url=${url}" && exit 1;
-  fi
+for cmake in ${CMAKE_FILES}; do
+  download_links=$(grep -h -E '^[^#]*\"(ftp|http|https)://.*(\.tar\.gz|\.tar\.bz2|\.tgz|\.tar\.xz|\.zip|export=download).*\"' "${cmake}" |
+		    grep -o -E '(ftp|http|https)://[^\"]*' | sort | uniq)
+  for url in ${download_links}; do
+    file_name=$(echo "${url}" | grep -o -E '[^\/]+$')
+    if [ -z "$file_name" ]; then
+      echo "invalid filename for url=${url}" && exit 1;
+    fi
+    download_name=$(grep -E -A 3 -B 3 "(ftp|http|https).+$file_name" "${cmake}" | grep -E -o 'DOWNLOAD_NAME .+' | cut -d ' ' -f 2-)
+    $WGET -N "${url}"
+    ret="$?"
+    if [ $ret -gt 0 ] && [ $ret -ne 8 ]; then
+       echo "Download failed for URL: '${url}'. wget finished with exit status '$ret'."
+       exit 1;
+    fi
+    if [ -n "$download_name" ]; then
+      mv "${file_name}" "${download_name}"
+      file_name=$download_name
+    fi
+    DOWNLOAD_NAMES="${DOWNLOAD_NAMES} ${file_name}"
+  done
 done
 
 ARCHIVE_NAME="SuperBuild-archives-$VERSION"
diff --git a/i18n/fr_FR.ts b/i18n/fr_FR.ts
index e9ea1fe..67a6aa2 100644
--- a/i18n/fr_FR.ts
+++ b/i18n/fr_FR.ts
@@ -279,7 +279,7 @@ Veuillez, s'il vous plait, supprimer votre répertoire de cache Monteverdi.
     </message>
     <message>
         <source><html><head/><body><p>Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)</p><p>Monteverdi is part of Orfeo Toolbox</p><p><a href="https://www.orfeo-toolbox.org/"><span style=" text-decoration: underline; color:#0000ff;">https://www.orfeo-toolbox.org/</span></a></p><p>Licensed under the Apache License, Version 2.0 (the &quot;License&quot;); yo [...]
-        <translation type="unfinished"></translation>
+        <translation></translation>
     </message>
 </context>
 <context>
@@ -457,6 +457,10 @@ Veuillez, s'il vous plait, supprimer votre répertoire de cache Monteverdi.
         <source>Title</source>
         <translation>Titre</translation>
     </message>
+    <message>
+        <source>Name</source>
+        <translation>Nom</translation>
+    </message>
 </context>
 <context>
     <name>mvd::ApplicationsToolBoxController</name>
@@ -4597,7 +4601,7 @@ Merci d'en sélectionner un autre.</translation>
     </message>
     <message>
         <source>GDAL Overviews</source>
-        <translation>Overviews GDAL</translation>
+        <translation>Aperçus GDAL</translation>
     </message>
     <message>
         <source>Generate</source>
@@ -4612,8 +4616,8 @@ Merci d'en sélectionner un autre.</translation>
         <translation>pixel(s)</translation>
     </message>
     <message>
-        <source>When the image width or height is lower than this minimum, overview generation is not proposed</source>
-        <translation>Lorsque la hauteur ou la largeur d'une image est inférieure à ce minimum, la génération des aperçus n'est pas proposée</translation>
+        <source>When the image width or height is lower than twice this minimum, overview generation is not proposed</source>
+        <translation>Lorsque la hauteur ou la largeur d'une image est inférieure à deux fois ce minimum, la génération des aperçus n'est pas proposée</translation>
     </message>
 </context>
 <context>
@@ -5106,5 +5110,37 @@ Le(s) résultat(s) vont être importés en tant que jeu de données.</translatio
         <source>Following files are being viewed in </source>
         <translation>Les fichiers suivants sont en cours de visualisation dans </translation>
     </message>
+    <message>
+        <source>Running</source>
+        <translation>En cours</translation>
+    </message>
+    <message>
+        <source>Done</source>
+        <translation>Terminé</translation>
+    </message>
+    <message>
+        <source>Failed</source>
+        <translation>Echec</translation>
+    </message>
+    <message>
+        <source>Ready to run</source>
+        <translation>Prêt à démarrer</translation>
+    </message>
+    <message>
+        <source>Select parameters</source>
+        <translation>Choix des paramètres</translation>
+    </message>
+    <message>
+        <source>Parameters</source>
+        <translation>Paramètres</translation>
+    </message>
+    <message>
+        <source>Documentation</source>
+        <translation>Documentation</translation>
+    </message>
+    <message>
+        <source>Logs</source>
+        <translation>Logs</translation>
+    </message>
 </context>
 </TS>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/otb.git



More information about the Pkg-grass-devel mailing list