diff --git a/Documentation/Cookbook/rst/FAQ.rst b/Documentation/Cookbook/rst/FAQ.rst
index 39a2287c3ad8a033cea4a7bfa46f9b4d7c8fd36f..490e77a34c1619fb5025e823fcf680d9c3d27c83 100644
--- a/Documentation/Cookbook/rst/FAQ.rst
+++ b/Documentation/Cookbook/rst/FAQ.rst
@@ -243,22 +243,21 @@ OFF the CMake variable OTB\_USE\_EXTERNAL\_ITK.
 OTB compilation and Windows platform
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-To build OTB on Windows, we highly recommend using OSGeo4W which
-provides all the necessary dependencies.
-
-Currently it is not possible to build OTB in Debug when using the
-dependencies provided by OSGeo4W. If you want to build OTB in Debug for
-Windows, you will need to build and install manually each dependency
-needed by OTB. You should use the same compiler for all the
-dependencies, as much as possible.
-
-Therefore, we highly recommend you to use OSGeo4W shell environment to
-build OTB. You can use the 32 or 64 bit installer, since OSGeo4W
-provides all the necessary dependencies in the two cases. Please follow
-carefully the procedure provided in the Software Guide.
-
-Typically, when using the dependencies provided by OSGeo4W, compile OTB
-in Release or RelWithDebInfo mode.
+To build OTB on Windows, you should prepare an environment with the following
+tools:
+
+* Visual Studio 2015 or later
+* CMake 3.1 or later
+* OTB XDK : download a Windows binary package of OTB and use the supplied
+  uninstall script to remove OTB binaries and headers. Now, this package only
+  contains the dependencies needed to build OTB.
+
+Then, you can download OTB sources (preferably, a version compatible with your
+XDK), and compile them as a standard CMake project. More details are available
+in the SoftwareGuide.
+
+There is an other solution, using OSGeo4W distribution. However, the
+dependencies may be outdated.
 
 Using OTB
 ---------
diff --git a/Documentation/Cookbook/rst/Installation_Linux.txt b/Documentation/Cookbook/rst/Installation_Linux.txt
index f8b0dd652b72b8b57dd58982af4bdaea3030eaf5..a236e906a5417653c12333a5967c9b6026d120f0 100644
--- a/Documentation/Cookbook/rst/Installation_Linux.txt
+++ b/Documentation/Cookbook/rst/Installation_Linux.txt
@@ -39,8 +39,8 @@ archive is extracted, the directory structure consists of:
 -  ``share``: A folder containing common resources and copyright
    mentions.
 
--  ``tool``: A folder containing usefull scripts to test the installation or
-   to uninstall OTB libraries and headers while keeping all the depedencies.
+-  ``tool``: A folder containing useful scripts to test the installation or
+   to uninstall OTB libraries and headers while keeping all the dependencies.
 
 The applications can be launched from the Mapla launcher. If you want to
 use the otbcli and otbgui launchers, you can initialize your environment
diff --git a/Documentation/Cookbook/rst/Installation_Macx.txt b/Documentation/Cookbook/rst/Installation_Macx.txt
index 1d227e256ed025b774f8b18cd63281e0df6ac6e2..f77d878dbdc93c71d35f55ffaf211391d613260e 100644
--- a/Documentation/Cookbook/rst/Installation_Macx.txt
+++ b/Documentation/Cookbook/rst/Installation_Macx.txt
@@ -28,8 +28,8 @@ Contents of OTB-|release|-Darwin64 is briefly listed below:
 -  ``share``: A folder containing common resources and copyright
    mentions.
 
--  ``tool``: A folder containing usefull scripts to test the installation or
-   to uninstall OTB libraries and headers while keeping all the depedencies.
+-  ``tool``: A folder containing useful scripts to test the installation or
+   to uninstall OTB libraries and headers while keeping all the dependencies.
 
 The applications can be launched from the Mapla launcher. If you want to
 use the otbcli and otbgui launchers, you can initialize your environment
@@ -90,6 +90,7 @@ A: You can get this error at startup running Monteverdi.app or Mapla.app. The
 solution is to run in a terminal the following command:  
 
 ::
+
    xcode-select --install
 
 And then try to restart Monteverdi or Mapla. 
diff --git a/Documentation/Cookbook/rst/Installation_Windows.txt b/Documentation/Cookbook/rst/Installation_Windows.txt
index 24b3a0c92c3bc58b8a86c9fec163002dcf318076..ab1fe763871fd23ad73b7df855e8b6db3925895c 100644
--- a/Documentation/Cookbook/rst/Installation_Windows.txt
+++ b/Documentation/Cookbook/rst/Installation_Windows.txt
@@ -21,8 +21,8 @@ and their launchers (both command line and graphical launchers are provided):
 -  ``include``: A folder containing all the necessary headers to compile OTB
    based projects.
 
--  ``tool``: A folder containing usefull scripts to test the installation or
-   to uninstall OTB libraries and headers while keeping all the depedencies.
+-  ``tool``: A folder containing useful scripts to test the installation or
+   to uninstall OTB libraries and headers while keeping all the dependencies.
 
 The applications can be launched from the Mapla launcher. If you want to
 use the otbcli and otbgui launchers, you can initialize a command prompt
diff --git a/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst b/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst
index 79273a1b8dad1225cf2e6628664cae3250c5bcd2..ab2a9a98170936d720cec4daf7a6c913c8ae9d6c 100644
--- a/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst
+++ b/Documentation/Cookbook/rst/recipes/contrast_enhancement.rst
@@ -41,7 +41,7 @@ You can apply this transformation with the *ContrastEnhancement* application:
                                -out output_image.tif
                                -spatial global
 
-It allows to compress the dynamic without loosing details and contrast.
+It allows to compress the dynamic without losing details and contrast.
 
 Advanced parameters
 ~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/SoftwareGuide/Latex/ContributorList.tex b/Documentation/SoftwareGuide/Latex/ContributorList.tex
index 8f34a6e134c565737bfa4edc4313219968fb53b2..9d86775fcd545dbd4a687275818dd56ecd69d3e5 100644
--- a/Documentation/SoftwareGuide/Latex/ContributorList.tex
+++ b/Documentation/SoftwareGuide/Latex/ContributorList.tex
@@ -5,6 +5,7 @@ Alexis Huck (Magellium),
 Amit Kulkarni,
 Andreas Tile (Debian GIS),
 Angelos Tzotsos,
+Antoine Regimbeau (CS),
 Antonio Valentino,
 Aur\'elien Bricier (CS),
 Caroline Ruffel (CS),
diff --git a/Documentation/SoftwareGuide/Latex/Installation.tex b/Documentation/SoftwareGuide/Latex/Installation.tex
index 6c1531dc647cd109b5ebb1a094f7f078d06eb9b7..ea869b753148edff4d213bf066a1de0b26a24271 100644
--- a/Documentation/SoftwareGuide/Latex/Installation.tex
+++ b/Documentation/SoftwareGuide/Latex/Installation.tex
@@ -324,7 +324,7 @@ directory, which in our case is \texttt{~/OTB/install/bin/}. For example:
 will launch the command line version of the \textbf{ExtractROI} application,
 while:
 \begin{verbatim}
-./OTB/install/bin/otbgui_ExtractROI
+~/OTB/install/bin/otbgui_ExtractROI
 \end{verbatim}
 will launch the graphical version.
 
@@ -420,7 +420,7 @@ $ make install
 \hline
 \textbf{OTB\_USE\_CURL} & OTBCurl & \\
 \hline
-\textbf{OTB\_USE\_MUPARSER} & OTBMuParser & OTBMathParser OTBDempsterShafer OTBAppClassification OTBAppMathParser OTBAppStereo OTBAppProjection OTBAppSegmentation OTBAppClassification OTBRoadExtraction OTBRCC8 OTBCCOBIA OTBAppSegmentation OTBMeanShift OTBAppSegmentation OTBMeanShift OTBAppSegmentation \\
+\textbf{OTB\_USE\_MUPARSER} & OTBMuParser & OTBMathParser OTBDempsterShafer OTBAppClassification OTBAppMathParser OTBAppStereo OTBAppProjection OTBAppSegmentation OTBRoadExtraction OTBRCC8 OTBCCOBIA OTBMeanShift \\
 \hline
 \textbf{OTB\_USE\_MUPARSERX} & OTBMuParserX & OTBMathParserX OTBAppMathParserX \\
 \hline
diff --git a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
index 16e518a278b56373e958ed974aab6dd2508103c1..3c55bf6efaa3da250f6c0286c1dc1f7cb6e69045 100644
--- a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
+++ b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx
@@ -151,7 +151,7 @@ private:
 		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 th image without loosing too much contrast. "
+      "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.");
@@ -704,7 +704,7 @@ private:
   void ComputeLuminance( const FloatVectorImageType::Pointer inImage ,
                          std::vector < unsigned int > rgb )
   {
-    // Retreive coeffs for each channel
+    // 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");
@@ -828,7 +828,7 @@ private:
       }
   }
 
-  // Threshold function that is normaly done in ComputeHistoFilter  and here is
+  // 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 )
diff --git a/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx b/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx
index 68c99058b4ea89e0ab2bdd1c1dd399f971708c39..c3b04df6a957230444db0dfb6a5c1eb8f3961587 100644
--- a/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx
+++ b/Modules/Applications/AppHyperspectral/app/otbVertexComponentAnalysis.cxx
@@ -51,7 +51,7 @@ private:
   {
     SetName("VertexComponentAnalysis");
     SetDescription("Given a set of mixed spectral vectors, estimate"
-    "reference subtances also known as endmembers using the Vertex"
+    "reference substances also known as endmembers using the Vertex"
     "Component Analysis algorithm.");
 
     // Documentation
@@ -59,7 +59,7 @@ private:
     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 subtances also known"
+    "estimates the spectral signature of reference substances also known"
     "as endmembers.");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
diff --git a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
index 1f0221e665a2291577f3d8ba4cb316624647148d..0378a7024a0ee5172c06d01af936658608ba8635 100644
--- a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx
@@ -252,6 +252,7 @@ private:
     if ( HasValue("in") )
       {
       ImageType* inImage = GetParameterImage("in");
+      inImage->UpdateOutputInformation();
       ImageType::RegionType  largestRegion = inImage->GetLargestPossibleRegion();
 
       bool userExtent = !HasUserValue( "mode.extent.ulx" ) \
@@ -385,7 +386,9 @@ private:
     region.SetIndex(1, GetParameterInt("starty"));
     if ( HasValue("in") )
       {
-      if (region.Crop(GetParameterImage("in")->GetLargestPossibleRegion()))
+      ImageType* inImage = GetParameterImage("in");
+      inImage->UpdateOutputInformation();
+      if (region.Crop(inImage->GetLargestPossibleRegion()))
         {
         SetParameterInt("sizex",region.GetSize(0), HasUserValue("sizex"));
         SetParameterInt("sizey",region.GetSize(1), HasUserValue("sizey"));
@@ -426,19 +429,15 @@ private:
 
       ImageType * inImage = GetParameterImage("in");
       FloatVectorImageType::IndexType uli , lri;
-      bool startin = inImage->TransformPhysicalPointToIndex(ulp,uli);
-      bool sizein = inImage->TransformPhysicalPointToIndex(lrp,lri);
-      if ( startin )
-        {
-        SetParameterInt( "startx", uli[0] , true );
-        SetParameterInt( "starty", uli[1] , true );
-        }
-        
-      if( startin && sizein )
-        {
-        SetParameterInt( "sizex", lri[0] - uli[0] + 1, true );
-        SetParameterInt( "sizey", lri[1] - uli[1] + 1, true );
-        }
+      inImage->TransformPhysicalPointToIndex(ulp,uli);
+      inImage->TransformPhysicalPointToIndex(lrp,lri);
+
+      SetParameterInt( "startx", uli[0] , true );
+      SetParameterInt( "starty", uli[1] , true );
+
+      SetParameterInt( "sizex", lri[0] - uli[0] + 1, true );
+      SetParameterInt( "sizey", lri[1] - uli[1] + 1, true );
+      
       }
     else if( GetParameterString( "mode.extent.unit" ) == "lonlat" )
       {
@@ -456,21 +455,16 @@ private:
       lrp_out = rsTransform->TransformPoint(lrp_in);
 
       FloatVectorImageType::IndexType uli_out , lri_out;
-      bool startin = inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
-      bool sizein = inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);
+      inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
+      inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);
 
-      if ( startin )
-        {
-        SetParameterInt( "startx", uli_out[0] , true );
-        SetParameterInt( "starty", uli_out[1] , true );
-        }
-            
-      if( startin && sizein )
-        {
-        SetParameterInt( "sizex", lri_out[0] - uli_out[0] + 1, true );
-        SetParameterInt( "sizey", lri_out[1] - uli_out[1] + 1, true );
-        }
-      }  
+      SetParameterInt( "startx", uli_out[0] , true );
+      SetParameterInt( "starty", uli_out[1] , true );
+
+      SetParameterInt( "sizex", lri_out[0] - uli_out[0] + 1, true );
+      SetParameterInt( "sizey", lri_out[1] - uli_out[1] + 1, true );
+      }
+      this->CropRegionOfInterest();
   }
 
   void
@@ -685,10 +679,10 @@ private:
     ImageType* inImage = GetParameterImage("in");
     inImage->UpdateOutputInformation();
 
-    if ( HasValue( "mode.fit.vect" ) && GetParameterString("mode") == "fit" )
+    if ( HasValue( "mode.fit.vect" ) && GetParameterString("mode") == "fit")
       {
       otb::ogr::DataSource::Pointer ogrDS;
-      ogrDS = otb::ogr::DataSource::New(GetParameterString("in") ,
+      ogrDS = otb::ogr::DataSource::New(GetParameterString("mode.fit.vect") ,
                                         otb::ogr::DataSource::Modes::Read);
       double ulx, uly, lrx, lry;
       bool extentAvailable = true;
@@ -724,40 +718,50 @@ private:
       if (extentAvailable)
         {
         RSTransformType::Pointer rsTransform = RSTransformType::New();
-        rsTransform->SetInputProjectionRef(inputProjectionRef);
+        rsTransform->SetInputProjectionRef( inputProjectionRef );
         rsTransform->SetOutputKeywordList( inImage->GetImageKeywordlist() );
         rsTransform->SetOutputProjectionRef( inImage->GetProjectionRef() );
         rsTransform->InstantiateTransform();
-
-        itk::Point<float, 2> ulp_in,  lrp_in , ulp_out , lrp_out;
+        itk::Point<float, 2> ulp_in , urp_in , llp_in , lrp_in ,
+          ulp_out , urp_out , llp_out , lrp_out;
         ulp_in[ 0 ] = ulx ;
         ulp_in[ 1 ] = uly ;
+        urp_in[ 0 ] = ulx ;
+        urp_in[ 1 ] = lry ;
+        llp_in[ 0 ] = lrx ; 
+        llp_in[ 1 ] = ulx ;
         lrp_in[ 0 ] = lrx ;
         lrp_in[ 1 ] = lry ;
         ulp_out = rsTransform->TransformPoint(ulp_in);
+        urp_out = rsTransform->TransformPoint(urp_in);
+        llp_out = rsTransform->TransformPoint(llp_in);
         lrp_out = rsTransform->TransformPoint(lrp_in);
+        FloatVectorImageType::IndexType uli_out , uri_out , lli_out , lri_out;
 
-        FloatVectorImageType::IndexType uli_out , lri_out;
-        bool startin , sizein ;
-        startin = inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
-        sizein = inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);
-
-        if ( startin )
-            {
-            SetParameterInt( "startx", uli_out[0] , false );
-            SetParameterInt( "starty", uli_out[1] , false );
-            }
-                
-        if( startin && sizein )
-            {
-            SetParameterInt( "sizey", lri_out[1] - uli_out[1] + 1 , false );
-            SetParameterInt( "sizex", lri_out[0] - uli_out[0] + 1 , false );
-            }
-        }
+        inImage->TransformPhysicalPointToIndex(ulp_out,uli_out);
+        inImage->TransformPhysicalPointToIndex(urp_out,uri_out);
+        inImage->TransformPhysicalPointToIndex(llp_out,lli_out);
+        inImage->TransformPhysicalPointToIndex(lrp_out,lri_out);
         
+        FloatVectorImageType::IndexType uli, lri;
+
+        uli[0] = std::min( std::min( uli_out[0] , uri_out[0] ) , 
+                           std::min( lli_out[0] , lri_out[0] ) );
+        uli[1] = std::min( std::min( uli_out[1] , uri_out[1] ) ,
+                           std::min( lli_out[1] , lri_out[1] ) );
+
+        lri[0] = std::max( std::max( uli_out[0] , uri_out[0] ) ,
+                           std::max( lli_out[0] , lri_out[0] ) );
+        lri[1] = std::max( std::max( uli_out[1] , uri_out[1] ) ,
+                           std::max( lli_out[1] , lri_out[1] ) );
+
+        SetParameterInt( "startx", uli[0] , false );
+        SetParameterInt( "starty", uli[1] , false );   
+        SetParameterInt( "sizex", lri[0] - uli[0] , false );
+        SetParameterInt( "sizey", lri[1] - uli[1] , false );
+        }
       }
-
-    if( HasValue( "mode.fit.im" ) && GetParameterString( "mode" ) == "fit" )
+    else if( HasValue( "mode.fit.im" ) && GetParameterString( "mode" ) == "fit" )
       {
       // Setup the DEM Handler
       otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev");
@@ -820,9 +824,9 @@ private:
       SetParameterInt("sizex",lri[0]-uli[0]);
       SetParameterInt("sizey",lri[1]-uli[1]);
 
-      this->CropRegionOfInterest();
       }
 
+    this->CropRegionOfInterest();
 
     m_ExtractROIFilter = ExtractROIFilterType::New();
     m_ExtractROIFilter->SetInput(inImage);
diff --git a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
index 4d3c9cb2abbc631ef6fde7bb034f4b183d27a342..3c91403e47100f50b352f436f2a7583d648a14de 100644
--- a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
+++ b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
@@ -91,7 +91,7 @@ private:
   {
     SetName("OrthoRectification");
     std::ostringstream oss;
-    oss << "This application allows to ortho-rectify optical and radar images from supported sensors." << std::endl;
+    oss << "This application allows ortho-rectifying optical and radar images from supported sensors." << std::endl;
     SetDescription(oss.str());
     // Documentation
     SetDocName("Ortho-rectification");
diff --git a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
index 111dea621f106dfc47f36a4b3e3319b81ce1e0d3..616594a6bb40d025e53535a344b3e4fadea294e0 100644
--- a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
+++ b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
@@ -115,7 +115,7 @@ private:
       " geometry.\n\n"
       "There are several ways to set the elevation source:\n"
       "  * An arbitrary constant elevation\n"
-      "  * A DEM directoy\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 "
diff --git a/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx b/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx
index 566ca5a34d305d7731a3df7567fc0d4f3d95ee9a..be163190893c063b32711abab1f45f8c77e67d13 100644
--- a/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx
+++ b/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx
@@ -89,7 +89,7 @@ private:
 
     AddParameter(ParameterType_InputImage, "in", "Support image");
     SetParameterDescription("in","Image defining the reference coordinate "
-      "system in which the tranform is applied. Both projected and sensor "
+      "system in which the transform is applied. Both projected and sensor "
       "images are supported.");
 
     // Transform Group
diff --git a/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.h b/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.h
index 431b6f1f0f5f55d0bc5c403a1df86e8f5f26e255..5a4c088dbc517565006fbc0c33492c8b9ebfdacd 100644
--- a/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.h
+++ b/Modules/Filtering/Contrast/include/otbComputeGainLutFilter.h
@@ -107,7 +107,7 @@ private:
                      HistoType & targetHisto ) ;
   //TODO Give the opportunity to choose the histogram target
   
-  /** Check whether the input histogram has enought pixel to be meaningful */
+  /** Check whether the input histogram has enough pixel to be meaningful */
   bool IsValid(const HistoType & inputHisto ) ;
 
   double m_Min;
diff --git a/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx b/Modules/Learning/LearningBase/include/otbMachineLearningModel.txx
index 678974e9d4f23525783842b860548dfc8b5ad4a9..00da0413879e83f013cf98053413e81dbcac0193 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/Sampling/include/otbOGRDataToSamplePositionFilter.h b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h
index 77388ff308006d5157bbd1cbb1c460132c78d674..8393766bcb81489c5e2582e2b1a38bb8912a4251 100644
--- a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h
+++ b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.h
@@ -139,6 +139,9 @@ protected:
    */
   void DispatchInputVectors(void) ITK_OVERRIDE;
 
+  /** Fill the output vectors with a special ordering (class partition) */
+  void FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update) ITK_OVERRIDE;
+
 private:
   PersistentOGRDataToSamplePositionFilter(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
diff --git a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx
index e2d8a40810ea938c874108af958fadd66e9ebb4e..cc70bcbb953570890938f3aa1f72993ac487e19b 100644
--- a/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx
+++ b/Modules/Learning/Sampling/include/otbOGRDataToSamplePositionFilter.txx
@@ -308,6 +308,55 @@ PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler>
     }
 }
 
+template<class TInputImage, class TMaskImage, class TSampler>
+void
+PersistentOGRDataToSamplePositionFilter<TInputImage,TMaskImage,TSampler>
+::FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update)
+{
+  ogr::Layer outLayer = outDS->GetLayersCount() == 1
+                        ? outDS->GetLayer(0)
+                        : outDS->GetLayer(this->GetOutLayerName());
+
+  OGRErr err = outLayer.ogr().StartTransaction();
+  if (err != OGRERR_NONE)
+    {
+    itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
+    }
+
+  // output vectors sorted by class
+  for (auto& label : m_ClassPartition)
+    {
+    ogr::Layer inLayer = this->GetInMemoryOutput(label.second,outIdx);
+    if (!inLayer)
+      {
+      continue;
+      }
+
+    // This test only uses 1 input, not compatible with multiple OGRData inputs
+    for(auto tmpIt = inLayer.begin(); tmpIt!=inLayer.end(); ++tmpIt)
+      {
+      if( label.first.compare(tmpIt->ogr().GetFieldAsString(this->GetFieldIndex())) != 0 )
+        continue;
+      if(update)
+        {
+        outLayer.SetFeature( *tmpIt );
+        }
+      else
+        {
+        ogr::Feature dstFeature(outLayer.GetLayerDefn());
+        dstFeature.SetFrom( *tmpIt, TRUE );
+        outLayer.CreateFeature( dstFeature );
+        }
+      }
+    }
+
+  err = outLayer.ogr().CommitTransaction();
+  if (err != OGRERR_NONE)
+    {
+    itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
+    }
+}
+
 // -------------- otb::OGRDataToSamplePositionFilter --------------------------
 
 template<class TInputImage, class TMaskImage, class TSampler>
diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h
index 8e80fb9e0e77c81e28834d36b1921b09768266a9..bb3b0ac40623ccd7766562f13755ad3e18cae45d 100644
--- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h
+++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.h
@@ -165,6 +165,9 @@ protected:
   /** Gather the content of in-memory output layer into the filter outputs */
   virtual void GatherOutputVectors(void);
 
+  /** Fill output vectors for a particular output */
+  virtual void FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update);
+
   /** Utility method to add new fields on an output layer */
   virtual void InitializeOutputDataSource(ogr::DataSource* inputDS, ogr::DataSource* outputDS);
 
diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
index f10ace96a9ba43e0194a191e2bcd57320fed310a..2973a7a8a3a2e251cdef0ffcf55f034eb6b217aa 100644
--- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
+++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx
@@ -275,8 +275,6 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
   // clean temporary inputs
   this->m_InMemoryInputs.clear();
 
-  unsigned int numberOfThreads = this->GetNumberOfThreads();
-
   // gather temporary outputs and write to output
   const otb::ogr::DataSource* vectors = this->GetOGRData();
   otb::Stopwatch chrono = otb::Stopwatch::StartNew();
@@ -287,58 +285,67 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage>
         this->itk::ProcessObject::GetOutput(k));
     if (realOutput)
       {
-      ogr::Layer outLayer = realOutput->GetLayersCount() == 1
-                            ? realOutput->GetLayer(0)
-                            : realOutput->GetLayer(m_OutLayerName);
+      this->FillOneOutput(count, realOutput, bool(vectors == realOutput));
+      count++;
+      }
+    }
 
-      OGRErr err = outLayer.ogr().StartTransaction();
-      if (err != OGRERR_NONE)
-        {
-        itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
-        }
+  chrono.Stop();
+  otbMsgDebugMacro(<< "Writing OGR points took " << chrono.GetElapsedMilliseconds() << " ms");
+  this->m_InMemoryOutputs.clear();
+}
 
-      for (unsigned int thread=0 ; thread < numberOfThreads ; thread++)
-        {
-        ogr::Layer inLayer = this->m_InMemoryOutputs[thread][count]->GetLayerChecked(0);
-        if (!inLayer)
-          {
-          continue;
-          }
+template <class TInputImage, class TMaskImage>
+void
+PersistentSamplingFilterBase<TInputImage,TMaskImage>
+::FillOneOutput(unsigned int outIdx, ogr::DataSource* outDS, bool update)
+{
+  ogr::Layer outLayer = outDS->GetLayersCount() == 1
+                        ? outDS->GetLayer(0)
+                        : outDS->GetLayer(m_OutLayerName);
 
-        ogr::Layer::const_iterator tmpIt = inLayer.begin();
-        // This test only uses 1 input, not compatible with multiple OGRData inputs
-        if (vectors == realOutput)
-          {
-          // Update mode
-          for(; tmpIt!=inLayer.end(); ++tmpIt)
-            {
-            outLayer.SetFeature( *tmpIt );
-            }
-          }
-        else
-          {
-          // Copy mode
-          for(; tmpIt!=inLayer.end(); ++tmpIt)
-            {
-            ogr::Feature dstFeature(outLayer.GetLayerDefn());
-            dstFeature.SetFrom( *tmpIt, TRUE );
-            outLayer.CreateFeature( dstFeature );
-            }
-          }
-        }
+  OGRErr err = outLayer.ogr().StartTransaction();
+  if (err != OGRERR_NONE)
+    {
+    itkExceptionMacro(<< "Unable to start transaction for OGR layer " << outLayer.ogr().GetName() << ".");
+    }
 
-      err = outLayer.ogr().CommitTransaction();
-      if (err != OGRERR_NONE)
+  unsigned int numberOfThreads = this->GetNumberOfThreads();
+  for (unsigned int thread=0 ; thread < numberOfThreads ; thread++)
+    {
+    ogr::Layer inLayer = this->m_InMemoryOutputs[thread][outIdx]->GetLayerChecked(0);
+    if (!inLayer)
+      {
+      continue;
+      }
+
+    ogr::Layer::const_iterator tmpIt = inLayer.begin();
+    // This test only uses 1 input, not compatible with multiple OGRData inputs
+    if (update)
+      {
+      // Update mode
+      for(; tmpIt!=inLayer.end(); ++tmpIt)
         {
-        itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
+        outLayer.SetFeature( *tmpIt );
+        }
+      }
+    else
+      {
+      // Copy mode
+      for(; tmpIt!=inLayer.end(); ++tmpIt)
+        {
+        ogr::Feature dstFeature(outLayer.GetLayerDefn());
+        dstFeature.SetFrom( *tmpIt, TRUE );
+        outLayer.CreateFeature( dstFeature );
         }
-      count++;
       }
     }
 
-  chrono.Stop();
-  otbMsgDebugMacro(<< "Writing OGR points took " << chrono.GetElapsedMilliseconds() << " ms");
-  this->m_InMemoryOutputs.clear();
+  err = outLayer.ogr().CommitTransaction();
+  if (err != OGRERR_NONE)
+    {
+    itkExceptionMacro(<< "Unable to commit transaction for OGR layer " << outLayer.ogr().GetName() << ".");
+    }
 }
 
 template <class TInputImage, class TMaskImage>
diff --git a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
index ad665fa48d910d4edb98e4b4fd97174446dbf27f..96cbf7120c497f340b31f7657e7161bbeafd2d63 100644
--- a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
+++ b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
@@ -554,21 +554,39 @@ SimpleParallelTiffWriter<TInputImage>
     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
diff --git a/Modules/Radiometry/SARCalibration/test/otbSarDeburstFilterTest.cxx b/Modules/Radiometry/SARCalibration/test/otbSarDeburstFilterTest.cxx
index 5d0f320c83194842843803a09b87cd78db05c3ad..d221088626f509462223f9cbbb93a6ce8d96c75a 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/Remote/SertitObject.remote.cmake b/Modules/Remote/SertitObject.remote.cmake
index 75cf492f5fd30f6bb092587a6b469b744c554c45..cabe6323f282290287acbcd89dd8cd14c9915d99 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 master
+  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 08bfd90bfd136bd4a369e30d4f99c13778de709d..b75c04cbf3866829bd9eac6bab586fa63da0a515 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 master
+  GIT_TAG f9aa7988fc399d8713f9e28fac15e637a783be6e
   )
diff --git a/Modules/Remote/otbGRM.remote.cmake b/Modules/Remote/otbGRM.remote.cmake
index 7083c522f2429f630c70049ea3b3e9998de2afb0..383c97da56fe3de3a8ad53ba7fbbf2d7c4c60698 100644
--- a/Modules/Remote/otbGRM.remote.cmake
+++ b/Modules/Remote/otbGRM.remote.cmake
@@ -12,5 +12,5 @@ A more detailed description can be found on the project website:
 http://tully.ups-tlse.fr/lassallep/grm
 "
   GIT_REPOSITORY https://github.com/orfeotoolbox/GRM
-  GIT_TAG develop
+  GIT_TAG c53a61d12b895a85c3909130021988730c309cb7
 )
diff --git a/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx b/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx
index 7bfeed219da832ca95fbe648759fec1df2a89d16..0d41eba032274c1a69201edf7cdd8d000cdc1c9d 100644
--- a/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbLabelImageToOGRDataSourceFilter.txx
@@ -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");
diff --git a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
index 95899b213f30a1574e34106603927a74ff52e9d7..d76968ecf1929a8f8034e016c8b13fa2d2ff3bfb 100644
--- a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
+++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h
@@ -421,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/ossimSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
index 46381857ea6df04347140969650827588ab1b395..ac695a2a4b790ebce7671fc7e27c62a954e91098 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp
@@ -46,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.
@@ -108,6 +107,8 @@ namespace ossimplugins
 
    const double ossimSarSensorModel::C = 299792458;
 
+   const unsigned int ossimSarSensorModel::thePluginVersion = 2;
+
    ossimSarSensorModel::ProductType::ProductType(string_view const& s)
    {
       using ossimplugins::begin;
@@ -952,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)
@@ -1218,13 +1222,18 @@ namespace ossimplugins
      static const char MODULE[] = "ossimplugins::ossimSarSensorModel::saveState";
      SCOPED_LOG(traceDebug, MODULE);
 
-     kwl.add(prefix,
-             ossimKeywordNames::TYPE_KW,
-             "ossimSarSensorModel",
-             true);
-
-     add(kwl, SUPPORT_DATA_PREFIX + "product_type", theProductType.ToString().data());
+     // 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    );
@@ -1247,7 +1256,7 @@ namespace ossimplugins
      kwl.removeKeysThatMatch(GCP_PREFIX+"*");
      add(kwl, theGCPRecords);
 
-     add(kwl, HEADER_PREFIX, "version", k_version);
+     add(kwl, HEADER_PREFIX, "version", thePluginVersion);
 
      return ossimSensorModel::saveState(kwl, prefix);
    }
@@ -1297,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/ossimSentinel1Model.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
index 17d764ceb1650dc38355703dd31006947a3b7ec8..716e7ad48addc2545c2c5855abbd1afc1c7651c8 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
@@ -150,11 +150,8 @@ namespace ossimplugins
 
       kwl.addList(theManifestKwl, true);
       kwl.addList(theProductKwl,  true);
-
-      const unsigned int k_version = 2;
-      add(kwl, HEADER_PREFIX, "version", k_version);
       
-      return ossimSensorModel::saveState(kwl, prefix);
+      return ossimSarSensorModel::saveState(kwl, prefix);
    }
 
 
@@ -214,6 +211,8 @@ namespace ossimplugins
 
       // -----[ Read manifest file
       const ossimFilename safeFile = searchManifestFile(file);
+      ossimString sensorId;
+      ossimString imageId;
 
       if ( !safeFile.empty() )
       {
@@ -235,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;
          }
@@ -246,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;
          }
@@ -316,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;
@@ -680,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);
@@ -787,6 +792,10 @@ namespace ossimplugins
             numBands,
             true);
 #endif
+
+      // Ensure that superclass members are initialized
+      loadState(theProductKwl);
+      
       return true;
    }
 
diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i
index 3489e589aa3e3c3a18e305e4448076aa99612404..d945d52af4dc68f35b84e30601c69fa2896557c5 100644
--- a/Modules/Wrappers/SWIG/src/otbApplication.i
+++ b/Modules/Wrappers/SWIG/src/otbApplication.i
@@ -747,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/test/python/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
index d1e4a50cf2f386418deb425a00d10f1d65eaaa30..b0e0ac49bc32e831d3780db989ad2a08938e293b 100644
--- a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
@@ -19,7 +19,6 @@
 #
 
 set(TEST_DRIVER otbTestDriver
-    --add-before-env PYTHONPATH        "${OTBSWIGWrapper_BINARY_DIR}/src"
     --add-before-env PYTHONPATH        $<TARGET_FILE_DIR:_otbApplication>
     --add-before-env OTB_APPLICATION_PATH $<TARGET_FILE_DIR:otbapp_Smoothing> )
 
@@ -27,7 +26,6 @@ if(WIN32)
   # on windows, loading the module _otbApplication requires the otbossimplugins*.dll
   # which is in the 'bin/<CMAKE_BUILD_TYPE>' folder
   set(TEST_DRIVER ${TEST_DRIVER}
-    --add-before-env PATH ${CMAKE_BINARY_DIR}/bin
     --add-before-env PATH $<TARGET_FILE_DIR:OTBCommon>)
 endif(WIN32)
 
diff --git a/Packaging/Files/selftester.sh b/Packaging/Files/selftester.sh
index 8137cfa29979d09df9e4615a2b618a552cb60d70..830fbf83e0f5499c3e82f8885fe52e84a0bdcbc0 100755
--- a/Packaging/Files/selftester.sh
+++ b/Packaging/Files/selftester.sh
@@ -31,6 +31,11 @@ ps_children () {
   ps -e -o pid -o command=COMMAND-WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIDE-COLUMN -o ppid | grep " $1$" | grep -v -e ' grep ' -e ' ps -e '
 }
 
+# get the pid field from the output line of ps_children
+get_pid() {
+  echo "$1" | grep -E -o '[0-9]+' | head -n 1
+}
+
 # nb_report_lines( ) : get number of lines in report
 nb_report_lines () {
   report_lines="$(wc -l selftest_report.log)"
@@ -127,12 +132,12 @@ for app in $OTB_APPS; do
     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")
+      CHILD_PROC=$(ps_children $GUI_PID | grep " bin/otbgui $app")
       if [ -n "$CHILD_PROC" ]; then
-        CHILD_PID=$(echo "$CHILD_PROC" | cut -d ' ' -f 1)
+        CHILD_PID=$(get_pid "$CHILD_PROC")
         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)
+          NEXT_CHILD_PID=$(get_pid "$NEXT_CHILD_PROC")
         fi
       fi
       nb_try=$(( nb_try + 1 ))
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 1f7046b54e1b88e5a70ab7d4afe033b84f40a0bf..2421280562e417e92d9a4f12d71cc33729a25736 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/Maintenance/SuperbuildDownloadList.sh b/Utilities/Maintenance/SuperbuildDownloadList.sh
index 382bc58ccaf4ff790407ba07981484085e0d59cd..48f693cc6b897324be7dab2feea2461af6a7afe9 100755
--- a/Utilities/Maintenance/SuperbuildDownloadList.sh
+++ b/Utilities/Maintenance/SuperbuildDownloadList.sh
@@ -53,14 +53,14 @@ mkdir -p "${DOWNLOAD_DIR}"
 cd "${DOWNLOAD_DIR}" || echo "cannot cd to DOWNLOAD_DIR"
 echo "Downloading files to ${DOWNLOAD_DIR}/"
 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} |
+  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-)
+    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
@@ -68,7 +68,7 @@ for cmake in ${CMAKE_FILES}; do
        exit 1;
     fi
     if [ -n "$download_name" ]; then
-      mv $file_name $download_name
+      mv "${file_name}" "${download_name}"
       file_name=$download_name
     fi
     DOWNLOAD_NAMES="${DOWNLOAD_NAMES} ${file_name}"