diff --git a/CMake/FindNumpy.cmake b/CMake/FindNumpy.cmake
index 764f57497c1dfbf43dda09118bc8e538fb513047..b53aa7c18a7d8bc7e3f1a1ef39ef4c400b7ca9cb 100644
--- a/CMake/FindNumpy.cmake
+++ b/CMake/FindNumpy.cmake
@@ -5,7 +5,7 @@
 #   NUMPY_INCLUDE_DIR   - where to find numpy/arrayobject.h, etc.
 
 EXEC_PROGRAM ("${PYTHON_EXECUTABLE}"
-  ARGS "-c 'import numpy; print numpy.get_include()'"
+  ARGS "${CMAKE_SOURCE_DIR}/CMake/otbTestNumpy.py"
   OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
   RETURN_VALUE NUMPY_NOT_FOUND)
 
diff --git a/CMake/OTBSetStandardCompilerFlags.cmake b/CMake/OTBSetStandardCompilerFlags.cmake
index 6814998e15d3418a6a59d0619136575630d3aaef..c44cb79482ee4c602d2dce33d9a62250eda26a9b 100644
--- a/CMake/OTBSetStandardCompilerFlags.cmake
+++ b/CMake/OTBSetStandardCompilerFlags.cmake
@@ -132,6 +132,23 @@ endfunction()
 
 
 macro(check_compiler_platform_flags)
+  # Since CMake 2.8.11, the size of the stack is not modified by CMake on
+  # windows platform, it uses the default size: with visual compiler it is 1Mbyte
+  # which is to lower for us (thanks to 6S code).
+  if(MSVC)
+    if (${CMAKE_VERSION} VERSION_GREATER "2.8.10.2")
+      if("${CMAKE_EXE_LINKER_FLAGS}" MATCHES "/STACK:[0-9]+")
+          message(STATUS "The size of the stack is already defined, so we dont't modified it.")
+      else()
+          set(OTB_REQUIRED_LINK_FLAGS "${OTB_REQUIRED_LINK_FLAGS} /STACK:10000000")
+          message(STATUS "The stack size is set to 10 Mbytes (/STACK:10000000).")
+      endif()
+    endif() #if (${CMAKE_VERSION..
+  elseif(MINGW)
+    set(OTB_REQUIRED_LINK_FLAGS "${OTB_REQUIRED_LINK_FLAGS} -Wl,--stack,10000000")
+    message(STATUS "The stack size is set to 10 Mbytes (-Wl,--stack,10000000).")
+  endif() # if(MSVC)
+
   # On Visual Studio 8 MS deprecated C. This removes all 1.276E1265 security
   # warnings
   if(WIN32)
diff --git a/CMake/otbTestNumpy.py b/CMake/otbTestNumpy.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b9a80111c4a895d0069dc9639c9701628c32e49
--- /dev/null
+++ b/CMake/otbTestNumpy.py
@@ -0,0 +1,2 @@
+import numpy
+print numpy.get_include()
diff --git a/Modules/Adapters/BoostAdapters/include/otbStringUtils.h b/Modules/Adapters/BoostAdapters/include/otbStringUtils.h
index 9c675f695fd19226845e538a84e4c6a4cba3cd7b..341b231eb2b73ce2895635aa609105b62234dea0 100644
--- a/Modules/Adapters/BoostAdapters/include/otbStringUtils.h
+++ b/Modules/Adapters/BoostAdapters/include/otbStringUtils.h
@@ -40,7 +40,7 @@ Res LexicalCast(In const& in, std::string const& kind) {
     }
     catch (boost::bad_lexical_cast &) {
         std::ostringstream oss;
-        oss << "Cannot decode " << in << " as this is not a valid value for " << kind;
+        oss << "Cannot decode '" << in << "' as this is not a valid value for '" << kind << "'";
         throw std::runtime_error(oss.str());
     }
 }
diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h b/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h
index 0a37948fab58167d9426007187279e5468497bd8..ed6bf3db5189fb534dbcb54c513b4f99f4b999ff 100644
--- a/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h
+++ b/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.h
@@ -32,8 +32,8 @@
 #include "itkObjectFactory.h" // that should have been included by itkMacro.h
 
 #include "otbOGRLayerWrapper.h"
+#include "otbOGRVersionProxy.h"
 
-class OGRDataSource;
 class OGRLayer;
 class OGRSpatialReference;
 class OGRGeometry;
@@ -46,7 +46,7 @@ namespace otb { namespace ogr {
  *
  * This class is meant to supercede \c otb::VectorData class.  It provides
  * an encapsulation of OGR classes. In that particular case, it's an
- * encapsulation of \c OGRDataSource.
+ * encapsulation of \c GDALDataset.
  *
  * \note Not meant to be inherited.
  * \note This class has an entity semantics: \em non-copyable, nor \em
@@ -77,10 +77,10 @@ public:
   //@{
   /** Default builder.
    * This builder function creates a new \c DataSource with its default
-   * constructor. The actual \c OGRDataSource is using the <em>in-memory</em>
+   * constructor. The actual \c GDALDataset is using the <em>in-memory</em>
    * \c OGRSFDriver: \c OGRMemDriver.
    *
-   * \throw itk::ExceptionObject if the inner \c OGRDataSource cannot be
+   * \throw itk::ExceptionObject if the inner \c GDALDataset cannot be
    * opened.
    *
    * \note \c OGRRegisterAll() is implicitly called on construction.
@@ -130,24 +130,24 @@ public:
    * \param[in] datasourcename OGR identifier of the data source
    * \param[in] mode     opening mode (read or read-write)
    * \return a newly created \c DataSource.
-   * \throw itk::ExceptionObject if the inner \c OGRDataSource cannot be
+   * \throw itk::ExceptionObject if the inner \c GDALDataset cannot be
    * opened.
    * \note \c OGRRegisterAll() is implicitly called on construction
-   * \see \c DataSource(OGRDataSource *)
+   * \see \c DataSource(GDALDataset *)
    */
   static Pointer New(std::string const& datasourcename, Modes::type mode = Modes::Read);
   /**
-   * Builder from a built \c OGRDataSource.
-   * \param[in,out] source  \c OGRDataSource already constructed.
+   * Builder from a built \c GDALDataset.
+   * \param[in,out] source  \c GDALDataset already constructed.
    * \return a newly created \c DataSource that assumes ownership of \c
    * source.
    * \throw Nothing
    * \note \c OGRRegisterAll() is supposed to have been called before building
    * \c source.
    * \note No condition is assumed on the non-nullity of \c source.
-   * \see \c DataSource(OGRDataSource *)
+   * \see \c DataSource(GDALDataset *)
    */
-  static Pointer New(OGRDataSource * sourcemode, Modes::type mode = Modes::Read);
+  static Pointer New(ogr::version_proxy::GDALDatasetType * sourcemode, Modes::type mode = Modes::Read);
   //@}
 
   /**\name Projection Reference property */
@@ -159,7 +159,7 @@ public:
   //@}
 
   /** Clears the data source.
-   * \post The \c OGRDataSource owned is destroyed with the dedicated function
+   * \post The \c GDALDataset owned is destroyed with the dedicated function
    * from OGR %API.
    * \post <tt>m_DataSource = 0</tt>
    */
@@ -274,17 +274,17 @@ public:
    *
    * This is a convenience function to setup a second data source with all the
    * meta information of another data source and use the same underlying \c
-   * OGRDataSource.
+   * GDALDataset.
    */
   virtual void Graft(const itk::DataObject *data);
 
   /**
    * Resets current data source with the one in parameter.
-   * \param[in,out] source source \c OGRDataSource that this instance will own.
+   * \param[in,out] source source \c GDALDataset that this instance will own.
    * \throw None
    * \post Assumes ownership of the \c source.
    */
-  void Reset(OGRDataSource * source);
+  void Reset(ogr::version_proxy::GDALDatasetType * source);
 
   /**\name Layers modification */
   //@{
@@ -309,7 +309,7 @@ public:
    * with \c CreateLayer(), you must use \c DeleteLayer().
    * \note The \c papszOptions parameter may later become a \c
    * std::vector<std::string>.
-   * \sa \c OGRDataSource::CreateLayer()
+   * \sa \c GDALDataset::CreateLayer()
    */
   Layer CreateLayer(
     std::string        const& name,
@@ -327,7 +327,7 @@ public:
    *
    * \pre The data source must support the delete operation.
    * \pre The index \c i must be in range [0, GetLayersCount()).
-   * \sa \c OGRDataSource::DeleteLayer()
+   * \sa \c GDALDataset::DeleteLayer()
    */
   void DeleteLayer(size_t i);
 
@@ -348,7 +348,7 @@ public:
    * with \c CreateLayer(), you must use \c DeleteLayer().
    * \note The \c papszOptions parameter may later become a \c
    * std::vector<std::string>.
-   * \sa \c OGRDataSource::CopyLayer()
+   * \sa \c GDALDataset::CopyLayer()
    */
   Layer CopyLayer(
     Layer            & srcLayer,
@@ -361,7 +361,7 @@ public:
    */
   //@{
   /** Returns the number of layers.
-   * \sa \c OGRDataSource::GetLayersCount()
+   * \sa \c GDALDataset::GetLayersCount()
    */
   int GetLayersCount() const;
 
@@ -437,8 +437,8 @@ public:
    * neither this wrapping.
    * \note The returned \c Layer will be automatically collected on its
    * destruction; i.e. unlike OGR API, no need to explicitly call \c
-   * OGRDataSource::ReleaseResultSet().
-   * \sa \c OGRDataSource::ExecuteSQL()
+   * GDALDataset::ReleaseResultSet().
+   * \sa \c GDALDataset::ExecuteSQL()
    */
   Layer ExecuteSQL(
     std::string const& statement,
@@ -461,32 +461,32 @@ public:
 
   /** Flushes all changes to disk.
    * \throw itd::ExceptionObject in case the flush operation failed.
-   * \sa \c OGRDataSource::SyncToDisk()
+   * \sa \c GDALDataset::SyncToDisk()
    */
   void SyncToDisk();
 
   /** Returns whether a capability is avalaible.
    * \param[in] capabilityName  name of the capability to check.
    * \throw None
-   * \sa \c OGRDataSource::TestCapability()
+   * \sa \c GDALDataset::TestCapability()
    */
   bool HasCapability(std::string const& capabilityName) const;
 
-  /** Access to raw \c OGRDataSource.
+  /** Access to raw \c GDALDataset.
    * This function provides an abstraction leak in case deeper control on the
-   * underlying \c OGRDataSource is required.
-   * \pre The underlying \c OGRDataSource must be valid, i.e.
+   * underlying \c GDALDataset is required.
+   * \pre The underlying \c GDALDataset must be valid, i.e.
    * <tt>m_DataSource != 0</tt>, an assertion is fired otherwise.
-   * \warning You must under no circonstance try to delete the \c OGRDataSource
+   * \warning You must under no circonstance try to delete the \c GDALDataset
    * obtained this way.
    */
-  OGRDataSource & ogr();
+    ogr::version_proxy::GDALDatasetType & ogr();
 
 protected:
   /** Default constructor.
-   * The actual \c OGRDataSource is using the <em>in-memory</em> \c
+   * The actual \c GDALDataset is using the <em>in-memory</em> \c
    * OGRSFDriver: \c OGRMemDriver.
-   * \throw itk::ExceptionObject if the inner \c OGRDataSource cannot be
+   * \throw itk::ExceptionObject if the inner \c GDALDataset cannot be
    * opened.
    *
    * \note \c OGRRegisterAll() is implicitly called on construction
@@ -496,9 +496,9 @@ protected:
   /** Init constructor.
    * \post The newly constructed object owns the \c source parameter.
    */
-  DataSource(OGRDataSource * source, Modes::type mode);
+  DataSource(ogr::version_proxy::GDALDatasetType * source, Modes::type mode);
   /** Destructor.
-   * \post The \c OGRDataSource owned is released (if not null).
+   * \post The \c GDALDataset owned is released (if not null).
    */
   virtual ~DataSource();
 
@@ -516,7 +516,7 @@ private:
    * \pre The layer must available, 0 is returned otherwise.
    * \throw None
    * \internal this function is a simple encapsulation of \c
-   * OGRDataSource::GetLayer().
+   * GDALDataset::GetLayer().
    */
   OGRLayer* GetLayerUnchecked(size_t i);
   /** @copydoc OGRLayer* otb::ogr::DataSource::GetLayerUnchecked(size_t i)
@@ -529,8 +529,11 @@ private:
   size_t GetLayerID(std::string const& name) const;
   int GetLayerIDUnchecked(std::string const& name) const;
 
+  /** Get a string describing the dataset */
+  std::string GetDatasetDescription() const;
+    
 private:
-  OGRDataSource  *m_DataSource;
+  ogr::version_proxy::GDALDatasetType *m_DataSource;
   Modes::type    m_OpenMode;
   int            m_FirstModifiableLayerID;
   }; // end class DataSource
diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.txx b/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.txx
index d9f240e07872467c2eb34c996e016326cbe6a740..3ae9e89704c1abcd31eeff29bc4ee989fa295315 100644
--- a/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.txx
+++ b/Modules/Adapters/GdalAdapters/include/otbOGRDataSourceWrapper.txx
@@ -38,9 +38,9 @@
 // to the compilation mode of the client code.
 
 inline
-OGRDataSource & otb::ogr::DataSource::ogr()
+otb::ogr::version_proxy::GDALDatasetType & otb::ogr::DataSource::ogr()
 {
-  assert(m_DataSource && "OGRDataSource not initialized");
+  assert(m_DataSource && "GDALDataset not initialized");
   return *m_DataSource;
 }
 
diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRLayerWrapper.h b/Modules/Adapters/GdalAdapters/include/otbOGRLayerWrapper.h
index 007229fc9ac2224b0ee822afe9250c0c86ad1bc7..419b84723c8e580d9b4fefffd493943cf18424f7 100644
--- a/Modules/Adapters/GdalAdapters/include/otbOGRLayerWrapper.h
+++ b/Modules/Adapters/GdalAdapters/include/otbOGRLayerWrapper.h
@@ -24,11 +24,11 @@ PURPOSE.  See the above copyright notices for more information.
 #include <boost/utility/enable_if.hpp>
 // #include "itkIndent.h", included from field
 #include "otbOGRFeatureWrapper.h"
+#include "otbOGRVersionProxy.h"
 
 // #include "ogr_core.h" // OGRwkbGeometryType, included from feature -> field
 // Forward declarations
 class OGRLayer;
-class OGRDataSource;
 class OGRGeometry;
 class OGRFeatureDefn;
 
@@ -94,7 +94,7 @@ public:
   /**
    * Init constructor for layers that need to be released.
    * \param layer  \c OGRLayer owned by the client code.
-   * \param sourceInChargeOfLifeTime  reference to the actual \c OGRDataSource
+   * \param sourceInChargeOfLifeTime  reference to the actual \c GDALDataset
    * that knows how to release the layer.
    * \post In this case, \c m_datasource is left null: we suppose (for now, that
    * the layer won't need access to the datasource meta-information).
@@ -105,7 +105,7 @@ public:
    * OGRDataSource::ExecuteSQL(). It's actually the constructor called by \c
    * DataSource::ExecuteSQL().
    */
-  Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime, bool modifiable);
+    Layer(OGRLayer* layer, otb::ogr::version_proxy::GDALDatasetType& sourceInChargeOfLifeTime, bool modifiable);
   //@}
 
   /**\name Features collection */
diff --git a/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h b/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c4ac63e4b685b3fddcfdb2fedba65f07e55523f
--- /dev/null
+++ b/Modules/Adapters/GdalAdapters/include/otbOGRVersionProxy.h
@@ -0,0 +1,183 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbOGRVersionProxy_h
+#define __otbOGRVersionProxy_h
+
+#include <string>
+#include <vector>
+#include "otbConfigure.h"
+
+#ifdef OTB_USE_GDAL_20
+class GDALDataset;
+class GDALDriver;
+#else
+class OGRDataSource;
+class OGRSFDriver;
+#endif
+
+namespace otb
+{
+namespace ogr
+{
+namespace version_proxy
+{
+
+/** 
+ * This namespace holds proxy functions hiding interface changes in gdal 2.0 
+ *
+ * This namespace holds proxy functions hiding interface changes in OGR
+ * dataset between gdal 1.x (x>10) and gdal 2.x. It defines a common
+ * interface that should be used in place of calling directly the
+ * wrapped gdal functions.
+ * 
+ * Whenever GDALDataset and GDALDriver have to be used to open a
+ * vector dataset (or OGRDataSource an OGRSFDriver for gdal 1.x), one
+ * should use ogr::version_proxy types GDALDatasetType and
+ * GDALDriverType.
+ * 
+ * See function documentation for details.
+ */
+
+  #ifdef OTB_USE_GDAL_20
+  typedef GDALDataset GDALDatasetType;
+  typedef GDALDriver GDALDriverType;
+  #else
+  typedef OGRDataSource GDALDatasetType;
+  typedef OGRSFDriver   GDALDriverType;
+#endif
+
+  /** 
+   * This function opens a file, possibly in read-only mode, and returns
+   * a dataset.
+   *
+   * Calls OGRSFDriverRegistrar::Open for gdal 1.x implementation and GDALopenEx for
+   * gdal 2.x implementation.
+
+   * \param filename Filename of the file to open
+   * \param readOnly: If true, dataset is open in read-only mode.
+   * \return NULL if file could not be open.
+   */ 
+  GDALDatasetType * Open(const char * filename, bool readOnly = true);
+
+  /**
+   * This function closes a dataset.
+   *
+   * Calls OGRDataSource::DestroyDataSource for gdal 1.x
+   * implementation and GDALClose for gdal 2.x implementation.
+   *
+   * \param dataset Pointer to the dataset to close. Will not be
+   * checked for null pointer.
+   */
+  void Close(GDALDatasetType * dataset);
+
+  /**
+   * This function creates a new dataset.
+   *
+   * Calls OGRSFDriver::CreateDataSource for gdal 1.x implementation
+   * and GDALDriver::Create with (0,0) raster size for gdal 2.x
+   * implementation
+   * 
+   * \param driver Pointer to the driver used for creation. Will not
+   * be checked for null pointer.
+   *
+   * \param name Name of the dataset to create.
+   * 
+   * \return NULL if dataset could not be created.
+   */
+  GDALDatasetType * Create(GDALDriverType * driver, const char * name);
+
+
+  /**
+   * This function physically deletes an existing dataset.
+   * 
+   * Calls OGRDataSource::DeleteDataSource for gdal 1.x implementation
+   * and GDALDriver::Delete for gdal 2.x implementation.
+   *
+   * \param name Name of the dataset to destroy.
+   */ 
+  bool Delete(const char * name);
+
+  /**
+   * This function returns a pointer to the driver from its name.
+   * 
+   * Calls OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName() for
+   * gdal 1.x implementation and
+   * GetGDALDriverManager()->GetDriverByName() for gdal 2.x
+   * implementation.
+   * 
+   * \param name Name of the driver to retrieve
+   * 
+   * \return NULL if no driver could be retrieved.
+   */
+  GDALDriverType *  GetDriverByName(const char * name);
+
+  /**
+   * Sync dataset to disk.
+   *
+   * Calls OGRDataSource::SyncToDisk() for gdal 1.x implementation and
+   * GDALDataset::FlushCache() for gdal 2.x  implementation.
+   *
+   * \param dataset Pointer to the dataset to sync. Will not be
+   * checked for null pointer.
+   *
+   * \return True if sync went on without any error.
+   */
+  bool SyncToDisk(GDALDatasetType * dataset);
+
+  /**
+   * \return The name of the dataset class behind the implementation
+   * (OGRDataSource for gdal 1.x and GdalDataset for gdal 2.x)
+   */
+  std::string GetDatasetClassName();
+
+  /**
+   * \return The name of the driver class behind the implementation
+   * (OGRSFDriver for gdal 1.x and GDALDriver for gdal 2.x)
+   */
+  std::string GetDriverClassName();
+
+  /**
+   * Return the list of files composing the dataset.
+   * 
+   * Calls OGRDataSource::GetName() and wrap in string vector for gdal
+   * 1.x implementation, and GDALDataset::GetFileList and wrap in
+   * string vector for gdal 2.x implementation.
+   *  
+   * \param dataset Pointer to the dataset to get the file list from. Will not be
+   * checked for null pointer.
+   * 
+   * \return A vector of string containing the list of files.
+   */
+  std::vector<std::string> GetFileListAsStringVector(GDALDatasetType * dataset);
+
+  /** 
+   * Return the list of available drivers.
+   *
+   * Calls OGRSFDriverRegistrar::GetRegistrar() for gdal 1.x
+   * implementation and GetGDALDriverManager() for gdal 2.x
+   * implementation.
+   *
+   * \return A vector of string containing the list of available drivers.
+   */  
+  std::vector<std::string> GetAvailableDriversAsStringVector();
+
+}
+}
+} // end namespace otb
+
+#endif
diff --git a/Modules/Adapters/GdalAdapters/src/CMakeLists.txt b/Modules/Adapters/GdalAdapters/src/CMakeLists.txt
index 87e83c558e27b3f3dddf9c167eb7d81a46b66a84..a052f01656ce4b0090ff69f13b6f4a06b544c482 100644
--- a/Modules/Adapters/GdalAdapters/src/CMakeLists.txt
+++ b/Modules/Adapters/GdalAdapters/src/CMakeLists.txt
@@ -10,6 +10,12 @@ set(OTBGdalAdapters_SRC
   otbOGRDataSourceWrapper.cxx
   )
 
+if(OTB_USE_GDAL_20)
+  set(OTBGdalAdapters_SRC ${OTBGdalAdapters_SRC} otbOGRVersionProxy2x.cxx)
+else(Otb_use_gdal_20)
+  set(OTBGdalAdapters_SRC ${OTBGdalAdapters_SRC} otbOGRVersionProxy1x.cxx)
+endif(OTB_USE_GDAL_20)
+
 add_library(OTBGdalAdapters ${OTBGdalAdapters_SRC})
 target_link_libraries(OTBGdalAdapters 
   ${OTBBoost_LIBRARIES}
diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx
index d2be6f3652f70946a75a90cfb77183908f23c247..891c22b662caa6df44cf8d1c0b04507dbc4289d2 100644
--- a/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx
+++ b/Modules/Adapters/GdalAdapters/src/otbOGRDataSourceWrapper.cxx
@@ -34,7 +34,6 @@
 #include "otbOGRDriversInit.h"
 #include "otbSystem.h"
 // OGR includes
-#include "ogrsf_frmts.h"
 
 /*===========================================================================*/
 /*=======================[ construction/destruction ]========================*/
@@ -45,13 +44,13 @@ bool otb::ogr::DataSource::Clear()
   return true;
 }
 
-void otb::ogr::DataSource::Reset(OGRDataSource * source)
+void otb::ogr::DataSource::Reset(otb::ogr::version_proxy::GDALDatasetType * source)
 {
   if (m_DataSource) {
     // OGR makes a pointless check for non-nullity in
-    // OGRDataSource::DestroyDataSource (pointless because "delete 0" is
+    // GDALDataset::DestroyDataSource (pointless because "delete 0" is
     // perfectly valid -> it's a no-op)
-    OGRDataSource::DestroyDataSource(m_DataSource); // void, noexcept
+    ogr::version_proxy::Close(m_DataSource); // void, noexcept
   }
   m_DataSource = source;
 }
@@ -119,16 +118,15 @@ otb::ogr::DataSource::DataSource()
 {
   Drivers::Init();
 
-  OGRSFDriver * d = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName("Memory");
+  ogr::version_proxy::GDALDriverType * d = ogr::version_proxy::GetDriverByName("Memory");
   assert(d && "OGR Memory driver not found");
-  m_DataSource = d->CreateDataSource("in-memory");
+  m_DataSource = ogr::version_proxy::Create(d,"in-memory");
   if (!m_DataSource) {
     itkExceptionMacro(<< "Failed to create OGRMemDataSource: " << CPLGetLastErrorMsg());
   }
-  m_DataSource->SetDriver(d);
 }
 
-otb::ogr::DataSource::DataSource(OGRDataSource * source, Modes::type mode)
+otb::ogr::DataSource::DataSource(otb::ogr::version_proxy::GDALDatasetType * source, Modes::type mode)
 : m_DataSource(source),
   m_OpenMode(mode),
   m_FirstModifiableLayerID(0)
@@ -140,14 +138,14 @@ otb::ogr::DataSource::Pointer otb::ogr::DataSource::OpenDataSource(std::string c
 {
   bool update = (mode != Modes::Read);
 
-  OGRDataSource * source = OGRSFDriverRegistrar::Open(datasourceName.c_str(), update);
+  ogr::version_proxy::GDALDatasetType * source = ogr::version_proxy::Open(datasourceName.c_str(),!update);
   if (!source)
     {
     // In read mode, this is a failure
     // In write mode (Overwrite and Update), create the data source transparently
     if (mode == Modes::Read)
       {
-      itkGenericExceptionMacro(<< "Failed to open OGRDataSource file "
+      itkGenericExceptionMacro(<< "Failed to open GDALDataset file "
         << datasourceName<<" : " << CPLGetLastErrorMsg());
       }
 
@@ -159,48 +157,30 @@ otb::ogr::DataSource::Pointer otb::ogr::DataSource::OpenDataSource(std::string c
         <<datasourceName<<">.");
       }
 
-    OGRSFDriver * d = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName);
+    ogr::version_proxy::GDALDriverType * d = ogr::version_proxy::GetDriverByName(driverName);
 
     if(!d)
       {
       itkGenericExceptionMacro(<<"Could not create OGR driver "<<driverName<<", check your OGR configuration for available drivers.");
       }
 
-    source = d->CreateDataSource(datasourceName.c_str());
+    source = ogr::version_proxy::Create(d,datasourceName.c_str());
     if (!source) {
-      itkGenericExceptionMacro(<< "Failed to create OGRDataSource <"<<datasourceName
+      itkGenericExceptionMacro(<< "Failed to create GDALDataset <"<<datasourceName
         <<"> (driver name: <" << driverName<<">: " << CPLGetLastErrorMsg());
     }
-    source->SetDriver(d);
     }
   return otb::ogr::DataSource::New(source, mode);
 }
 
 void DeleteDataSource(std::string const& datasourceName)
 {
-  // Attempt to delete the datasource if it already exists
-  OGRDataSource * poDS = OGRSFDriverRegistrar::Open(datasourceName.c_str(), TRUE);
-
-  if (poDS != NULL)
+  bool ret = otb::ogr::version_proxy::Delete(datasourceName.c_str());
+  if (!ret)
     {
-    OGRSFDriver * ogrDriver = poDS->GetDriver();
-    OGRDataSource::DestroyDataSource(poDS);
-    //Erase the data if possible
-    if (ogrDriver->TestCapability(ODrCDeleteDataSource))
-      {
-      //Delete datasource
-      OGRErr ret = ogrDriver->DeleteDataSource(datasourceName.c_str());
-      if (ret != OGRERR_NONE)
-        {
-        itkGenericExceptionMacro(<< "Deletion of data source " << datasourceName
-                        << " failed: " << CPLGetLastErrorMsg());
-        }
-      }
-    else
-      {
-      itkGenericExceptionMacro(<< "Cannot delete data source " << datasourceName);
-      }
-    } // if (poDS != NULL)
+    itkGenericExceptionMacro(<< "Deletion of data source " << datasourceName
+                             << " failed: " << CPLGetLastErrorMsg());
+    }
 }
 
 otb::ogr::DataSource::Pointer
@@ -213,7 +193,14 @@ otb::ogr::DataSource::New(std::string const& datasourceName, Modes::type mode)
 
   Drivers::Init();
 
-  if (mode == Modes::Overwrite)
+  ogr::version_proxy::GDALDatasetType * ds = ogr::version_proxy::Open(datasourceName.c_str(),true);
+
+  bool ds_exists = (ds!=NULL);
+
+  ogr::version_proxy::Close(ds);
+  
+
+  if (ds_exists && mode == Modes::Overwrite)
     {
     DeleteDataSource(datasourceName);
     }
@@ -223,7 +210,7 @@ otb::ogr::DataSource::New(std::string const& datasourceName, Modes::type mode)
 
 /*static*/
 otb::ogr::DataSource::Pointer
-otb::ogr::DataSource::New(OGRDataSource * source, Modes::type mode)
+otb::ogr::DataSource::New(otb::ogr::version_proxy::GDALDatasetType * source, Modes::type mode)
 {
   Pointer res = new DataSource(source, mode);
   res->UnRegister();
@@ -271,7 +258,7 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer(
   if (m_OpenMode == Modes::Read)
     {
     otb::ogr::Layer l = GetLayerChecked(name); // will throw if not existing
-    itkGenericOutputMacro(<< "Requesting layer creation in read-only OGRDataSource. Returning the existing layer");
+    itkGenericOutputMacro(<< "Requesting layer creation in read-only GDALDataset. Returning the existing layer");
     return l;
     }
 
@@ -292,9 +279,9 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer(
     OGRLayer * ol = m_DataSource->CreateLayer(
       name.c_str(), poSpatialRef, eGType, otb::ogr::StringListConverter(papszOptions).to_ogr());
     if (!ol)
-      {
+      { 
       itkGenericExceptionMacro(<< "Failed to create the layer <"<<name
-        << "> in the OGRDataSource file <" << m_DataSource->GetName()
+                               << "> in the GDALDataset file <" << GetDatasetDescription()
         <<">: " << CPLGetLastErrorMsg());
       }
 
@@ -317,7 +304,7 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer(
       if (!ol)
         {
         itkGenericExceptionMacro(<< "Failed to create the layer <"<<name
-          << "> in the OGRDataSource file <" << m_DataSource->GetName()
+                                 << "> in the GDALDataset file <" <<  GetDatasetDescription()
           <<">: " << CPLGetLastErrorMsg());
         }
 
@@ -329,7 +316,7 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer(
   case Modes::Update_LayerCreateOnly:
     {
     // The layer exists. Returns it
-    // It will be non-modifiable if already existing at OGRDataSource creation time
+    // It will be non-modifiable if already existing at GDALDataset creation time
     if (layer)
       {
       return layer;
@@ -341,7 +328,7 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer(
     if (!ol)
       {
       itkGenericExceptionMacro(<< "Failed to create the layer <"<<name
-        << "> in the OGRDataSource file <" << m_DataSource->GetName()
+                               << "> in the GDALDataset file <" <<  GetDatasetDescription()
         <<">: " << CPLGetLastErrorMsg());
       }
 
@@ -351,11 +338,11 @@ otb::ogr::Layer otb::ogr::DataSource::CreateLayer(
     break;
   default :
     assert(false && "Should never be there");
-    itkGenericExceptionMacro(<< "OGRDataSource opening mode not supported");
+    itkGenericExceptionMacro(<< "GDALDataset opening mode not supported");
     break;
   }
 
-  itkGenericExceptionMacro(<< "OGRDataSource opening mode not supported");
+  itkGenericExceptionMacro(<< "GDALDataset opening mode not supported");
   return Layer(0, false); // keep compiler happy
 }
 
@@ -369,11 +356,11 @@ otb::ogr::Layer otb::ogr::DataSource::CopyLayer(
   switch (m_OpenMode)
   {
     case Modes::Invalid:
-      assert(false && "Invalid OGRDataSource opening mode");
-      itkGenericExceptionMacro(<< "Invalid OGRDataSource opening mode");
+      assert(false && "Invalid GDALDataset opening mode");
+      itkGenericExceptionMacro(<< "Invalid GDALDataset opening mode");
       break;
     case Modes::Read:
-      itkGenericExceptionMacro(<< "OGRDataSource is opened in Read mode : cannot create a layer");
+      itkGenericExceptionMacro(<< "GDALDataset is opened in Read mode : cannot create a layer");
       break;
     default:
       break;
@@ -382,10 +369,10 @@ otb::ogr::Layer otb::ogr::DataSource::CopyLayer(
   OGRLayer * l0 = &srcLayer.ogr();
   OGRLayer * ol = m_DataSource->CopyLayer(l0, newName.c_str(), papszOptions);
   if (!ol)
-    {
+    {    
     itkGenericExceptionMacro(<< "Failed to copy the layer <"
       << srcLayer.GetName() << "> into the new layer <" <<newName
-      << "> in the OGRDataSource file <" << m_DataSource->GetName()
+                             << "> in the GDALDataset file <" <<  GetDatasetDescription()
       <<">: " << CPLGetLastErrorMsg());
     }
   const bool modifiable = true;
@@ -400,14 +387,14 @@ void otb::ogr::DataSource::DeleteLayer(size_t i)
   switch (m_OpenMode)
   {
     case Modes::Invalid:
-      assert(false && "Invalid OGRDataSource opening mode");
-      itkGenericExceptionMacro(<< "Invalid OGRDataSource opening mode");
+      assert(false && "Invalid GDALDataset opening mode");
+      itkGenericExceptionMacro(<< "Invalid GDALDataset opening mode");
       break;
     case Modes::Read:
-      itkGenericExceptionMacro(<< "OGRDataSource is opened in Read mode : cannot delete a layer");
+      itkGenericExceptionMacro(<< "GDALDataset is opened in Read mode : cannot delete a layer");
       break;
     case Modes::Update_LayerCreateOnly:
-      itkGenericExceptionMacro(<< "OGRDataSource is opened in Update_LayerCreateOnly mode : cannot delete a layer");
+      itkGenericExceptionMacro(<< "GDALDataset is opened in Update_LayerCreateOnly mode : cannot delete a layer");
       break;
     default:
       break;
@@ -415,15 +402,15 @@ void otb::ogr::DataSource::DeleteLayer(size_t i)
 
   const int nb_layers = GetLayersCount();
   if (int(i) >= nb_layers)
-    {
-    itkExceptionMacro(<< "Cannot delete " << i << "th layer in the OGRDataSource <"
-      << m_DataSource->GetName() << "> as it contains only " << nb_layers << "layers.");
+    {      
+    itkExceptionMacro(<< "Cannot delete " << i << "th layer in the GDALDataset <"
+                      <<  GetDatasetDescription() << "> as it contains only " << nb_layers << "layers.");
     }
   const OGRErr err = m_DataSource->DeleteLayer(int(i));
   if (err != OGRERR_NONE)
     {
-    itkExceptionMacro(<< "Cannot delete " << i << "th layer in the OGRDataSource <"
-      << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg());
+    itkExceptionMacro(<< "Cannot delete " << i << "th layer in the GDALDataset <"
+                      <<  GetDatasetDescription() << ">: " << CPLGetLastErrorMsg());
     }
 }
 
@@ -478,9 +465,9 @@ size_t otb::ogr::DataSource::GetLayerID(std::string const& name) const
 {
   int const id = GetLayerIDUnchecked(name);
   if (id < 0)
-    {
+    {    
     itkExceptionMacro( << "Cannot fetch any layer named <" << name
-      << "> in the OGRDataSource <" << m_DataSource->GetName() << ">: "
+                       << "> in the GDALDataset <" <<  GetDatasetDescription() << ">: "
       << CPLGetLastErrorMsg());
     }
   return 0; // keep compiler happy
@@ -491,15 +478,15 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(size_t i)
   assert(m_DataSource && "Datasource not initialized");
   const int nb_layers = GetLayersCount();
   if (int(i) >= nb_layers)
-    {
-    itkExceptionMacro(<< "Cannot fetch " << i << "th layer in the OGRDataSource <"
-      << m_DataSource->GetName() << "> as it contains only " << nb_layers << "layers.");
+    {    
+    itkExceptionMacro(<< "Cannot fetch " << i << "th layer in the GDALDataset <"
+                      << GetDatasetDescription() << "> as it contains only " << nb_layers << "layers.");
     }
   OGRLayer * layer_ptr = m_DataSource->GetLayer(int(i));
   if (!layer_ptr)
     {
-    itkExceptionMacro( << "Unexpected error: cannot fetch " << i << "th layer in the OGRDataSource <"
-      << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg());
+    itkExceptionMacro( << "Unexpected error: cannot fetch " << i << "th layer in the GDALDataset <"
+                       << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg());
     }
   return otb::ogr::Layer(layer_ptr, IsLayerModifiable(i));
 }
@@ -525,7 +512,7 @@ otb::ogr::Layer otb::ogr::DataSource::GetLayerChecked(std::string const& name)
   if (!layer_ptr)
     {
     itkExceptionMacro( << "Cannot fetch any layer named <" << name
-      << "> in the OGRDataSource <" << m_DataSource->GetName() << ">: "
+      << "> in the GDALDataset <" << GetDatasetDescription() << ">: "
       << CPLGetLastErrorMsg());
     }
   return otb::ogr::Layer(layer_ptr, IsLayerModifiable(name));
@@ -550,10 +537,10 @@ otb::ogr::Layer otb::ogr::DataSource::ExecuteSQL(
     {
 #if defined(PREFER_EXCEPTION)
     itkExceptionMacro( << "Unexpected error: cannot execute the SQL request <" << statement
-      << "> in the OGRDataSource <" << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg());
+      << "> in the GDALDataset <" <<  GetDatasetDescription() << ">: " << CPLGetLastErrorMsg());
 #else
     // Cannot use the deleter made for result sets obtained from
-    // OGRDataSource::ExecuteSQL because it checks for non-nullity....
+    // GDALDataset::ExecuteSQL because it checks for non-nullity....
     // *sigh*
     return otb::ogr::Layer(0, modifiable);
 #endif
@@ -699,10 +686,22 @@ bool otb::ogr::DataSource::HasCapability(std::string const& capabilityName) cons
 void otb::ogr::DataSource::SyncToDisk()
 {
   assert(m_DataSource && "Datasource not initialized");
-  const OGRErr res= m_DataSource->SyncToDisk();
-  if (res != OGRERR_NONE)
+  bool ret = otb::ogr::version_proxy::SyncToDisk(m_DataSource);
+
+  if(!ret)
     {
     itkExceptionMacro( << "Cannot flush the pending of the OGRDataSource <"
-      << m_DataSource->GetName() << ">: " << CPLGetLastErrorMsg());
+                       << GetDatasetDescription() << ">: " << CPLGetLastErrorMsg());
     }
 }
+
+
+std::string otb::ogr::DataSource::GetDatasetDescription() const
+{
+  std::vector<std::string> files = otb::ogr::version_proxy::GetFileListAsStringVector(m_DataSource);
+  std::string description = "";
+  for(std::vector<std::string>::const_iterator it = files.begin();it!=files.end();++it)
+    description+=(*it)+", ";
+
+  return description;
+}
diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRLayerWrapper.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRLayerWrapper.cxx
index 6942ef41a8b4f1916fd99592736d58468a4511f2..9a9aa525bba80edc004bba95df091291a3fe38fe 100644
--- a/Modules/Adapters/GdalAdapters/src/otbOGRLayerWrapper.cxx
+++ b/Modules/Adapters/GdalAdapters/src/otbOGRLayerWrapper.cxx
@@ -27,10 +27,10 @@
 #ifdef __GNUC__
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wshadow"
-#include "ogrsf_frmts.h" // OGRDataSource & OGRLayer
+#include "gdal_priv.h"// GDALDataset
 #pragma GCC diagnostic pop
 #else
-#include "ogrsf_frmts.h" // OGRDataSource & OGRLayer
+#include "gdal_priv.h" // GDALDataset
 #endif
 
 #include "otbOGRDataSourceWrapper.h"
@@ -60,8 +60,8 @@ otb::ogr::Layer::Layer(OGRLayer* layer, bool modifiable)
 {
 }
 
-otb::ogr::Layer::Layer(OGRLayer* layer, OGRDataSource& sourceInChargeOfLifeTime, bool modifiable)
-:   m_Layer(layer,  boost::bind(&OGRDataSource::ReleaseResultSet, boost::ref(sourceInChargeOfLifeTime), _1))
+otb::ogr::Layer::Layer(OGRLayer* layer, otb::ogr::version_proxy::GDALDatasetType& sourceInChargeOfLifeTime, bool modifiable)
+:   m_Layer(layer,  boost::bind(&otb::ogr::version_proxy::GDALDatasetType::ReleaseResultSet, boost::ref(sourceInChargeOfLifeTime), _1))
   , m_Modifiable(modifiable)
 {
   assert(layer && "A null OGRlayer cannot belong to an OGRDataSource" );
diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy1x.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy1x.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f92ee6e1dfd4a1e1784421369a867b56c76441c3
--- /dev/null
+++ b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy1x.cxx
@@ -0,0 +1,124 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "otbOGRVersionProxy.h"
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include "ogrsf_frmts.h"
+#pragma GCC diagnostic pop
+#else
+#include "ogrsf_frmts.h"
+#endif
+
+namespace otb
+{
+namespace ogr
+{
+namespace version_proxy
+{
+
+GDALDatasetType * Open(const char * filename, bool readOnly)
+{
+  return OGRSFDriverRegistrar::Open(filename,!readOnly);
+}
+
+void Close(GDALDatasetType * dataset)
+{
+  OGRDataSource::DestroyDataSource(dataset);
+}
+  
+GDALDatasetType * Create(GDALDriverType * driver, const char * name)
+{
+  GDALDatasetType * ds = driver->CreateDataSource(name);
+
+  if(ds)  
+    ds->SetDriver(driver);
+  
+  return ds;
+}
+
+bool Delete(const char * name)
+{
+  // Open dataset
+  GDALDatasetType * poDS = Open(name,false);
+  GDALDriverType * poDriver = NULL;
+  if(poDS)
+    {
+    poDriver = poDS->GetDriver();
+    Close(poDS);
+    }
+
+  if(poDriver && poDriver->TestCapability(ODrCDeleteDataSource))
+    {
+    
+    OGRErr ret = poDriver->DeleteDataSource(name);
+    return (ret == OGRERR_NONE);
+    }
+
+  return false;
+}
+
+GDALDriverType *  GetDriverByName(const char * name)
+{
+  return OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(name);
+}
+
+std::string GetDatasetClassName()
+{
+  return std::string("OGRDataSource");
+}
+
+std::string GetDriverClassName()
+{
+  return std::string("OGRSFDriver");
+}
+
+std::vector<std::string> GetFileListAsStringVector(GDALDatasetType * dataset)
+{
+  std::vector<std::string> ret;
+
+  ret.push_back(std::string(dataset->GetName()));
+  
+  return ret;
+}
+
+bool SyncToDisk(GDALDatasetType * dataset)
+{
+  const OGRErr res= dataset->SyncToDisk();
+
+  return (res == OGRERR_NONE);
+}
+
+std::vector<std::string> GetAvailableDriversAsStringVector()
+{
+  std::vector<std::string> ret;
+  
+  int nbDrivers = OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
+  
+  for(int i = 0; i < nbDrivers;++i)
+    {
+    ret.push_back(OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i)->GetName());
+    }
+
+  return ret;
+}
+
+}
+}
+} // end namespace
diff --git a/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy2x.cxx b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy2x.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..725486f4b74758e60b880cf8d38906dff85a9ead
--- /dev/null
+++ b/Modules/Adapters/GdalAdapters/src/otbOGRVersionProxy2x.cxx
@@ -0,0 +1,157 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "otbOGRVersionProxy.h"
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include "gdal_priv.h"
+#pragma GCC diagnostic pop
+#else
+#include "gdal_priv.h"
+#endif
+
+
+namespace otb
+{
+namespace ogr
+{
+namespace version_proxy
+{
+
+GDALDatasetType * Open(const char * filename, bool readOnly)
+{
+  return (GDALDatasetType *)GDALOpenEx(filename, (readOnly? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR,NULL,NULL,NULL);
+}
+
+void Close(GDALDatasetType * dataset)
+{
+  GDALClose(dataset);
+}
+  
+GDALDatasetType * Create(GDALDriverType * driver, const char * name)
+{
+  return driver->Create(name,0,0,0,GDT_Unknown,NULL);
+}
+
+bool Delete(const char * name)
+{
+  // Open dataset
+  GDALDatasetType * poDS = otb::ogr::version_proxy::Open(name,false);
+  GDALDriverType * poDriver = NULL;
+  if(poDS)
+    {
+    poDriver = poDS->GetDriver();
+    Close(poDS);
+    }
+
+  if(poDriver)
+    {
+    OGRErr ret = poDriver->Delete(name);
+
+    return (ret == OGRERR_NONE);
+    }
+  return false;
+}
+
+GDALDriverType *  GetDriverByName(const char * name)
+{
+  return GetGDALDriverManager()->GetDriverByName(name);
+}
+
+std::string GetDatasetClassName()
+{
+  return std::string("GDALDataset");
+}
+
+std::string GetDriverClassName()
+{
+  return std::string("GDALDriver");
+}
+
+namespace raii
+{
+// This class is used in the next function, so as to prevent any
+// ressource leak on char ** returned by dataset->GetFileList()
+class CharPPCapsule
+{
+public:
+  CharPPCapsule(char ** in)
+    : m_P(in)
+  {}
+
+  const char ** P() const
+  {
+    return const_cast<const char **>(m_P);
+  }
+  
+  ~CharPPCapsule()
+  {
+    if(m_P)
+      CSLDestroy(m_P);
+  }
+
+private:
+  char ** m_P;
+};
+}
+
+std::vector<std::string> GetFileListAsStringVector(GDALDatasetType * dataset)
+{
+  std::vector<std::string> ret;
+  
+  raii::CharPPCapsule capsule(dataset->GetFileList());
+
+  std::string files_str="";
+      
+  if(capsule.P())
+    {
+    unsigned int i = 0;
+    while(capsule.P()[i]!=NULL)
+      {
+      ret.push_back(std::string(capsule.P()[i]));
+      ++i;
+      } 
+    }
+  return ret;
+}
+
+bool SyncToDisk(GDALDatasetType * dataset)
+{
+  dataset->FlushCache();
+
+  return true;
+}
+
+std::vector<std::string> GetAvailableDriversAsStringVector()
+{
+  std::vector<std::string> ret;
+  
+  int nbDrivers = GetGDALDriverManager()->GetDriverCount();
+  
+  for(int i = 0; i < nbDrivers;++i)
+    {
+    ret.push_back(GDALGetDriverShortName(GetGDALDriverManager()->GetDriver(i)));
+    }
+
+  return ret;
+}
+
+}
+}
+} // end namespace
diff --git a/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx
index 2449029c861368d5d34121d875608b009e79a530..fa327c4a6dd3abce4299130b3755d20c92ac99b8 100644
--- a/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx
+++ b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx
@@ -20,6 +20,10 @@
 
 #include "otbImageToNoDataMaskFilter.h"
 #include "otbChangeNoDataValueFilter.h"
+#include "itkMaskImageFilter.h"
+#include "otbVectorImageToImageListFilter.h"
+#include "otbImageListToVectorImageFilter.h"
+#include "otbChangeInformationImageFilter.h"
 
 namespace otb
 {
@@ -44,6 +48,12 @@ public:
   typedef otb::ImageToNoDataMaskFilter<FloatVectorImageType,UInt8ImageType> FilterType;
   typedef otb::ChangeNoDataValueFilter<FloatVectorImageType,FloatVectorImageType> ChangeNoDataFilterType;
   
+  typedef otb::ImageList<FloatImageType> ImageListType;
+  typedef otb::VectorImageToImageListFilter<FloatVectorImageType,ImageListType> VectorToListFilterType;
+  typedef otb::ImageListToVectorImageFilter<ImageListType,FloatVectorImageType> ListToVectorFilterType;
+  typedef itk::MaskImageFilter<FloatImageType,UInt8ImageType,FloatImageType> MaskFilterType;
+  typedef otb::ChangeInformationImageFilter<FloatVectorImageType> ChangeInfoFilterType;
+
 private:
   void DoInit()
   {
@@ -89,8 +99,14 @@ private:
     SetParameterDescription("mode.changevalue.newv","The new no-data value");
     SetDefaultParameterInt("mode.changevalue.newv",0);
 
+    AddChoice("mode.apply","Apply a mask as no-data");
+
+    SetParameterDescription("mode.apply","Apply an external mask to an image using the no-data value of the input image");
+    AddParameter(ParameterType_InputImage, "mode.apply.mask", "Mask image");
+    SetParameterDescription("mode.apply.mask","Mask to be applied on input image (valid pixels have non null values)");
+
     SetParameterString("mode","buildmask");
-    
+
     AddRAMParameter();
 
     // Doc example parameter settings
@@ -132,10 +148,66 @@ private:
       {
       SetParameterOutputImage("out",m_ChangeNoDataFilter->GetOutput());
       }
+    else if (GetParameterString("mode") == "apply")
+      {
+      m_MaskFilters.clear();
+      UInt8ImageType::Pointer maskPtr = this->GetParameterImage<UInt8ImageType>("mode.apply.mask");
+      unsigned int nbBands = inputPtr->GetNumberOfComponentsPerPixel();
+      itk::MetaDataDictionary &dict = inputPtr->GetMetaDataDictionary();
+      std::vector<bool> flags;
+      std::vector<double> values;
+      bool ret = otb::ReadNoDataFlags(dict,flags,values);
+      if (!ret)
+        {
+        flags.resize(nbBands,true);
+        values.resize(nbBands,0.0);
+        }
+
+      m_V2L = VectorToListFilterType::New();
+      m_V2L->SetInput(inputPtr);
+      ImageListType::Pointer inputList = m_V2L->GetOutput();
+      inputList->UpdateOutputInformation();
+      ImageListType::Pointer outputList = ImageListType::New();
+      for (unsigned int i=0 ; i<nbBands ; ++i)
+        {
+        if (flags[i])
+          {
+          MaskFilterType::Pointer masker = MaskFilterType::New();
+          masker->SetInput(inputList->GetNthElement(i));
+          masker->SetMaskImage(maskPtr);
+          masker->SetMaskingValue(0);
+          masker->SetOutsideValue(values[i]);
+          outputList->PushBack(masker->GetOutput());
+          m_MaskFilters.push_back(masker);
+          }
+        else
+          {
+          outputList->PushBack(inputList->GetNthElement(i));
+          }
+        }
+      m_L2V = ListToVectorFilterType::New();
+      m_L2V->SetInput(outputList);
+      if (!ret)
+        {
+        m_MetaDataChanger = ChangeInfoFilterType::New();
+        m_MetaDataChanger->SetInput(m_L2V->GetOutput());
+        m_MetaDataChanger->SetOutputMetaData<std::vector<bool> >(otb::MetaDataKey::NoDataValueAvailable,&flags);
+        m_MetaDataChanger->SetOutputMetaData<std::vector<double> >(otb::MetaDataKey::NoDataValue,&values);
+        SetParameterOutputImage("out",m_MetaDataChanger->GetOutput());
+        }
+      else
+        {
+        SetParameterOutputImage("out",m_L2V->GetOutput());
+        }
+      }
   }
 
   FilterType::Pointer m_Filter;
   ChangeNoDataFilterType::Pointer m_ChangeNoDataFilter;
+  std::vector<MaskFilterType::Pointer> m_MaskFilters;
+  VectorToListFilterType::Pointer m_V2L;
+  ListToVectorFilterType::Pointer m_L2V;
+  ChangeInfoFilterType::Pointer m_MetaDataChanger;
 };
 
 }
diff --git a/Modules/Applications/AppSARCalibration/app/otbSarRadiometricCalibration.cxx b/Modules/Applications/AppSARCalibration/app/otbSarRadiometricCalibration.cxx
index b3068c927ac1452f6b48af361950def7f55d29fb..3aa03c21a0f7bfc511697246794bf35695ae6300 100644
--- a/Modules/Applications/AppSARCalibration/app/otbSarRadiometricCalibration.cxx
+++ b/Modules/Applications/AppSARCalibration/app/otbSarRadiometricCalibration.cxx
@@ -24,7 +24,6 @@ namespace otb
 {
 namespace Wrapper
 {
-
 class SarRadiometricCalibration : public Application
 {
 public:
@@ -40,17 +39,17 @@ public:
   itkTypeMacro(SarRadiometricCalibration, otb::Application);
 
   typedef otb::SarRadiometricCalibrationToImageFilter<ComplexFloatImageType,
-                                                      ComplexFloatImageType>     CalibrationFilterType;
+                                                      FloatImageType>     CalibrationFilterType;
 
 private:
   void DoInit()
   {
     SetName("SarRadiometricCalibration");
-    SetDescription("Perform SAR calibration on input complex images");
+    SetDescription("Perform radiometric calibration of SAR images. Following sensors are supported: TerraSAR-X, Sentinel1 and Radarsat-2.Both Single Look Complex(SLC) and detected products are supported as input.\n");
 
     // Documentation
     SetDocName("SAR Radiometric calibration");
-    SetDocLongDescription("This application performs SAR calibration on input complex images.");
+    SetDocLongDescription("The objective of SAR calibration is to provide imagery in which the pixel values can be directly related to the radar backscatter of the scene. This application allows to compute Sigma Naught (Radiometric Calibration) for TerraSAR-X, Sentinel1 L1 and Radarsat-2 sensors. Metadata are automatically retrieved from image products.The application supports complex and non-complex images (SLC or detected products).\n");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso(" ");
@@ -58,25 +57,39 @@ private:
     AddDocTag(Tags::Calibration);
     AddDocTag(Tags::SAR);
 
-    AddParameter(ParameterType_ComplexInputImage,  "in", "Input Complex Image");
+    AddParameter(ParameterType_ComplexInputImage,  "in", "Input Image");
     SetParameterDescription("in", "Input complex image");
 
-    AddParameter(ParameterType_ComplexOutputImage,  "out", "Output Image");
-    SetParameterDescription("out", "Output calibrated complex image");
+    AddParameter(ParameterType_OutputImage,  "out", "Output Image");
+    SetParameterDescription("out", "Output calibrated image. This image contains the backscatter (sigmaNought) of the input image.");
 
     AddRAMParameter();
 
     AddParameter(ParameterType_Empty, "noise", "Disable Noise");
-    SetParameterDescription("noise", "Flag to disable noise");
+    SetParameterDescription("noise", "Flag to disable noise. For 5.2.0 release, the noise values are only read by TerraSARX product.");
     MandatoryOff("noise");
 
+    AddParameter(ParameterType_Choice, "lut", "Lookup table sigma /gamma/ beta/ DN.");
+    SetParameterDescription("lut", "Lookup table values are not available with all SAR products. Products that provide lookup table with metadata are: Sentinel1, Radarsat2.");
+    AddChoice("lut.sigma", "Use sigma nought lookup");
+    SetParameterDescription("lut.sigma","Use Sigma nought lookup value from product metadata");
+    AddChoice("lut.gamma", "Use gamma nought lookup");
+    SetParameterDescription("lut.gamma","Use Gamma nought lookup value from product metadata");
+    AddChoice("lut.beta", "Use beta nought lookup");
+    SetParameterDescription("lut.beta","Use Beta nought lookup value from product metadata");
+    AddChoice("lut.dn", "Use DN value lookup");
+    SetParameterDescription("lut.dn","Use DN value lookup value from product metadata");
+    SetDefaultParameterInt("lut", 0);
+
     // Doc example parameter settings
     SetDocExampleParameterValue("in", "RSAT_imagery_HH.tif");
     SetDocExampleParameterValue("out", "SarRadiometricCalibration.tif" );
   }
 
   void DoUpdateParameters()
-  { }
+  {
+
+  }
 
   void DoExecute()
   {
@@ -92,11 +105,19 @@ private:
       m_CalibrationFilter->SetEnableNoise(false);
       }
 
+    short lut = 0;
+
+    lut = GetParameterInt("lut");
+
+    m_CalibrationFilter->SetLookupSelected(lut);
+
     // Set the output image
-    SetParameterComplexOutputImage("out", m_CalibrationFilter->GetOutput());
+    SetParameterOutputImage("out", m_CalibrationFilter->GetOutput());
+
   }
 
   CalibrationFilterType::Pointer   m_CalibrationFilter;
+
 };
 }
 }
diff --git a/Modules/Applications/AppSARCalibration/test/CMakeLists.txt b/Modules/Applications/AppSARCalibration/test/CMakeLists.txt
index 285dd10621352c2af1047c31a52db69076a4e299..02e9e48f3f4e073a84a970187f66ba67e308842a 100644
--- a/Modules/Applications/AppSARCalibration/test/CMakeLists.txt
+++ b/Modules/Applications/AppSARCalibration/test/CMakeLists.txt
@@ -1,2 +1,17 @@
 otb_module_test()
 #----------- SarRadiometricCalibration TESTS ----------------
+otb_test_application(NAME apTvRaSarRadiometricCalibration_SENTINEL1
+  APP  SarRadiometricCalibration
+  OPTIONS -in ${INPUTDATA}/SENTINEL1_SLC_S6_1S_extract_300_300.tif?&geom=${INPUTDATA}/SENTINEL1_SLC_S6_1S_extract_300_300.geom
+  -out ${TEMP}/apTvRaSarRadiometricCalibration_SENTINEL1.tif
+  VALID   --compare-image ${NOTOL}
+  ${BASELINE}/raTvSarRadiometricCalibration_SENTINEL1.tif
+  ${TEMP}/apTvRaSarRadiometricCalibration_SENTINEL1.tif )
+
+otb_test_application(NAME apTvRaSarRadiometricCalibration_RADARSAT2
+  APP  SarRadiometricCalibration
+  OPTIONS -in ${INPUTDATA}/RADARSAT2_ALTONA_300_300_VV.tif?&geom=${INPUTDATA}/RADARSAT2_ALTONA_300_300_VV.geom
+  -out ${TEMP}/apTvRaSarRadiometricCalibration_RADARSAT2.tif
+  VALID   --compare-image ${NOTOL}
+  ${BASELINE}/raTvSarRadiometricCalibration_RADARSAT2.tif
+  ${TEMP}/apTvRaSarRadiometricCalibration_RADARSAT2.tif )
diff --git a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
index dfd43a4514a265c352445b999e6fedb307f74487..8015f13648a5a337870a91b3f22f6f47cdcfd6f4 100644
--- a/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
+++ b/Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
@@ -675,7 +675,8 @@ private:
        //and recomputed FID for each features (without holes).
         //Note : the GetDriver() Method has not been encapsulated in otb::ogr::DataSource,
         //so we must access the OGR pointer by using .ogr()
-       std::string driverName(ogrDS->ogr().GetDriver()->GetName());
+
+        std::string driverName(ogrDS->ogr().GetDriver()->GetName());
        if ( driverName.find("ESRI Shapefile") != std::string::npos)
          {
            otbAppLogINFO(<<"REPACK the Shapefile ..."<<std::endl);
diff --git a/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx b/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
index 01dc19cdbb019791042345d3c05e593c0b48f0a6..1fbaf04a5943511a562c4b80e7874ee9d798126f 100644
--- a/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
+++ b/Modules/Applications/AppTest/test/otbWrapperApplicationDocTests.cxx
@@ -39,7 +39,6 @@ int otbWrapperApplicationDocTest(int argc, char* argv[])
     std::copy(argv + 1, argv + argc, std::back_inserter(modulePathList));
 
     // Load the path in the environment
-    std::string specificEnv("ITK_AUTOLOAD_PATH=");
     std::list<std::string>::const_iterator it = modulePathList.begin();
     while( it != modulePathList.end() )
       {
diff --git a/Modules/Core/Common/src/otbConfigure.h.in b/Modules/Core/Common/src/otbConfigure.h.in
index 29555ad72a89c3d8879787b6f87b5a8c77aca532..38ac5b8a48a1df786fac99d4f7d03352fa51dfcc 100644
--- a/Modules/Core/Common/src/otbConfigure.h.in
+++ b/Modules/Core/Common/src/otbConfigure.h.in
@@ -17,3 +17,4 @@
 /* Show developper debug messages */
 #cmakedefine OTB_SHOW_ALL_MSG_DEBUG
 
+#cmakedefine OTB_USE_GDAL_20
diff --git a/Modules/Core/Metadata/include/otbRadarsat2ImageMetadataInterface.h b/Modules/Core/Metadata/include/otbRadarsat2ImageMetadataInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..46439ca65227e1671ad6cfb565d2a0c6786da27b
--- /dev/null
+++ b/Modules/Core/Metadata/include/otbRadarsat2ImageMetadataInterface.h
@@ -0,0 +1,203 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbRadarsat2ImageMetadataInterface_h
+#define __otbRadarsat2ImageMetadataInterface_h
+
+#include "otbSarImageMetadataInterface.h"
+
+namespace otb
+{
+/** \class Radarsat2ImageMetadataInterface
+ *
+ * \brief Creation of an "otb" Radarsat2ImageMetadataInterface that gets metadata.
+ *
+ *
+ * \ingroup OTBMetadata
+ */
+
+class ITK_ABI_EXPORT Radarsat2ImageMetadataInterface : public SarImageMetadataInterface
+{
+public:
+
+  typedef Radarsat2ImageMetadataInterface    Self;
+  typedef SarImageMetadataInterface         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(Radarsat2ImageMetadataInterface, SarImageMetadataInterface);
+
+  typedef Superclass::ImageType                ImageType;
+  typedef Superclass::MetaDataDictionaryType   MetaDataDictionaryType;
+  typedef Superclass::VectorType               VectorType;
+  typedef Superclass::VariableLengthVectorType VariableLengthVectorType;
+  typedef Superclass::ImageKeywordlistType     ImageKeywordlistType;
+  typedef Superclass::LookupDataPointerType LookupDataPointerType;
+//  typedef Radarsat2CalibrationLookupData::Pointer          LookupDataPointerType;
+
+  /*ImageMetadataInterfaceBase pure virtuals */
+  /** Get the imaging production day from the ossim metadata : DATASET_PRODUCTION_DATE metadata variable */
+  int GetProductionDay() const;
+
+  /** Get the imaging production month from the ossim metadata : DATASET_PRODUCTION_DATE metadata variable */
+  int GetProductionMonth() const;
+
+  /** Get the imaging production year from the ossim metadata : DATASET_PRODUCTION_DATE metadata variable */
+  int GetProductionYear() const;
+
+  /** check sensor ID */
+  bool CanRead() const;
+
+  int GetDay() const;
+
+  int GetMonth() const;
+
+  int GetYear() const;
+
+  int GetHour() const;
+
+  int GetMinute() const;
+
+  UIntVectorType GetDefaultDisplay() const;
+
+  /*SarImageMetadataInterface pure virutals rituals */
+  double GetPRF() const;
+
+  double GetRSF() const;
+
+  double GetRadarFrequency() const;
+
+  double GetCenterIncidenceAngle() const;
+
+  /*get lookup data for calulating backscatter */
+  void CreateCalibrationLookupData(const short type);
+
+
+protected:
+  /* class constructor */
+  Radarsat2ImageMetadataInterface();
+
+  /* class desctructor */
+  virtual ~Radarsat2ImageMetadataInterface() {}
+
+private:
+  Radarsat2ImageMetadataInterface(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+/* Helper function to parse date and time into a std::vector<std::string>
+ * using boost::split() expect date time in yyyy-mm-ddThh:mm:ss.ms
+ * the date-time string is to be found in keywordlist with key 'key'
+ * fills argument dateFields of type std::vector<std::string> which is mutable!
+ * TODO: move this method into base class
+ */
+  void ParseDateTime(const char* key, std::vector<int>& dateFields) const;
+
+  mutable std::vector<int> m_ProductionDateFields;
+  mutable std::vector<int> m_AcquisitionDateFields;
+
+};
+
+
+class Radarsat2CalibrationLookupData : public SarCalibrationLookupData
+{
+
+public:
+
+  /** Standard typedefs */
+  typedef Radarsat2CalibrationLookupData   Self;
+  typedef SarCalibrationLookupData         Superclass;
+  typedef itk::SmartPointer<Self>          Pointer;
+  typedef itk::SmartPointer<const Self>    ConstPointer;
+
+  /** Creation through the object factory */
+  itkNewMacro(Self);
+
+  /** RTTI */
+  itkTypeMacro(Radarsat2CalibrationLookupData, SarCalibrationLookupData);
+
+  typedef itk::IndexValueType IndexValueType;
+
+  typedef std::vector<float> GainListType;
+
+
+  Radarsat2CalibrationLookupData()
+    : m_Offset(0)
+  {
+
+  }
+
+  virtual ~Radarsat2CalibrationLookupData()
+  {
+
+  }
+
+  void InitParameters(short type, int offset,  GainListType gains)
+  {
+    this->SetType(type);
+    m_Offset = offset;
+    m_Gains = gains;
+  }
+
+  double GetValue(const IndexValueType x, const IndexValueType itkNotUsed(y))
+  {
+    double lutVal = 1.0;
+
+    const size_t pos =  x + m_Offset;
+    if(pos  < m_Gains.size())
+      {
+      lutVal = m_Gains[pos];
+      }
+    else
+      {
+      //itkExceptionMacro( << "error: (pos < list.size() )" << pos << " < " << list.size())
+      }
+    return lutVal;
+  }
+
+  void PrintSelf(std::ostream & os, itk::Indent indent) const
+  {
+    os << indent << " offset:'" << m_Offset << "'" << std::endl;
+    os <<  " referenceNoiseLevel.gain: " << std::endl;
+    std::vector<float>::const_iterator it = m_Gains.begin();
+    while (it != m_Gains.end())
+      {
+      os << (*it) << " ";
+      ++it;
+      }
+    os << std::endl;
+
+    Superclass::PrintSelf(os, indent);
+  }
+
+private:
+
+  Radarsat2CalibrationLookupData(const Self&); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+  GainListType m_Gains;
+  int m_Offset;
+
+
+};
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Core/Metadata/include/otbRadarsat2ImageMetadataInterfaceFactory.h b/Modules/Core/Metadata/include/otbRadarsat2ImageMetadataInterfaceFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..2aeb8a8f583be04f5b8fcb0f022015daea6d283f
--- /dev/null
+++ b/Modules/Core/Metadata/include/otbRadarsat2ImageMetadataInterfaceFactory.h
@@ -0,0 +1,68 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbRadarsat2ImageMetadataInterfaceFactory_h
+#define __otbRadarsat2ImageMetadataInterfaceFactory_h
+
+#include "itkObjectFactoryBase.h"
+
+namespace otb
+{
+/** \class Radarsat2ImageMetadataInterfaceFactory
+ * \brief Creating an instance of a ImageMetadataInterface object using object factory.
+ *
+ * \ingroup OTBMetadata
+ */
+class ITK_EXPORT Radarsat2ImageMetadataInterfaceFactory : public itk::ObjectFactoryBase
+{
+public:
+  /** Standard class typedefs. */
+  typedef Radarsat2ImageMetadataInterfaceFactory Self;
+  typedef itk::ObjectFactoryBase            Superclass;
+  typedef itk::SmartPointer<Self>           Pointer;
+  typedef itk::SmartPointer<const Self>     ConstPointer;
+
+  /** Class methods used to interface with the registered factories. */
+  virtual const char* GetITKSourceVersion(void) const;
+  virtual const char* GetDescription(void) const;
+
+  /** Method for class instantiation. */
+  itkFactorylessNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(Radarsat2ImageMetadataInterfaceFactory, itk::ObjectFactoryBase);
+
+  /** Register one factory of this type  */
+  static void RegisterOneFactory(void)
+  {
+    Pointer factory = Radarsat2ImageMetadataInterfaceFactory::New();
+    itk::ObjectFactoryBase::RegisterFactory(factory);
+  }
+
+protected:
+  Radarsat2ImageMetadataInterfaceFactory();
+  virtual ~Radarsat2ImageMetadataInterfaceFactory();
+
+private:
+  Radarsat2ImageMetadataInterfaceFactory(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+};
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Core/Metadata/src/CMakeLists.txt b/Modules/Core/Metadata/src/CMakeLists.txt
index 77dad8c9f5ae67af5ba6ed436ab72c0954abf9a9..a81509ee9cba75db47fa7fb168357b91525385f2 100644
--- a/Modules/Core/Metadata/src/CMakeLists.txt
+++ b/Modules/Core/Metadata/src/CMakeLists.txt
@@ -39,6 +39,9 @@ set(OTBMetadata_SRC
   otbSentinel1ImageMetadataInterfaceFactory.cxx
   otbSentinel1ImageMetadataInterface.cxx
 
+  otbRadarsat2ImageMetadataInterfaceFactory.cxx
+  otbRadarsat2ImageMetadataInterface.cxx
+
   otbNoDataHelper.cxx
   )
 
diff --git a/Modules/Core/Metadata/src/otbImageMetadataInterfaceFactory.cxx b/Modules/Core/Metadata/src/otbImageMetadataInterfaceFactory.cxx
index 4b554bf6267ff9239d5e2beada80d77a0bae57df..31ff54ac85a44fed7046c77541c120fc79204146 100644
--- a/Modules/Core/Metadata/src/otbImageMetadataInterfaceFactory.cxx
+++ b/Modules/Core/Metadata/src/otbImageMetadataInterfaceFactory.cxx
@@ -33,6 +33,7 @@
 // SAR Sensors
 #include "otbTerraSarImageMetadataInterfaceFactory.h"
 #include "otbSentinel1ImageMetadataInterfaceFactory.h"
+#include "otbRadarsat2ImageMetadataInterfaceFactory.h"
 
 #include "itkMutexLock.h"
 #include "itkMutexLockHolder.h"
@@ -112,7 +113,7 @@ ImageMetadataInterfaceFactory
       itk::ObjectFactoryBase::RegisterFactory(WorldView2ImageMetadataInterfaceFactory::New());
       itk::ObjectFactoryBase::RegisterFactory(TerraSarImageMetadataInterfaceFactory::New());
       itk::ObjectFactoryBase::RegisterFactory(Sentinel1ImageMetadataInterfaceFactory::New());
-
+      itk::ObjectFactoryBase::RegisterFactory(Radarsat2ImageMetadataInterfaceFactory::New());
       firstTime = false;
       }
     }
diff --git a/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterface.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..748c45d65419a9b9dea843f12fed6d93ba3e4f00
--- /dev/null
+++ b/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterface.cxx
@@ -0,0 +1,260 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#include "otbSarImageMetadataInterface.h"
+#include "otbRadarsat2ImageMetadataInterface.h"
+
+#include "otbMacro.h"
+#include "itkMetaDataObject.h"
+#include "otbImageKeywordlist.h"
+
+//useful constants
+#include <otbMath.h>
+
+namespace otb
+{
+
+Radarsat2ImageMetadataInterface
+::Radarsat2ImageMetadataInterface()
+{
+
+}
+
+bool
+Radarsat2ImageMetadataInterface::CanRead() const
+{
+  std::string sensorID = GetSensorID();
+
+  if (sensorID.find("RADARSAT-2") != std::string::npos)
+    {
+    return true;
+    }
+  else
+    return false;
+}
+
+
+void
+Radarsat2ImageMetadataInterface::
+CreateCalibrationLookupData(const short type)
+  {
+   std::string lut = "SigmaNought";
+
+   switch (type)
+     {
+     case SarCalibrationLookupData::BETA:
+     {
+     lut = "BetaNought";
+     }
+     break;
+
+     case SarCalibrationLookupData::GAMMA:
+     {
+     lut = "GammaNought";
+     }
+     break;
+
+     case SarCalibrationLookupData::DN:
+     {
+     lut = "DN";
+     }
+     break;
+
+     case SarCalibrationLookupData::SIGMA:
+     default:
+     {
+     lut = "SigmaNought";
+     }
+     break;
+     }
+
+  const ImageKeywordlistType imageKeywordlist =  this->GetImageKeywordlist();
+  const std::string key = "referenceNoiseLevel[" + lut + "].gain";
+
+  Radarsat2CalibrationLookupData::GainListType glist;
+  int offset = 0;
+
+  Utils::ConvertStringToVector(imageKeywordlist.GetMetadataByKey("referenceNoiseLevel[" + lut + "].gain"), glist, "referenceNoiseLevel[" + lut + "].gain");
+
+  Utils::LexicalCast<int>(imageKeywordlist.GetMetadataByKey("referenceNoiseLevel[" + lut + "].offset"), "referenceNoiseLevel[" + lut + "].offset");
+
+  Radarsat2CalibrationLookupData::Pointer sarLut;
+  sarLut = Radarsat2CalibrationLookupData::New();
+  sarLut->InitParameters(type, offset, glist);
+  this->SetCalibrationLookupData(sarLut);
+
+}
+
+void
+Radarsat2ImageMetadataInterface
+::ParseDateTime(const char* key, std::vector<int>& dateFields) const
+{
+  if(dateFields.size() < 1 )
+    {
+    //parse from keyword list
+    if (!this->CanRead())
+      {
+      itkExceptionMacro(<< "Invalid Metadata, not a valid product");
+      }
+
+    const ImageKeywordlistType imageKeywordlist  = this->GetImageKeywordlist();
+    if (!imageKeywordlist.HasKey(key))
+      {
+      itkExceptionMacro( << "no key named '" << key << "'");
+      }
+
+    std::string date_time_str = imageKeywordlist.GetMetadataByKey(key);
+    date_time_str.resize(date_time_str.size() - 1);
+    Utils::ConvertStringToVector(date_time_str, dateFields, key, "-T:.");
+    }
+}
+
+int
+Radarsat2ImageMetadataInterface::GetYear() const
+{
+  int value = 0;
+  ParseDateTime("support_data.image_date", m_AcquisitionDateFields);
+  if(m_AcquisitionDateFields.size() > 0 )
+    {
+    value = Utils::LexicalCast<int>( m_AcquisitionDateFields[0], "support_data.image_date(year)" );
+    }
+  return value;
+}
+
+int
+Radarsat2ImageMetadataInterface::GetMonth() const
+{
+  int value = 0;
+  ParseDateTime("support_data.image_date", m_AcquisitionDateFields);
+  if(m_AcquisitionDateFields.size() > 1 )
+    {
+    value = Utils::LexicalCast<int>( m_AcquisitionDateFields[1], "support_data.image_date(month)" );
+    }
+  return value;
+}
+
+int
+Radarsat2ImageMetadataInterface::GetDay() const
+{
+  int value = 0;
+  ParseDateTime("support_data.image_date", m_AcquisitionDateFields);
+  if(m_AcquisitionDateFields.size() > 2 )
+    {
+    value = Utils::LexicalCast<int>( m_AcquisitionDateFields[2], "support_data.image_date(day)" );
+    }
+  return value;
+}
+
+int
+Radarsat2ImageMetadataInterface::GetHour() const
+{
+  int value = 0;
+  ParseDateTime("support_data.image_date", m_AcquisitionDateFields);
+  if(m_AcquisitionDateFields.size() > 3 )
+    {
+    value = Utils::LexicalCast<int>( m_AcquisitionDateFields[3], "support_data.image_date(hour)" );
+    }
+  return value;
+}
+
+int
+Radarsat2ImageMetadataInterface::GetMinute() const
+{
+  int value = 0;
+  ParseDateTime("support_data.image_date", m_AcquisitionDateFields);
+  if(m_AcquisitionDateFields.size() > 4 )
+    {
+    value = Utils::LexicalCast<int>( m_AcquisitionDateFields[4], "support_data.image_date(minute)" );
+    }
+  return value;
+}
+
+int
+Radarsat2ImageMetadataInterface::GetProductionYear() const
+{
+  int value = 0;
+  ParseDateTime("support_data.date", m_ProductionDateFields);
+  if(m_ProductionDateFields.size() > 0 )
+    {
+    value = Utils::LexicalCast<int>( m_ProductionDateFields[0], "support_data.image_date(year)" );
+    }
+  return value;
+
+}
+
+int
+Radarsat2ImageMetadataInterface::GetProductionMonth() const
+{
+  int value = 0;
+  ParseDateTime("support_data.date", m_ProductionDateFields);
+  if(m_ProductionDateFields.size() > 1 )
+    {
+    value = Utils::LexicalCast<int>( m_ProductionDateFields[1], "support_data.image_date(production month)" );
+    }
+  return value;
+}
+
+int
+Radarsat2ImageMetadataInterface::GetProductionDay() const
+{
+  int value = 0;
+  ParseDateTime("support_data.date", m_ProductionDateFields);
+  if(m_ProductionDateFields.size() > 2 )
+    {
+    value = Utils::LexicalCast<int>( m_ProductionDateFields[2], "support_data.image_date(production day)" );
+    }
+  return value;
+}
+
+
+double
+Radarsat2ImageMetadataInterface::GetPRF() const
+{
+  return 0;
+}
+
+double
+Radarsat2ImageMetadataInterface::GetRSF() const
+{
+  return 0;
+}
+
+double
+Radarsat2ImageMetadataInterface::GetRadarFrequency() const
+{
+  return 0;
+}
+
+double
+Radarsat2ImageMetadataInterface::GetCenterIncidenceAngle() const
+{
+  return 0;
+}
+
+Radarsat2ImageMetadataInterface::UIntVectorType
+Radarsat2ImageMetadataInterface::
+GetDefaultDisplay() const
+{
+  UIntVectorType rgb(3);
+  rgb[0] = 0;
+  rgb[1] = 0;
+  rgb[2] = 0;
+  return rgb;
+}
+
+} // end namespace otb
diff --git a/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterfaceFactory.cxx b/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterfaceFactory.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e9f656cfc1ef64bdb6225559b6de5091d97c9f60
--- /dev/null
+++ b/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterfaceFactory.cxx
@@ -0,0 +1,58 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+
+#include <typeinfo>
+#include <cassert>
+
+#include "otbRadarsat2ImageMetadataInterfaceFactory.h"
+#include "otbRadarsat2ImageMetadataInterface.h"
+
+#include "itkCreateObjectFunction.h"
+#include "itkVersion.h"
+
+namespace otb
+{
+Radarsat2ImageMetadataInterfaceFactory
+::Radarsat2ImageMetadataInterfaceFactory()
+{
+  this->RegisterOverride("SarImageMetadataInterface",
+                         "otbRadarsat2ImageMetadataInterface",
+                         "Radarsat2 Metadata Interface",
+                         1,
+                         itk::CreateObjectFunction<Radarsat2ImageMetadataInterface>::New());
+}
+
+Radarsat2ImageMetadataInterfaceFactory
+::~Radarsat2ImageMetadataInterfaceFactory()
+{
+}
+
+const char*
+Radarsat2ImageMetadataInterfaceFactory::GetITKSourceVersion(void) const
+{
+  return ITK_SOURCE_VERSION;
+}
+
+const char*
+Radarsat2ImageMetadataInterfaceFactory::GetDescription() const
+{
+  return "Radarsat2 Metadata Interface Factory, handle Radarsat2 metadata in OTB";
+}
+
+} // end namespace otb
diff --git a/Modules/Core/Metadata/src/otbSarImageMetadataInterfaceFactory.cxx b/Modules/Core/Metadata/src/otbSarImageMetadataInterfaceFactory.cxx
index 0cb27515e7e87d6f06f8c5390162500e6caa4509..f0c7bcff04e050b29babcf8d89c88a5493cec70e 100644
--- a/Modules/Core/Metadata/src/otbSarImageMetadataInterfaceFactory.cxx
+++ b/Modules/Core/Metadata/src/otbSarImageMetadataInterfaceFactory.cxx
@@ -23,6 +23,7 @@
 // SAR Sensors
 #include "otbTerraSarImageMetadataInterfaceFactory.h"
 #include "otbSentinel1ImageMetadataInterfaceFactory.h"
+#include "otbRadarsat2ImageMetadataInterfaceFactory.h"
 
 #include "itkMutexLock.h"
 #include "itkMutexLockHolder.h"
@@ -81,6 +82,7 @@ SarImageMetadataInterfaceFactory
       {
       itk::ObjectFactoryBase::RegisterFactory(TerraSarImageMetadataInterfaceFactory::New());
       itk::ObjectFactoryBase::RegisterFactory(Sentinel1ImageMetadataInterfaceFactory::New());
+      itk::ObjectFactoryBase::RegisterFactory(Radarsat2ImageMetadataInterfaceFactory::New());
       firstTime = false;
       }
     }
diff --git a/Modules/Core/Metadata/test/CMakeLists.txt b/Modules/Core/Metadata/test/CMakeLists.txt
index 7cf31ac3f3b85b70acc2b6bcb2d192a147e4532c..23e6ef48e261edb6a9d8a5e4cd89acb047b646da 100644
--- a/Modules/Core/Metadata/test/CMakeLists.txt
+++ b/Modules/Core/Metadata/test/CMakeLists.txt
@@ -25,6 +25,7 @@ otbDefaultImageMetadataInterface.cxx
 otbImageMetadataInterfaceTest2.cxx
 otbNoDataHelperTest.cxx
 otbSarCalibrationLookupDataTest.cxx
+otbRadarsat2ImageMetadataInterfaceNew.cxx
 )
 
 add_executable(otbMetadataTestDriver ${OTBMetadataTests})
@@ -76,17 +77,28 @@ otb_add_test(NAME ioTvSarImageMetadataInterfaceTest_TSX1PANGKALANBUUNUsingHHCosF
   ${TEMP}/ioTvSarImageMetadataInterface_TSX1PANGKALANBUUNUsingHHCosFile.txt
   )
 
-otb_add_test(NAME ioTvImageMetadataInterfaceBaseTest_Sentinel1 COMMAND otbMetadataTestDriver
-  --compare-ascii ${EPSILON_9} ${BASELINE_FILES}/ioTvImageMetadataInterfaceBase_Sentinel1.txt
-  ${TEMP}/ioTvImageMetadataInterfaceBase_Sentinel1.txt
+otb_add_test(NAME ioTvImageMetadataInterfaceBaseTest_SENTINEL1 COMMAND otbMetadataTestDriver
+  --compare-ascii ${EPSILON_9} ${BASELINE_FILES}/ioTvImageMetadataInterfaceBase_SENTINEL1.txt
+  ${TEMP}/ioTvImageMetadataInterfaceBase_SENTINEL1.txt
   otbImageMetadataInterfaceBaseTest
   LARGEINPUT{SENTINEL1/S1A_S6_SLC__1SSV_20150619T195043/measurement/s1a-s6-slc-vv-20150619t195043-20150619t195101-006447-00887d-001.tiff}
-  ${TEMP}/ioTvImageMetadataInterfaceBase_Sentinel1.txt
+  ${TEMP}/ioTvImageMetadataInterfaceBase_SENTINEL1.txt
+  )
+
+otb_add_test(NAME ioTvImageMetadataInterfaceBaseTest_RADARSAT2 COMMAND otbMetadataTestDriver
+  --compare-ascii ${EPSILON_9} ${BASELINE_FILES}/ioTvImageMetadataInterfaceBase_RADARSAT2.txt
+  ${TEMP}/ioTvImageMetadataInterfaceBase_RADARSAT2.txt
+  otbImageMetadataInterfaceBaseTest
+  LARGEINPUT{RADARSAT2/ALTONA/Fine_Quad-Pol_Dataset/PK6621_DK406_FQ9_20080405_124900_HH_VV_HV_VH_SLC_Altona/imagery_HV.tif}
+  ${TEMP}/ioTvImageMetadataInterfaceBase_RADARSAT2.txt
   )
 
 otb_add_test(NAME ioTuSentinel1ImageMetadataInterfaceNew COMMAND otbMetadataTestDriver
   otbSentinel1ImageMetadataInterfaceNew )
 
+otb_add_test(NAME ioTuRadarsat2ImageMetadataInterfaceNew COMMAND otbMetadataTestDriver
+  otbRadarsat2ImageMetadataInterfaceNew )
+
 otb_add_test(NAME ioTuDefaultImageMetadataInterfaceFactoryNew COMMAND otbMetadataTestDriver
   otbDefaultImageMetadataInterfaceFactoryNew )
 
@@ -375,4 +387,12 @@ otb_add_test(NAME ioTvSarCalibrationLookupDataTest_SENTINEL1 COMMAND otbMetadata
   otbSarCalibrationLookupDataTest
   ${INPUTDATA}/SENTINEL1_SLC_S6_1S_extract_300_300.tif?&geom=${INPUTDATA}/SENTINEL1_SLC_S6_1S_extract_300_300.geom
   ${TEMP}/ioTvSarCalibrationLookupDataTest_SENTINEL1.txt
+  )
+
+otb_add_test(NAME ioTvSarCalibrationLookupDataTest_RADARSAT2 COMMAND otbMetadataTestDriver
+  --compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTvSarCalibrationLookupDataTest_RADARSAT2.txt
+  ${TEMP}/ioTvSarCalibrationLookupDataTest_RADARSAT2.txt
+  otbSarCalibrationLookupDataTest
+  ${INPUTDATA}/RADARSAT2_ALTONA_300_300_VV.tif?&geom=${INPUTDATA}/RADARSAT2_ALTONA_300_300_VV.geom
+  ${TEMP}/ioTvSarCalibrationLookupDataTest_RADARSAT2.txt
   )
\ No newline at end of file
diff --git a/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx b/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx
index 9b48c72a5bb07d49db1b90cf2e8bc0da4e95aa5e..ea205e1d08d67b76de16468be0578a459cb549ec 100644
--- a/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx
+++ b/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx
@@ -24,4 +24,5 @@ void RegisterTests()
   REGISTER_TEST(otbImageMetadataInterfaceTest2);
   REGISTER_TEST(otbNoDataHelperTest);
   REGISTER_TEST(otbSarCalibrationLookupDataTest);
+  REGISTER_TEST(otbRadarsat2ImageMetadataInterfaceNew);
 }
diff --git a/Modules/Core/Metadata/test/otbRadarsat2ImageMetadataInterfaceNew.cxx b/Modules/Core/Metadata/test/otbRadarsat2ImageMetadataInterfaceNew.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..191ac66e7a3628638cba3443631d207d263f6178
--- /dev/null
+++ b/Modules/Core/Metadata/test/otbRadarsat2ImageMetadataInterfaceNew.cxx
@@ -0,0 +1,32 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+
+
+#include "itkMacro.h"
+#include <iostream>
+#include "otbRadarsat2ImageMetadataInterface.h"
+
+int otbRadarsat2ImageMetadataInterfaceNew(int itkNotUsed(argc), char * itkNotUsed(argv) [])
+{
+  otb::Radarsat2ImageMetadataInterface::Pointer object = otb::Radarsat2ImageMetadataInterface::New();
+
+  std::cout << object << std::endl;
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h
index 4ebdfce5c43e1299bb7195712b8ad2df55b1e3c9..3b44ec0bedd6295fc0491fec6942d03ba10b9d87 100644
--- a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h
+++ b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.h
@@ -93,6 +93,8 @@ protected:
    */
   virtual void GenerateInputRequestedRegion();
 
+  virtual void GenerateOutputInformation();
+
   /**
    * Re-implement the method ThreadedGenerateData to mask area outside the deformation grid
    */
diff --git a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx
index a3e9972a3b5117584e0b984f6c3d0cdf0ec9f693..19ba9ff358c2f35ac314090048b0605b6a08e66f 100644
--- a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx
+++ b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.txx
@@ -23,6 +23,9 @@
 
 #include "otbStreamingWarpImageFilter.h"
 #include "itkImageRegionIteratorWithIndex.h"
+#include "itkDefaultConvertPixelTraits.h"
+#include "itkMetaDataObject.h"
+#include "otbMetaDataKey.h"
 
 namespace otb
 {
@@ -202,6 +205,40 @@ StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
  }
 
 
+template<class TInputImage, class TOutputImage, class TDisplacementField>
+void
+StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
+::GenerateOutputInformation()
+{
+  Superclass::GenerateOutputInformation();
+
+  // Set the NoData flag to the edge padding value
+  itk::MetaDataDictionary& dict = this->GetOutput()->GetMetaDataDictionary();
+  std::vector<bool> noDataValueAvailable;
+  bool ret = itk::ExposeMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  if (!ret)
+    {
+    noDataValueAvailable.resize(this->GetOutput()->GetNumberOfComponentsPerPixel(),false);
+    }
+  std::vector<double> noDataValue;
+  ret = itk::ExposeMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
+  if (!ret)
+    {
+    noDataValue.resize(this->GetOutput()->GetNumberOfComponentsPerPixel(),0.0);
+    }
+  PixelType edgePadding = this->GetEdgePaddingValue();
+  for (unsigned int i=0; i<noDataValueAvailable.size() ; ++i)
+    {
+    if (!noDataValueAvailable[i])
+      {
+      noDataValueAvailable[i] = true;
+      noDataValue[i] = itk::DefaultConvertPixelTraits<PixelType>::GetNthComponent(i,edgePadding);
+      }
+    }
+  itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
+}
+
 template<class TInputImage, class TOutputImage, class TDisplacementField>
 void
 StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField>
diff --git a/Modules/Core/VectorDataBase/include/otbVectorDataKeywordlist.h b/Modules/Core/VectorDataBase/include/otbVectorDataKeywordlist.h
index 8b16fb5d70e0b8c069e1562abfe47708a6658bc6..f55622ad5e041cf471703c546bc032e4c78100c9 100644
--- a/Modules/Core/VectorDataBase/include/otbVectorDataKeywordlist.h
+++ b/Modules/Core/VectorDataBase/include/otbVectorDataKeywordlist.h
@@ -141,8 +141,9 @@ public:
 
   /** Constructor */
   VectorDataKeywordlist();
+
   /** Destructor */
-  virtual ~VectorDataKeywordlist();
+  ~VectorDataKeywordlist();
 
   /** Constructor by copy (deep copy)*/
   VectorDataKeywordlist(const Self& other);
diff --git a/Modules/Core/VectorDataBase/src/otbVectorDataKeywordlist.cxx b/Modules/Core/VectorDataBase/src/otbVectorDataKeywordlist.cxx
index 4404db5e7a58c0a065aa3cd342b61f208df8b275..9b5463d604ad411ba07a2c4dfc6804b91e07d2fc 100644
--- a/Modules/Core/VectorDataBase/src/otbVectorDataKeywordlist.cxx
+++ b/Modules/Core/VectorDataBase/src/otbVectorDataKeywordlist.cxx
@@ -20,6 +20,8 @@
 
 #include "otbVectorDataKeywordlist.h"
 
+#include "otbConfigure.h"
+
 namespace otb
 {
 
@@ -88,25 +90,39 @@ VectorDataKeywordlist
     {
     if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
       {
-      if (m_FieldList[i].first->GetType() == OFTString)
+      switch(m_FieldList[i].first->GetType())
+        {
+        case OFTString:
         {
         return m_FieldList[i].second.String;
         }
-      if (m_FieldList[i].first->GetType() == OFTInteger)
+        case OFTInteger:
         {
         std::ostringstream ss;
         ss << std::setprecision(15) << m_FieldList[i].second.Integer;
         return ss.str();
         }
-      if (m_FieldList[i].first->GetType() == OFTReal)
+#ifdef OTB_USE_GDAL_20
+        case OFTInteger64:
+        {
+        std::ostringstream ss;
+        ss << std::setprecision(15) << m_FieldList[i].second.Integer64;
+        return ss.str();
+        }
+#endif     
+        case OFTReal:
         {
         std::ostringstream ss;
         ss << std::setprecision(15) << m_FieldList[i].second.Real;
         return ss.str();
         }
-      itkExceptionMacro(
-        << "This type (" << m_FieldList[i].first->GetType() <<
-        ") is not handled (yet) by GetFieldAsString(), please request for it");
+        default:
+        {
+        itkExceptionMacro(
+          << "Type of field " << m_FieldList[i].first->GetNameRef() << " (" << m_FieldList[i].first->GetType() <<
+          ") is not handled (yet) by GetFieldAsString(), please request for it");
+        }
+        }
       }
     }
   return "";
@@ -120,24 +136,30 @@ VectorDataKeywordlist
       {
       if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
         {
-        if (m_FieldList[i].first->GetType() == OFTInteger)
+        switch (m_FieldList[i].first->GetType())
+          {
+          case OFTInteger:
           {
           return (double)(m_FieldList[i].second.Integer);
           }
-        if (m_FieldList[i].first->GetType() == OFTReal)
+          case OFTReal:
           {
           return (double)(m_FieldList[i].second.Real);
           }
-        if (m_FieldList[i].first->GetType() == OFTString)
+          case OFTString:
           {
           std::istringstream is(m_FieldList[i].second.String);
           double value;
           is >> value;
           return value;
           }
-        itkExceptionMacro(
-          << "This type (" << m_FieldList[i].first->GetType() <<
-          ") is not handled (yet) by GetFieldAsDouble(), please request for it");
+          default:
+          {
+           itkExceptionMacro(
+             << "Type of field " << m_FieldList[i].first->GetNameRef() << " (" << m_FieldList[i].first->GetType() <<
+             ") is not handled (yet) by GetFieldAsDouble(), please request for it");
+          }
+          }
         }
       }
     return 0.;
@@ -151,26 +173,47 @@ VectorDataKeywordlist
       {
       if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
         {
-        if (m_FieldList[i].first->GetType() == OFTInteger)
+        switch(m_FieldList[i].first->GetType())
+          {
+          case OFTInteger:
           {
-          return (int)(m_FieldList[i].second.Integer);
+        return (int)(m_FieldList[i].second.Integer);
+        }
+#ifdef OTB_USE_GDAL_20
+        // Some fields that were OFTInteger with gdal 1.x are now
+        // exposed as OFTInteger64. So as to make the old code still
+        // work with the same data, here we downcast to Integer (if
+        // and only if no overflow occur).
+        case OFTInteger64:
+          {
+          if(m_FieldList[i].second.Integer64 > itk::NumericTraits<int>::max())
+            {
+            itkExceptionMacro(<<"value "<<m_FieldList[i].second.Integer64<<" of field "<<m_FieldList[i].first->GetNameRef()<<" can not be safely casted to 32 bits integer");
+            }
+          
+          return static_cast<int>(m_FieldList[i].second.Integer64);
           }
-        if (m_FieldList[i].first->GetType() == OFTReal)
+#endif    
+        case OFTReal:
           {
           return (int)(m_FieldList[i].second.Real);
           }
-        if (m_FieldList[i].first->GetType() == OFTString)
+        case OFTString:
           {
           std::istringstream is(m_FieldList[i].second.String);
           int value;
           is >> value;
           return value;
           }
+        default:
+        {
         itkExceptionMacro(
-          << "This type (" << m_FieldList[i].first->GetType() <<
+          << "Type of field " << m_FieldList[i].first->GetNameRef() << " (" << m_FieldList[i].first->GetType() <<
           ") is not handled (yet) by GetFieldAsInt(), please request for it");
         }
-      }
+        }
+        }
+        }
     return 0.;
 }
 
@@ -383,51 +426,11 @@ VectorDataKeywordlist::CopyFieldList(const Self& kwl)
                              kwl.GetNthField(idx).second.Real);
       break;
       }
-      case OFTIntegerList:
-      {
-      std::cerr << "Type not handled for Integer conversion" <<std::endl;
-      break;
-      }
-      case OFTRealList:
-      {
-      std::cerr << "Type not handled for Integer conversion"<<std::endl;
-      break;
-      }
-      case OFTStringList:
-      {
-      std::cerr << "Type not handled for Integer conversion"<<std::endl;
-      break;
-      }
-      case OFTWideString:
-      {
-      std::cerr << "Type not handled for Integer conversion"<<std::endl;
-      break;
-      }
-      case OFTWideStringList:
-      {
-      std::cerr << "Type not handled for Integer conversion"<<std::endl;
-      break;
-      }
-      case OFTBinary:
-      {
-      std::cerr << "Type not handled for Integer conversion"<<std::endl;
-      break;
-      }
-      case OFTDate:
-      {
-      std::cerr << "Type not handled for Integer conversion"<<std::endl;
-      break;
-      }
-      case OFTTime:
-      {
-      std::cerr << "Type not handled for Integer conversion"<<std::endl;
-      break;
-      }
-      case OFTDateTime:
+      default:
       {
       std::cerr << "Type not handled for Integer conversion"<<std::endl;
       break;
-      }
+      }      
       }
     }
 }
@@ -447,21 +450,11 @@ VectorDataKeywordlist
       output << field.second.Integer;
       break;
       }
-    case OFTIntegerList:
-      {
-      output << "Type not handled for printing";
-      break;
-      }
     case OFTReal:
       {
       output << field.second.Real;
       break;
       }
-    case OFTRealList:
-      {
-      std::cerr << "Type not handled for printing" << std::endl;
-      break;
-      }
     case OFTString:
       {
       if (field.second.String != NULL)
@@ -470,26 +463,6 @@ VectorDataKeywordlist
         }
       break;
       }
-    case OFTStringList:
-      {
-      output << "Type not handled for printing";
-      break;
-      }
-    case OFTWideString:
-      {
-      output << "Type not handled for printing";
-      break;
-      }
-    case OFTWideStringList:
-      {
-      output << "Type not handled for printing";
-      break;
-      }
-    case OFTBinary:
-      {
-      output << "Type not handled for printing";
-      break;
-      }
     case OFTDate:
       {
       output << field.second.Date.Year << field.second.Date.Month << field.second.Date.Day;
@@ -506,6 +479,16 @@ VectorDataKeywordlist
              << field.second.Date.Hour << field.second.Date.Minute << field.second.Date.Second;
       break;
       }
+#ifdef OTB_USE_GDAL_20
+    case OFTInteger64:
+    {
+    output << std::setprecision(15)<<field.second.Integer64;
+    break;
+    }
+#endif     
+    default:
+      output << "Type not handled for printing";
+      break;
     }
   output << std::endl;
   return output.str();
@@ -524,21 +507,18 @@ VectorDataKeywordlist
       outField.second.Integer = field.second.Integer;
       break;
       }
-    case OFTIntegerList:
-      {
-      std::cerr << "OGR type not handled" << std::endl;
-      break;
-      }
+#ifdef OTB_USE_GDAL_20
+    case OFTInteger64:
+    {
+    outField.second.Integer64 = field.second.Integer64;
+    break;
+    }
+#endif     
     case OFTReal:
       {
       outField.second.Real = field.second.Real;
       break;
       }
-    case OFTRealList:
-      {
-      std::cerr << "OGR type not handled" << std::endl;
-      break;
-      }
     case OFTString:
       {
       if (field.second.String != NULL)
@@ -548,26 +528,6 @@ VectorDataKeywordlist
         }
       break;
       }
-    case OFTStringList:
-      {
-      std::cerr << "OGR type not handled" << std::endl;
-      break;
-      }
-    case OFTWideString:
-      {
-      std::cerr << "OGR type not handled" << std::endl;
-      break;
-      }
-    case OFTWideStringList:
-      {
-      std::cerr << "OGR type not handled" << std::endl;
-      break;
-      }
-    case OFTBinary:
-      {
-      std::cerr << "OGR type not handled" << std::endl;
-      break;
-      }
     case OFTDate:
       {
       outField.second.Date.Year = field.second.Date.Year;
@@ -592,6 +552,11 @@ VectorDataKeywordlist
       outField.second.Date.Second = field.second.Date.Second;
       break;
       }
+    default:
+      {
+      std::cerr << "OGR type not handled" << std::endl;
+      break;
+      }
     }
   return outField;
 }
diff --git a/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..f92b2c20656c832253b695b6f5845a93465635b1
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.h
@@ -0,0 +1,94 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbChangeInformationImageFilter_h
+#define __otbChangeInformationImageFilter_h
+
+#include "itkChangeInformationImageFilter.h"
+#include "otbMetaDataKey.h"
+
+namespace otb
+{
+
+/**
+ * \class ChangeInformationImageFilter
+ * \brief Filter to modify image metadata
+ *
+ * The base class is itk::ChangeInformationImageFilter that allows to
+ * modifiy origin, spacing, direction and buffered region. This deriving
+ * filter adds the support of MetaDataDictionary.
+ *
+ * \ingroup OTBImageManipulation
+ */
+template< typename TInputImage >
+class ChangeInformationImageFilter:
+  public itk::ChangeInformationImageFilter< TInputImage >
+{
+public:
+  /** Standard class typedefs. */
+  typedef ChangeInformationImageFilter                   Self;
+  typedef itk::ChangeInformationImageFilter<TInputImage> Superclass;
+  typedef itk::SmartPointer<Self>                        Pointer;
+  typedef itk::SmartPointer<const Self>                  ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Creation through object factory macro */
+  itkTypeMacro(ChangeInformationImageFilter, itk::ChangeInformationImageFilter);
+
+  /** Set key names to change */
+  void SetChangeMetaData(const char *keyname, bool flag);
+
+  /** Ask if a metadata will be changed */
+  bool GetChangeMetaData(const char *keyname);
+
+  /** Set output values for metadata, passing a NULL value will remove the
+   *  metadata from output. If not set for a key name in the change list,
+   *  the metadata will also be set.
+   */
+  template<typename T>
+  void SetOutputMetaData(const char *keyname, const T * value);
+
+protected:
+  ChangeInformationImageFilter() {}
+  virtual ~ChangeInformationImageFilter() {}
+
+  /** Apply changes to the output image metadata. */
+  virtual void GenerateOutputInformation();
+
+private:
+  ChangeInformationImageFilter(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+  /** Removes a field from a metadata dictionary
+   *  After ITK 4.6, an Erase() method has been added to
+   *  itk::MetaDataDictionary, so this function could be tagged as deprecated */
+  bool RemoveKeyFromDictionary(itk::MetaDataDictionary & dict, const std::string & key);
+
+  /** List of metadata keys to change */
+  std::set<std::string> m_ChangedKeys;
+
+};
+
+} // End of namespace OTB
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbChangeInformationImageFilter.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..319684064c4caf4a83c8be8b7fd460cae13d920d
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbChangeInformationImageFilter.txx
@@ -0,0 +1,150 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbChangeInformationImageFilter_txx
+#define __otbChangeInformationImageFilter_txx
+
+#include "otbChangeInformationImageFilter.h"
+#include "itkMetaDataObject.h"
+
+namespace otb
+{
+
+template< typename TInputImage >
+void
+ChangeInformationImageFilter<TInputImage>
+::SetChangeMetaData(const char *keyname, bool flag)
+{
+  std::string key(keyname);
+  if (! key.empty())
+    {
+    if (flag)
+      {
+      m_ChangedKeys.insert(key);
+      }
+    else
+      {
+      std::set<std::string>::iterator pos = m_ChangedKeys.find(key);
+      if (pos != m_ChangedKeys.end())
+        {
+        m_ChangedKeys.erase(pos);
+        }
+      }
+    }
+}
+
+template< typename TInputImage >
+bool
+ChangeInformationImageFilter<TInputImage>
+::GetChangeMetaData(const char *keyname)
+{
+  std::string key(keyname);
+  if (! key.empty())
+    {
+    if (m_ChangedKeys.find(key) != m_ChangedKeys.end())
+      {
+      return true;
+      }
+    }
+  return false;
+}
+
+template< typename TInputImage >
+template<typename T>
+void
+ChangeInformationImageFilter<TInputImage>
+::SetOutputMetaData(const char *keyname, const T * value)
+{
+  std::string key(keyname);
+  if (! key.empty())
+    {
+    // enable this key for metadata change
+    m_ChangedKeys.insert(key);
+    itk::MetaDataDictionary &dict = this->GetMetaDataDictionary();
+    if (value == NULL)
+      {
+      // Remove meta-data from dictionary
+      this->RemoveKeyFromDictionary(dict,key);
+      }
+    else
+      {
+      // Set metadata in dictionary
+      const T &valueRef = (*value);
+      itk::EncapsulateMetaData<T>(dict,key,valueRef);
+      }
+    }
+}
+
+template< typename TInputImage >
+void
+ChangeInformationImageFilter<TInputImage>
+::GenerateOutputInformation()
+{
+  Superclass::GenerateOutputInformation();
+
+  // Process the metadatas to be changed
+  itk::MetaDataDictionary &dict = this->GetMetaDataDictionary();
+  itk::MetaDataDictionary &outputDict = this->GetOutput()->GetMetaDataDictionary();
+  std::set<std::string>::iterator it = m_ChangedKeys.begin();
+  for ( ; it != m_ChangedKeys.end() ; ++it)
+    {
+    if (dict.HasKey(*it))
+      {
+      // Replace metadata in output dictionary
+      outputDict[*it] = dict[*it];
+      }
+    else
+      {
+      // Remove metadata from output dictionary
+      this->RemoveKeyFromDictionary(outputDict,*it);
+      }
+    }
+}
+
+template< typename TInputImage >
+bool
+ChangeInformationImageFilter<TInputImage>
+::RemoveKeyFromDictionary(itk::MetaDataDictionary & dict, const std::string & key)
+{
+  std::vector<std::string> keyList = dict.GetKeys();
+  std::vector<std::string>::iterator pos = keyList.begin();
+  while (pos != keyList.end())
+    {
+    if (key.compare(*pos) == 0)
+      {
+      break;
+      }
+    ++pos;
+    }
+  if (pos != keyList.end())
+    {
+    itk::MetaDataDictionary copyDict;
+    keyList.erase(pos);
+    pos = keyList.begin();
+    for ( ; pos != keyList.end();++pos)
+      {
+      copyDict.Set(*pos, const_cast<itk::MetaDataObjectBase*>(dict.Get(*pos)));
+      }
+    dict = copyDict;
+    return true;
+    }
+  return false;
+}
+
+} // End of namespace OTB
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
index 86e9cd72c67dca156fc4fd293c9b220ff186fc21..3019412f1434a6242298ef6d9fc9eff55aa520d2 100644
--- a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
+++ b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
@@ -75,6 +75,7 @@ otbOneRIBandImageToOneComplexBandImage.cxx
 otbTwoNRIBandsImageToNComplexBandsImage.cxx
 otbChangeNoDataValueFilter.cxx
 otbImageToNoDataMaskFilter.cxx
+otbChangeInformationImageFilter.cxx
 )
 
 add_executable(otbImageManipulationTestDriver ${OTBImageManipulationTests})
@@ -710,3 +711,8 @@ otb_add_test(NAME filteringImageManipulationChangeNoDataValueFilter COMMAND otbI
 
 otb_add_test(NAME filteringImageManipulationImageToNoDataMaskFilter COMMAND otbImageManipulationTestDriver
   otbImageToNoDataMaskFilter)
+
+otb_add_test(NAME bfTvChangeInformationImageFilter COMMAND  otbImageManipulationTestDriver
+  otbChangeInformationImageFilter
+  ${INPUTDATA}/WV2_PAN_ROI_1000_100.tif
+  )
diff --git a/Modules/Filtering/ImageManipulation/test/otbChangeInformationImageFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbChangeInformationImageFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2a6a7e2a904cee67cfa8d15e7bf7d3be65126ece
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbChangeInformationImageFilter.cxx
@@ -0,0 +1,66 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "otbChangeInformationImageFilter.h"
+#include "otbImageFileReader.h"
+#include "otbImage.h"
+
+int otbChangeInformationImageFilter(int itkNotUsed(argc), char * argv[])
+{
+  const char *inputFilename(argv[1]);
+
+  typedef otb::Image<float,2> ImageType;
+  typedef otb::ChangeInformationImageFilter<ImageType> FilterType;
+  typedef otb::ImageFileReader<ImageType> ReaderType;
+  
+  ReaderType::Pointer reader = ReaderType::New();
+  reader->SetFileName(inputFilename);
+  
+  FilterType::Pointer filter = FilterType::New();
+  filter->SetInput(reader->GetOutput());
+  // try to set a different ProjRef
+  std::string newProj("Fake ProjRef");
+  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey,&newProj);
+  // erase that choice
+  filter->SetOutputMetaData<std::string>(otb::MetaDataKey::ProjectionRefKey,NULL);
+  // add a no data to the image
+  std::vector<bool> flags;
+  flags.push_back(true);
+  std::vector<double> nodata;
+  nodata.push_back(0.0);
+  filter->SetOutputMetaData<std::vector<bool> >(otb::MetaDataKey::NoDataValueAvailable,&flags);
+  filter->SetOutputMetaData<std::vector<double> >(otb::MetaDataKey::NoDataValue,&nodata);
+  filter->UpdateOutputInformation();
+
+  ImageType::Pointer outImage = filter->GetOutput();
+  if (! outImage->GetProjectionRef().empty())
+    {
+    std::cout << "Projection is supposed to be removed but is still present !" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  itk::MetaDataDictionary &dict = outImage->GetMetaDataDictionary();
+  if (!dict.HasKey(otb::MetaDataKey::NoDataValueAvailable) ||
+      !dict.HasKey(otb::MetaDataKey::NoDataValue))
+    {
+    std::cout << "Missing no data metadata !" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  return EXIT_SUCCESS;
+}
+
diff --git a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
index f732d0d2a493a927ccfd34f1f5633d85b3508cf3..299f6744511b2d781a1f5a0d973b4c122c44674b 100644
--- a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
@@ -81,4 +81,5 @@ void RegisterTests()
   REGISTER_TEST(otbTwoNRIBandsImageToNComplexBandsImage);
   REGISTER_TEST(otbChangeNoDataValueFilter);
   REGISTER_TEST(otbImageToNoDataMaskFilter);
+  REGISTER_TEST(otbChangeInformationImageFilter);
 }
diff --git a/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.h b/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.h
index 39d04f689ad6bb90b695073cb6a4a32c9b8e6685..ce25b90ecedb1db3c54530bac7ffd8b0d9f3bfe7 100644
--- a/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.h
+++ b/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.h
@@ -164,6 +164,7 @@ protected:
                      const KernelIteratorType kernelBegin,
                      const KernelIteratorType kernelEnd);
 
+  virtual void GenerateOutputInformation();
 
 private:
   NeighborhoodMajorityVotingImageFilter(const Self&); //purposely not implemented
diff --git a/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.txx b/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.txx
index 2889cf1d861de2ec69193924e94da97db67d565c..93c05d6b2034c637528cfaecec84e7e69a9fc89b 100644
--- a/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.txx
+++ b/Modules/Fusion/MajorityVoting/include/otbNeighborhoodMajorityVotingImageFilter.txx
@@ -23,6 +23,9 @@
 // gets integrated into the main directories.
 
 #include "otbNeighborhoodMajorityVotingImageFilter.h"
+#include "itkDefaultConvertPixelTraits.h"
+#include "itkMetaDataObject.h"
+#include "otbMetaDataKey.h"
 
 namespace otb
 {
@@ -118,6 +121,30 @@ const KernelIteratorType kernelEnd)
   return majorityLabel;
 }
 
+template<class TInputImage, class TOutputImage, class TKernel>
+void
+NeighborhoodMajorityVotingImageFilter<TInputImage, TOutputImage, TKernel>
+::GenerateOutputInformation()
+{
+  Superclass::GenerateOutputInformation();
+
+  TOutputImage* outputPtr = this->GetOutput();
+
+  // Set the NoData value using the background
+  const unsigned int & nbBands =  outputPtr->GetNumberOfComponentsPerPixel();
+  std::vector<bool> noDataValueAvailable;
+  noDataValueAvailable.resize(nbBands,true);
+  std::vector<double> noDataValue;
+  noDataValue.resize(nbBands,0.0);
+  for (unsigned int i=0 ; i<nbBands ; ++i)
+    {
+    noDataValue[i] = itk::DefaultConvertPixelTraits<PixelType>::GetNthComponent(i,m_LabelForNoDataPixels);
+    }
+  itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
+  itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
+}
+
 } // end namespace otb
 
 #endif
diff --git a/Modules/Fusion/MajorityVoting/otb-module.cmake b/Modules/Fusion/MajorityVoting/otb-module.cmake
index bc585bf62a7088aa2ca551d384bcc6f9d011b36b..8643c503476f640fd87ad82754cfb97720c56a8b 100644
--- a/Modules/Fusion/MajorityVoting/otb-module.cmake
+++ b/Modules/Fusion/MajorityVoting/otb-module.cmake
@@ -5,6 +5,7 @@ this label value (see also DempsterShafer module).")
 otb_module(OTBMajorityVoting
   DEPENDS
     OTBITK
+    OTBOSSIMAdapters
 
   TEST_DEPENDS
     OTBTestKernel
diff --git a/Modules/IO/IOGDAL/include/otbOGRIOHelper.h b/Modules/IO/IOGDAL/include/otbOGRIOHelper.h
index baf02bd4ee213ec10f1c7d4c3591afd8d767effe..6df03e24d743bccc4c4c5cb2a2858a1c2bf0c0d4 100644
--- a/Modules/IO/IOGDAL/include/otbOGRIOHelper.h
+++ b/Modules/IO/IOGDAL/include/otbOGRIOHelper.h
@@ -21,8 +21,9 @@
 #include <vector>
 
 #include "otbVectorData.h"
+#include "otbOGRVersionProxy.h"
 
-class OGRDataSource;
+class GDALDataset;
 class OGRGeometryCollection;
 class OGRLayer;
 class OGRSpatialReference;
@@ -63,14 +64,14 @@ public:
 
 
   unsigned int ProcessNodeWrite(InternalTreeNodeType * source,
-                                OGRDataSource * m_DataSource,
+                                ogr::version_proxy::GDALDatasetType * m_DataSource,
                                 OGRGeometryCollection * ogrCollection,
                                 OGRLayer * ogrCurrentLayer,
                                 OGRSpatialReference * oSRS);
 
   /** Return a list of OGRLayer * */
   std::vector<OGRLayer*> ConvertDataTreeNodeToOGRLayers(InternalTreeNodeType * source,
-                                                        OGRDataSource * dummyDatasource,
+                                                        ogr::version_proxy::GDALDatasetType * dummyDatasource,
                                                         OGRLayer* ogrCurrentLayer,
                                                         OGRSpatialReference * oSRS);
 
diff --git a/Modules/IO/IOGDAL/include/otbOGRVectorDataIO.h b/Modules/IO/IOGDAL/include/otbOGRVectorDataIO.h
index f7ae24d3dac2171d7a1ecabc928546a98fa6538a..45f89b75d23d1659d7d201bcaa5633d7e20f345e 100644
--- a/Modules/IO/IOGDAL/include/otbOGRVectorDataIO.h
+++ b/Modules/IO/IOGDAL/include/otbOGRVectorDataIO.h
@@ -23,7 +23,7 @@
 #include "otbVectorDataIOBase.h"
 #include "otbVectorData.h"
 
-class OGRDataSource;
+#include "otbOGRVersionProxy.h"
 
 namespace otb
 {
@@ -116,7 +116,7 @@ private:
 
   std::string GetOGRDriverName(std::string name) const;
 
-  OGRDataSource * m_DataSource;
+  ogr::version_proxy::GDALDatasetType * m_DataSource;
 
 };
 
diff --git a/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx b/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
index 4216a78fa1613a42be710769db43a657ac8a25ff..6cc3890ac278ad4b67c9731e58aadea10694e3bb 100644
--- a/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
+++ b/Modules/IO/IOGDAL/src/otbOGRIOHelper.cxx
@@ -649,7 +649,7 @@ void OGRIOHelper
 
 unsigned int OGRIOHelper
 ::ProcessNodeWrite(InternalTreeNodeType * source,
-                   OGRDataSource * m_DataSource,
+                   ogr::version_proxy::GDALDatasetType * m_DataSource,
                    OGRGeometryCollection * ogrCollection,
                    OGRLayer * ogrCurrentLayer,
                    OGRSpatialReference * oSRS)
@@ -1025,7 +1025,7 @@ unsigned int OGRIOHelper
  **/
 std::vector<OGRLayer*> OGRIOHelper
 ::ConvertDataTreeNodeToOGRLayers(InternalTreeNodeType * source,
-                                 OGRDataSource * inMemoryDataSource,
+                                 ogr::version_proxy::GDALDatasetType * inMemoryDataSource,
                                  OGRLayer* ogrCurrentLayer,
                                  OGRSpatialReference * oSRS)
 {
@@ -1034,8 +1034,8 @@ std::vector<OGRLayer*> OGRIOHelper
   if (inMemoryDataSource == NULL)
     {
     const char * driverName = "Memory";
-    OGRSFDriver * ogrDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driverName);
-    inMemoryDataSource = ogrDriver->CreateDataSource("tempDataSource",NULL);
+    ogr::version_proxy::GDALDriverType * ogrDriver = ogr::version_proxy::GetDriverByName(driverName);
+    inMemoryDataSource = ogr::version_proxy::Create(ogrDriver,"tempDataSource");
     }
 
   std::vector<OGRLayer*>  ogrLayerVector;
diff --git a/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx b/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
index cd2b744bda57b013c9c54cb9b0a6935386aab6da..75da823e3f873c64a8d7b969de141a8acd2bd290 100644
--- a/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
+++ b/Modules/IO/IOGDAL/src/otbOGRVectorDataIO.cxx
@@ -46,7 +46,7 @@ OGRVectorDataIO::~OGRVectorDataIO()
 {
   if (m_DataSource != NULL)
     {
-    OGRDataSource::DestroyDataSource(m_DataSource);
+    otb::ogr::version_proxy::Close(m_DataSource);
     }
 }
 
@@ -54,13 +54,15 @@ OGRVectorDataIO::~OGRVectorDataIO()
 bool
 OGRVectorDataIO::CanReadFile(const char* filename) const
 {
-  OGRDataSource * poDS = OGRSFDriverRegistrar::Open(filename, FALSE);
+  otb::ogr::version_proxy::GDALDatasetType * poDS = ogr::version_proxy::Open(filename, true);
+  
   if (poDS == NULL)
     {
+    std::cerr<<"Can not read file "<<filename<<" with GDALOpen"<<std::endl;
     return false;
     }
 //     std::cout << poDS->GetDriver()->GetName() << std::endl;
-  OGRDataSource::DestroyDataSource(poDS);
+  ogr::version_proxy::Close(poDS);
   return true;
 }
 
@@ -88,10 +90,10 @@ OGRVectorDataIO
 
   if (m_DataSource != NULL)
     {
-    OGRDataSource::DestroyDataSource(m_DataSource);
+    ogr::version_proxy::Close(m_DataSource);
     }
 
-  m_DataSource = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), FALSE);
+  m_DataSource = ogr::version_proxy::Open(this->m_FileName.c_str(),true);
 
   if (m_DataSource == NULL)
     {
@@ -176,7 +178,7 @@ OGRVectorDataIO
 
     } // end For each layer
 
-  OGRDataSource::DestroyDataSource(m_DataSource);
+  GDALClose(m_DataSource);
   m_DataSource = NULL;
 }
 
@@ -194,7 +196,7 @@ bool OGRVectorDataIO::CanWriteFile(const char* filename) const
 }
 
 
-void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** papszOptions)
+void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** /** unused */)
 {
   itk::TimeProbe chrono;
   chrono.Start();
@@ -208,8 +210,8 @@ void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** papszOptions)
 
 
   //Find first the OGR driver
-  OGRSFDriver * ogrDriver =
-    OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(this->GetOGRDriverName(this->m_FileName).data());
+  ogr::version_proxy::GDALDriverType * ogrDriver =
+    ogr::version_proxy::GetDriverByName(this->GetOGRDriverName(this->m_FileName).data());
 
   if (ogrDriver == NULL)
     {
@@ -219,25 +221,14 @@ void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** papszOptions)
   // free an existing previous data source, if any
   if (m_DataSource != NULL)
     {
-    OGRDataSource::DestroyDataSource(m_DataSource);
+    ogr::version_proxy::Close(m_DataSource);
     }
 
   // Erase the dataSource if already exist
-  //TODO investigate the possibility of giving the option OVERWRITE=YES to the CreateDataSource method
-  OGRDataSource * poDS = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), TRUE);
-  if (poDS != NULL)
-    {
-    //Erase the data if possible
-    if (poDS->GetDriver()->TestCapability(ODrCDeleteDataSource))
-      {
-      //Delete datasource
-      poDS->GetDriver()->DeleteDataSource(this->m_FileName.c_str());
-      }
-    }
-  OGRDataSource::DestroyDataSource(poDS);
+  ogr::version_proxy::Delete(this->m_FileName.c_str());
 
   // m_DataSource = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), TRUE);
-  m_DataSource = ogrDriver->CreateDataSource(this->m_FileName.c_str(), papszOptions);
+  m_DataSource = ogr::version_proxy::Create(ogrDriver,this->m_FileName.c_str());
 
   // check the created data source
   if (m_DataSource == NULL)
@@ -292,7 +283,7 @@ void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** papszOptions)
   otbMsgDevMacro( << "layerKept " << layerKept );
   (void)layerKept; // keep compiler happy
 
-  OGRDataSource::DestroyDataSource(m_DataSource);
+  otb::ogr::version_proxy::Close(m_DataSource);
   m_DataSource = NULL;
 
   if (oSRS != NULL)
diff --git a/Modules/IO/TestKernel/src/otbTestHelper.cxx b/Modules/IO/TestKernel/src/otbTestHelper.cxx
index ab256ff3ef14e56f136b288279f2453a8af87264..bf7996740b24b70b0bf6475636da3616b7f02dd3 100644
--- a/Modules/IO/TestKernel/src/otbTestHelper.cxx
+++ b/Modules/IO/TestKernel/src/otbTestHelper.cxx
@@ -27,6 +27,8 @@
 #include <algorithm>
 #include <string>
 
+#include "ogrsf_frmts.h"
+
 #include "itksys/SystemTools.hxx"
 #include "itksys/Directory.hxx"
 #include "itksys/RegularExpression.hxx"
@@ -37,6 +39,9 @@
 #include "otbDifferenceImageFilter.h"
 #include "otbPrintableImageFilter.h"
 #include "otbStreamingShrinkImageFilter.h"
+#include "otbOGRVersionProxy.h"
+
+#include "otbConfigure.h"
 
 #define ITK_TEST_DIMENSION_MAX 6
 
@@ -44,16 +49,6 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 #include "cpl_multiproc.h"
-#include "ogr_api.h"
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-#include "ogrsf_frmts.h"
-#pragma GCC diagnostic pop
-#else
-#include "ogrsf_frmts.h"
-#endif
 
 #define otbPrintDiff(comment, refStr, testStr) \
   std::cout << "   ----    '" << comment << "' checking   ---------------------------" << std::endl; \
@@ -1074,33 +1069,33 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b
   /* -------------------------------------------------------------------- */
   /*      Open data source.                                               */
   /* -------------------------------------------------------------------- */
-  OGRDataSource *ref_poDS = NULL;
-  OGRSFDriver *  ref_poDriver = NULL;
+  otb::ogr::version_proxy::GDALDatasetType *ref_poDS = NULL;
+  otb::ogr::version_proxy::GDALDriverType *  ref_poDriver = NULL;
   //OGRGeometry *  ref_poSpatialFilter = NULL;
-  OGRDataSource *test_poDS = NULL;
-  OGRSFDriver *  test_poDriver = NULL;
+  otb::ogr::version_proxy::GDALDatasetType *test_poDS = NULL;
+  otb::ogr::version_proxy::GDALDriverType *  test_poDriver = NULL;
   //OGRGeometry *  test_poSpatialFilter = NULL;
 
-  OGRRegisterAll();
-
-  ref_poDS = OGRSFDriverRegistrar::Open(ref_pszDataSource, !bReadOnly, &ref_poDriver);
+  ref_poDS = otb::ogr::version_proxy::Open(ref_pszDataSource, false);
   if (ref_poDS == NULL && !bReadOnly)
     {
-    ref_poDS = OGRSFDriverRegistrar::Open(ref_pszDataSource, FALSE, &ref_poDriver);
+    ref_poDS = otb::ogr::version_proxy::Open(ref_pszDataSource, true);
+    bReadOnly = TRUE;
     if (ref_poDS != NULL && m_ReportErrors)
       {
-      std::cout << "Had to open REF data source read-only.\n";
-      bReadOnly = TRUE;
+      std::cout << "Had to open REF data source read-only."<<std::endl;
       }
     }
-  test_poDS = OGRSFDriverRegistrar::Open(test_pszDataSource, !bReadOnly, &test_poDriver);
+  test_poDS = otb::ogr::version_proxy::Open(ref_pszDataSource, bReadOnly);
   if (test_poDS == NULL && !bReadOnly)
     {
-    test_poDS = OGRSFDriverRegistrar::Open(test_pszDataSource, FALSE, &test_poDriver);
+    test_poDS = otb::ogr::version_proxy::Open(ref_pszDataSource, bReadOnly);
+
+    bReadOnly = TRUE;
+    
     if (test_poDS != NULL && m_ReportErrors)
       {
-      std::cout << "Had to open REF data source read-only.\n";
-      bReadOnly = TRUE;
+      std::cout << "Had to open TEST data source read-only."<<std::endl;
       }
     }
   /* -------------------------------------------------------------------- */
@@ -1108,51 +1103,69 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b
   /* -------------------------------------------------------------------- */
   if (ref_poDS == NULL)
     {
-    OGRSFDriverRegistrar *ref_poR = OGRSFDriverRegistrar::GetRegistrar();
-
+   
     if (m_ReportErrors)
-      std::cout << "FAILURE:\n"
-      "Unable to open REF datasource `" << ref_pszDataSource << "' with the following drivers." << std::endl;
-    for (int iDriver = 0; iDriver < ref_poR->GetDriverCount(); ++iDriver)
       {
-      std::cout << "  -> " << ref_poR->GetDriver(iDriver)->GetName() << std::endl;
+      std::cout << "FAILURE:\n" "Unable to open REF datasource `" << ref_pszDataSource << "' with the following drivers." << std::endl;
+
+      std::vector<std::string> drivers = ogr::version_proxy::GetAvailableDriversAsStringVector();
+    
+      for (std::vector<std::string>::const_iterator it = drivers.begin();it!=drivers.end();++it)
+        {
+        std::cout << "  -> " << *it << std::endl;
+        }
       }
     return (1);
     }
+  ref_poDriver = ref_poDS->GetDriver();
   CPLAssert(ref_poDriver != NULL);
 
   if (test_poDS == NULL)
     {
-    OGRSFDriverRegistrar *test_poR = OGRSFDriverRegistrar::GetRegistrar();
-
     if (m_ReportErrors)
-      std::cout << "FAILURE:\n"
-      "Unable to open TEST datasource `" << test_pszDataSource << "' with the following drivers." << std::endl;
-    for (int iDriver = 0; iDriver < test_poR->GetDriverCount(); ++iDriver)
       {
-      std::cout << "  -> " << test_poR->GetDriver(iDriver)->GetName() << std::endl;
+      std::cout << "FAILURE:\n""Unable to open TEST datasource `" << test_pszDataSource << "' with the following drivers." << std::endl;
+
+      std::vector<std::string> drivers = ogr::version_proxy::GetAvailableDriversAsStringVector();
+      
+      for (std::vector<std::string>::const_iterator it = drivers.begin();it!=drivers.end();++it)
+        {
+        std::cout << "  -> " << *it << std::endl;
+        }
       }
     return (1);
     }
+  test_poDriver = test_poDS->GetDriver();
   CPLAssert(test_poDriver != NULL);
 
   /* -------------------------------------------------------------------- */
   /*      Some information messages.                                      */
   /* -------------------------------------------------------------------- */
-  otbCheckStringValue("INFO: using driver", ref_poDriver->GetName(), test_poDriver->GetName(), nbdiff, m_ReportErrors);
-
-  // std::string strRefName(ref_poDS->GetName());
-  // std::string strTestName(test_poDS->GetName());
-  // if (strRefName != strTestName)
-  //   {
-  //   if (!m_ReportErrors)
-  //     {
-  //     otbPrintDiff("WARNING: INFO: Internal data source name poDS->GetName() were different",
-  //                  strRefName,
-  //                  strTestName);
-  //     }
-  //   }
+  otbCheckStringValue("INFO: using driver", GDALGetDriverShortName(ref_poDriver), GDALGetDriverShortName(test_poDriver), nbdiff, m_ReportErrors);
 
+  // TODO: Improve this check as it will stop as soon as one of the
+  // list ends (i.e. it does not guarantee that all files are present)
+  std::vector<std::string> refFileList = otb::ogr::version_proxy::GetFileListAsStringVector(ref_poDS);
+  std::vector<std::string> testFileList = otb::ogr::version_proxy::GetFileListAsStringVector(test_poDS);
+
+  unsigned int fileId = 0;
+
+  while (fileId < refFileList.size() && fileId < testFileList.size())
+    {
+    std::string strRefName(refFileList[fileId]);
+    std::string strTestName(testFileList[fileId]);
+    if (strRefName != strTestName)
+      {
+      if (!m_ReportErrors)
+        {
+        otbPrintDiff("WARNING: INFO: Internal data source files were different",
+                     strRefName,
+                     strTestName);
+        }
+      }
+    ++fileId;
+    }
+  
   /* -------------------------------------------------------------------- */
   /*      Process each data source layer.                                 */
   /* -------------------------------------------------------------------- */
@@ -1240,8 +1253,8 @@ int TestHelper::RegressionTestOgrFile(const char *testOgrFilename, const char *b
   /* -------------------------------------------------------------------- */
   /*      Close down.                                                     */
   /* -------------------------------------------------------------------- */
-  OGRDataSource::DestroyDataSource( ref_poDS );
-  OGRDataSource::DestroyDataSource( test_poDS );
+  GDALClose( ref_poDS );
+  GDALClose( test_poDS );
 
   return (nbdiff != 0) ? 1 : 0;
 }
@@ -1256,7 +1269,7 @@ void TestHelper::DumpOGRFeature(FILE* fpOut, OGRFeature* feature, char** papszOp
     return;
     }
 
-  fprintf(fpOut, "OGRFeature:%ld\n", feature->GetFID());
+  fprintf(fpOut, "OGRFeature:%lld\n", feature->GetFID());
 
   const char* pszDisplayFields =
     CSLFetchNameValue(papszOptions, "DISPLAY_FIELDS");
@@ -1374,6 +1387,8 @@ void TestHelper::DumpOGRGeometry(FILE* fp, OGRGeometry* geometry, const char * p
         }
       case wkbLinearRing:
         break;
+      default:
+        break;
       }
     }
   else if (pszDisplayGeometry == NULL || CSLTestBoolean(pszDisplayGeometry) ||
diff --git a/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.h b/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.h
index 2c3810858082feca40b6b6296f7df821aa1fa964..84b093f8c167c6985890be5a9e9c888b4dd2c8d6 100644
--- a/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.h
+++ b/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.h
@@ -139,6 +139,8 @@ protected:
   /** Destructor */
   virtual ~DSFusionOfClassifiersImageFilter() {}
 
+  /** Generate output information */
+  virtual void GenerateOutputInformation();
   /** Threaded generate data */
   virtual void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId);
   /** Before threaded generate data */
diff --git a/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.txx b/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.txx
index 65c577151dec44cbe7000adf8facf2b398c1891c..5305fa3d368444bf63e6e70cfbc630c11d51436d 100644
--- a/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.txx
+++ b/Modules/Learning/DempsterShafer/include/otbDSFusionOfClassifiersImageFilter.txx
@@ -22,6 +22,9 @@
 #include "itkImageRegionIterator.h"
 #include "itkProgressReporter.h"
 
+#include "itkMetaDataObject.h"
+#include "otbMetaDataKey.h"
+
 namespace otb
 {
 /**
@@ -84,6 +87,23 @@ DSFusionOfClassifiersImageFilter<TInputImage, TOutputImage, TMaskImage>
 }
 /* ************************************************************************************************************** */
 
+template <class TInputImage, class TOutputImage, class TMaskImage>
+void
+DSFusionOfClassifiersImageFilter<TInputImage, TOutputImage, TMaskImage>
+::GenerateOutputInformation()
+{
+  Superclass::GenerateOutputInformation();
+
+  // Set the NoData value
+  std::vector<bool> noDataValueAvailable;
+  noDataValueAvailable.push_back(true);
+  std::vector<double> noDataValue;
+  noDataValue.push_back(m_LabelForNoDataPixels);
+  itk::MetaDataDictionary& dict = this->GetOutput()->GetMetaDataDictionary();
+  itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
+}
+/* ************************************************************************************************************** */
 
 template <class TInputImage, class TOutputImage, class TMaskImage>
 void
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h
index 541afff72d4dc35ffc3ae3055abda78f4ef74846..1331f740d5e4991b9d77d540019f003922baf2a6 100644
--- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h
+++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.h
@@ -18,13 +18,11 @@
 #ifndef __otbSarRadiometricCalibrationFunction_h
 #define __otbSarRadiometricCalibrationFunction_h
 
-#include "otbSarRadiometricCalibrationFunctor.h"
 #include "otbSarParametricMapFunction.h"
-
-
+#include "otbSarCalibrationLookupData.h"
+#include "otbMath.h"
 namespace otb
 {
-
 /**
  * \class SarRadiometricCalibrationFunction
  * \brief Calculate the backscatter for the given pixel
@@ -71,33 +69,31 @@ public:
 
   itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension);
 
-
   /** Datatype used for the evaluation */
   typedef double                                                 RealType;
-  typedef otb::Functor::SarRadiometricCalibrationFunctor<RealType, RealType>           FunctorType;
-  typedef typename FunctorType::RealType                        FunctorRealType;
+//  typedef otb::Functor::SarRadiometricCalibrationFunctor<RealType, RealType>           FunctorType;
+//  typedef typename FunctorType::RealType                        FunctorRealType;
 
   typedef otb::SarParametricMapFunction<InputImageType>               ParametricFunctionType;
   typedef typename ParametricFunctionType::Pointer                    ParametricFunctionPointer;
   typedef typename ParametricFunctionType::ConstPointer               ParametricFunctionConstPointer;
 
-  /** Evaluate the function at non-integer positions */
-  virtual OutputType Evaluate(const PointType& point) const;
-
   /** Evalulate the function at specified index */
-  virtual OutputType EvaluateAtIndex(const IndexType& index) const
+  virtual OutputType EvaluateAtIndex(const IndexType& index) const;
+
+  /** Evaluate the function at non-integer positions */
+  virtual OutputType Evaluate(const PointType& point) const
   {
-    PointType point;
-    this->GetInputImage()->TransformIndexToPhysicalPoint( index, point);
-    return this->Evaluate(point);
+    IndexType index;
+    this->ConvertPointToNearestIndex(point, index);
+    return this->EvaluateAtIndex(index);
   }
 
-  virtual OutputType EvaluateAtContinuousIndex(
-    const ContinuousIndexType& cindex) const
+  virtual OutputType EvaluateAtContinuousIndex(const ContinuousIndexType& cindex) const
   {
-    PointType point;
-    this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( cindex, point);
-    return this->Evaluate(point);
+    IndexType index;
+    this->ConvertContinuousIndexToNearestIndex(cindex, index);
+    return this->EvaluateAtIndex(index);
   }
 
   /** Set the input image.
@@ -108,10 +104,10 @@ public:
 
 
   /** Get/Set the Scale value */
-  itkSetMacro(Scale, FunctorRealType);
-  itkGetMacro(Scale, FunctorRealType);
+  itkSetMacro(Scale, RealType);
+  itkGetMacro(Scale, RealType);
 
-  /** Get/Set the Offset value */
+  /** Get/Set the Noise value */
   itkSetObjectMacro(Noise, ParametricFunctionType);
   itkGetConstObjectMacro(Noise, ParametricFunctionType);
   itkGetObjectMacro(Noise, ParametricFunctionType);
@@ -140,23 +136,66 @@ public:
   itkGetConstObjectMacro(RangeSpreadLoss, ParametricFunctionType);
   itkGetObjectMacro(RangeSpreadLoss, ParametricFunctionType);
 
+  /** Set the RescalingFactor value */
+  itkSetMacro(RescalingFactor, RealType);
+
+  /** Get/Set flag to indicate if these are used */
+  itkSetMacro(ApplyAntennaPatternGain, bool);
+  itkGetMacro(ApplyAntennaPatternGain, bool);
+
+  itkSetMacro(ApplyIncidenceAngleCorrection, bool);
+  itkGetMacro(ApplyIncidenceAngleCorrection, bool);
+
+  itkSetMacro(ApplyRangeSpreadLossCorrection, bool);
+  itkGetMacro(ApplyRangeSpreadLossCorrection, bool);
+
+  itkSetMacro(ApplyLookupDataCorrection, bool);
+  itkGetMacro(ApplyLookupDataCorrection, bool);
+
+  itkSetMacro(ApplyRescalingFactor, bool);
+  itkGetMacro(ApplyRescalingFactor, bool);
+
+    typedef SarCalibrationLookupData::Pointer LookupDataPointer;
+
+  /** Set SetCalibrationLookupData instance */
+  void SetCalibrationLookupData(LookupDataPointer lut)
+  {
+    m_Lut = lut;
+  }
 
 protected:
+
+  /** ctor */
   SarRadiometricCalibrationFunction();
+
+  /** default, empty, virtual dtor */
   virtual ~SarRadiometricCalibrationFunction(){}
+
+  /** print method */
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
+  /** Flags to indiciate if these values needs to be applied in calibration*/
+
 private:
   SarRadiometricCalibrationFunction(const Self &);  //purposely not implemented
   void operator =(const Self&);  //purposely not implemented
 
-  FunctorRealType             m_Scale;
-  ParametricFunctionPointer   m_Noise;
+  RealType             m_Scale;
   bool                        m_EnableNoise;
+  RealType             m_RescalingFactor;
+  bool                        m_ApplyAntennaPatternGain;
+  bool                        m_ApplyIncidenceAngleCorrection;
+  bool                        m_ApplyRangeSpreadLossCorrection;
+  bool                        m_ApplyLookupDataCorrection;
+  bool                        m_ApplyRescalingFactor;
+  ParametricFunctionPointer   m_Noise;
   ParametricFunctionPointer   m_AntennaPatternNewGain;
   ParametricFunctionPointer   m_AntennaPatternOldGain;
   ParametricFunctionPointer   m_IncidenceAngle;
   ParametricFunctionPointer   m_RangeSpreadLoss;
+  LookupDataPointer   m_Lut;
+
+
 };
 
 } // end namespace otb
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx
index b04ee4c8fc450006826cf3db1f5ad80777ca518b..4e22a24c59b7c33f252a95064f96446eae88a47a 100644
--- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx
+++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunction.txx
@@ -24,27 +24,38 @@
 
 namespace otb
 {
-
 /**
  * Constructor
  */
 template <class TInputImage, class TCoordRep>
 SarRadiometricCalibrationFunction<TInputImage, TCoordRep>
-::SarRadiometricCalibrationFunction():
-  m_Scale(1.0)
+::SarRadiometricCalibrationFunction()
+: m_Scale(1.0)
+, m_EnableNoise(false)
+, m_RescalingFactor(1.0)
+, m_ApplyAntennaPatternGain(true)
+, m_ApplyIncidenceAngleCorrection(true)
+, m_ApplyRangeSpreadLossCorrection(true)
+, m_ApplyLookupDataCorrection(false)
+, m_ApplyRescalingFactor(false)
+
 {
+  /* intialize parametric functions */
   m_Noise = ParametricFunctionType::New();
   m_AntennaPatternNewGain = ParametricFunctionType::New();
   m_AntennaPatternOldGain = ParametricFunctionType::New();
   m_IncidenceAngle = ParametricFunctionType::New();
   m_RangeSpreadLoss = ParametricFunctionType::New();
 
+  /* intialize default values in paramerticFunction instances  */
   m_Noise->SetConstantValue(0.0);
-  m_EnableNoise = true;
   m_AntennaPatternNewGain->SetConstantValue(1.0);
   m_AntennaPatternOldGain->SetConstantValue(1.0);
   m_IncidenceAngle->SetConstantValue(CONST_PI_2);
   m_RangeSpreadLoss->SetConstantValue(1.0);
+
+//  m_Lut = 0; //new LookupTableBase();
+
 }
 
 /**
@@ -65,7 +76,7 @@ SarRadiometricCalibrationFunction<TInputImage, TCoordRep>
 }
 
 /**
- *
+ * Print
  */
 template <class TInputImage, class TCoordRep>
 void
@@ -75,23 +86,16 @@ SarRadiometricCalibrationFunction<TInputImage, TCoordRep>
   this->Superclass::PrintSelf(os, indent);
 }
 
-/**
- *
- */
+/* Function: EvaluateAtIndex. This computes the required values for each pixel
+* whose index is given in indexType argument. To convert index to point it uses
+* InputImage::TransformIndexToPhysicalPoint(). IncidenceAngle and similar are
+* computed based on this calculated point in SarParametricFunction   */
 template <class TInputImage, class TCoordRep>
 typename SarRadiometricCalibrationFunction<TInputImage, TCoordRep>
 ::OutputType
 SarRadiometricCalibrationFunction<TInputImage, TCoordRep>
-::Evaluate(const PointType& point) const
+::EvaluateAtIndex(const IndexType& index) const
 {
-  IndexType index;
-  this->GetInputImage()->TransformPhysicalPointToIndex(point, index);
-
-  if (!this->GetInputImage())
-    {
-    itkDebugMacro( <<"ERROR with GetInputImage()");
-    return (itk::NumericTraits<OutputType>::max());
-    }
 
   if (!this->IsInsideBuffer(index))
     {
@@ -99,21 +103,69 @@ SarRadiometricCalibrationFunction<TInputImage, TCoordRep>
     return (itk::NumericTraits<OutputType>::max());
     }
 
-  FunctorType functor;
+  /* convert index to point */
+  PointType point;
+  if (m_ApplyAntennaPatternGain || m_ApplyIncidenceAngleCorrection || m_ApplyRangeSpreadLossCorrection)
+    this->GetInputImage()->TransformIndexToPhysicalPoint( index, point);
+
+  /** digitalNumber:
+    * For complex pixel type, vcl_abs() returns the modulus. which is
+    * sqrt((I*I) + (Q*Q)). Where I and Q are real and imaginary part of the
+    * complex pixel. So to to get (I*I) + (Q*Q) in our calculation, the output
+    * of vcl_abs() is squared. See below (digitalNumber * digitalNumber) where
+    * digitalNumber is the output of vcl_abs() which is sqrt((I*I) + (Q*Q)). For
+    * non-complex pixel types, vcl_abs() simply returns absolute value.
+    */
+
+  RealType digitalNumber = static_cast<RealType>(vcl_abs(this->GetInputImage()->GetPixel(index)));
+  RealType sigma = m_Scale * digitalNumber * digitalNumber;
+
+  /** substract noise if enabled. */
   if (m_EnableNoise)
     {
-    functor.SetNoise(static_cast<FunctorRealType>(m_Noise->Evaluate(point)));
+    sigma  -= static_cast<RealType>(m_Noise->Evaluate(point));
+    }
+
+  /** Apply incidence angle correction if needed */
+  if (m_ApplyIncidenceAngleCorrection)
+    {
+    sigma *= vcl_sin(static_cast<RealType>(m_IncidenceAngle->Evaluate(point)));
     }
-  functor.SetScale(m_Scale);
-  functor.SetAntennaPatternNewGain(static_cast<FunctorRealType>(m_AntennaPatternNewGain->Evaluate(point)));
-  functor.SetAntennaPatternOldGain(static_cast<FunctorRealType>(m_AntennaPatternOldGain->Evaluate(point)));
-  functor.SetIncidenceAngle(static_cast<FunctorRealType>(m_IncidenceAngle->Evaluate(point)));
-  functor.SetRangeSpreadLoss(static_cast<FunctorRealType>(m_RangeSpreadLoss->Evaluate(point)));
 
-  const RealType value = static_cast<RealType>(vcl_abs(this->GetInputImage()->GetPixel(index)));
-  RealType result = functor(value);
+  /** Apply old and new antenna pattern gain. */
+  if (m_ApplyAntennaPatternGain)
+    {
+    sigma *= static_cast<RealType>(m_AntennaPatternNewGain->Evaluate(point));
+    sigma /= static_cast<RealType>(m_AntennaPatternOldGain->Evaluate(point));
+    }
+
+  /** Apply range spread loss if needed. */
+  if (m_ApplyRangeSpreadLossCorrection)
+    {
+    sigma *= static_cast<RealType>(m_RangeSpreadLoss->Evaluate(point));
+    }
+
+  /** Lookup value has effect on for some sensors which does not required the
+    * above values (incidence angle, rangespreadloss etc.. */
+  if (m_ApplyLookupDataCorrection)
+    {
+    RealType lutVal = static_cast<RealType>(m_Lut->GetValue(index[0], index[1]));
+    sigma /= lutVal * lutVal;
+    }
+
+  /** rescaling factor has effect only with CosmoSkymed Products */
+  if (m_ApplyRescalingFactor)
+    {
+    sigma /= m_RescalingFactor;
+    }
+
+
+  if(sigma < 0.0)
+    {
+    sigma = 0.0;
+    }
 
-  return static_cast<OutputType>(result);
+  return static_cast<OutputType>(sigma);
 }
 
 } // end namespace otb
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunctor.h b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunctor.h
deleted file mode 100644
index db02de332b500272b71d92b3844816cf81d6f628..0000000000000000000000000000000000000000
--- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationFunctor.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*=========================================================================
-
-  Program:   ORFEO Toolbox
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
-
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-
-#ifndef __otbSarRadiometricCalibrationFunctor_h
-#define __otbSarRadiometricCalibrationFunctor_h
-
-#include "otbMath.h"
-#include "itkNumericTraits.h"
-
-namespace otb
-{
-
-namespace Functor
-{
-/**
- * \class SarRadiometricCalibrationFunctor
- * \brief Compute the backscatter value.
- *  \f$ \sigma^{0} = (scale * DN^{2} + offset) * sin( \theta_{inc}) * OldGain / NewGain * RangeSpreadLoss \f$
- *
- *
- * \ingroup OTBSARCalibration
- */
-template<class TInput, class TOutput>
-class ITK_EXPORT SarRadiometricCalibrationFunctor
-{
-public:
-  typedef TInput                                            InputType;
-  typedef TOutput                                           OutputType;
-  typedef typename itk::NumericTraits<InputType>::AbsType   RealType;
-
-  SarRadiometricCalibrationFunctor()
-  {
-    m_Noise = 0.0;
-    m_Scale = 1.0;
-    m_IncidenceAngle = CONST_PI_2;
-    m_AntennaPatternOldGain = 1.0;
-    m_AntennaPatternNewGain = 1.0;
-    m_RangeSpreadLoss = 1.0;
-  };
-
-  ~SarRadiometricCalibrationFunctor(){};
-
-  inline TOutput operator ()(const TInput& value) const
-  {
-    RealType digitalNumber = static_cast<RealType> (vcl_abs(value));
-    RealType sigma;
-
-    sigma  = m_Scale * (digitalNumber * digitalNumber - m_Noise);
-    sigma *= vcl_sin(m_IncidenceAngle);
-    sigma *= m_AntennaPatternOldGain;
-    sigma /= m_AntennaPatternNewGain;
-    sigma *= m_RangeSpreadLoss;
-
-    if(sigma < 0.0)
-    {
-      sigma = 0.0;
-    }
-
-    return static_cast<OutputType>(sigma);
-  }
-
-  /** Set offset method */
-  void SetNoise(RealType value)
-  {
-    m_Noise = value;
-  }
-
-  /** Get offset method */
-  RealType GetNoise() const
-  {
-    return m_Noise;
-  }
-
-  /** Set scale method */
-  void SetScale(RealType value)
-  {
-    m_Scale = value;
-  }
-
-  /** Get scale method */
-  RealType GetScale() const
-  {
-    return m_Scale;
-  }
-
-  /** Set antennaPatternNewGain method */
-  void SetAntennaPatternNewGain(RealType value)
-  {
-    m_AntennaPatternNewGain = value;
-  }
-
-  /** Get antennaPatternNewGain method */
-  RealType GetAntennaPatternNewGain() const
-  {
-    return m_AntennaPatternNewGain;
-  }
-
-  /** Set antennaPatternOldGain method */
-  void SetAntennaPatternOldGain(RealType value)
-  {
-    m_AntennaPatternOldGain = value;
-  }
-
-  /** Get antennaPatternOldGain method */
-  RealType GetAntennaPatternOldGain() const
-  {
-    return m_AntennaPatternOldGain;
-  }
-
-  /** Set incidenceAngle method */
-  void SetIncidenceAngle(RealType value)
-  {
-    m_IncidenceAngle = value;
-  }
-
-  /** Get incidenceAngle method */
-  RealType GetIncidenceAngle() const
-  {
-    return m_IncidenceAngle;
-  }
-
-  /** Set rangeSpreadLoss method */
-  void SetRangeSpreadLoss(RealType value)
-  {
-    m_RangeSpreadLoss = value;
-  }
-
-  /** Get scale method */
-  RealType GetRangeSpreadLoss() const
-  {
-    return m_RangeSpreadLoss;
-  }
-
-private:
-  RealType   m_Noise;
-  RealType   m_Scale;
-  RealType   m_AntennaPatternNewGain;
-  RealType   m_AntennaPatternOldGain;
-  RealType   m_IncidenceAngle;
-  RealType   m_RangeSpreadLoss;
-};
-}
-
-}
-
-#endif
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h
index 1212e9ae682de9b3f46e885d24efee34ebef12ba..523cdbccb1a8a4d3c37938df7435d87e696c7820 100644
--- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h
+++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.h
@@ -28,9 +28,29 @@ namespace otb
 {
 
 /** \class SarRadiometricCalibrationToImageFilter
-  * \brief Evaluates the SarRadiometricCalibrationFunction onto a source image
+ * \brief Evaluates the SarRadiometricCalibrationFunction onto a source image
+ * The BeforeThreadedGenerateData create a SarImageMetadataInterface based on
+ * input metadata dictionary. The nature of product(TerrSARX, Sentinel1, etc..)
+ * are thus detected  automatically from this. The filter then reads necessary
+ * parameters required to perform SarCalibration in a generic way.
  *
- * The function has to inherit from itkImageFunction
+ * BeforeThreadedGenerateData() instanciate a SarRadiometricCalibrationFunction
+ * and pass the values taken from SarImageMetadataInterface instance to it. This
+ * is where the actual computation of sigma (backscatter) occurs.
+ *
+ * Noise, Antenna pattern gain (old && new), range spread loss, incidence angle
+ * data members used in this class are all instances of SarPrametricFunction
+ * class. Each have a Evaluate() method and a special
+ * EvaluateParametricCoefficient() which computes the actual value.
+ *
+ * The technical details and more discussion of SarCalibration can be found in jira
+ * story #863.
+ *
+ * \see \c otb::SarParametricFunction
+ * \see \c otb::SarCalibrationLookupBase
+ * References (Retreived on 08-Sept-2015)
+ * Sentinel1 - https://sentinel.esa.int/web/sentinel/sentinel-1-sar-wiki/-/wiki/Sentinel%20One/Application+of+Radiometric+Calibration+LUT
+ * Radarsat2 - http://gs.mdacorporation.com/products/sensor/radarsat2/RS2_Product_Description.pdf
  *
  * \ingroup ImageFilters
  *
@@ -76,20 +96,37 @@ public:
   typedef typename FunctionType::ParametricFunctionConstPointer ParametricFunctionConstPointer;
   typedef typename FunctionType::ParametricFunctionType         ParametricFunctionType;
 
+
+  /** Enable/disable the noise flag in SarRadiometricCalibrationFunction */
   void SetEnableNoise(bool inArg)
   {
     this->GetFunction()->SetEnableNoise(inArg);
   }
+
+  itkSetMacro(LookupSelected, short);
+  itkGetConstMacro(LookupSelected, short);
+
 protected:
+  /** Default ctor */
   SarRadiometricCalibrationToImageFilter();
+
+  /** Empty, default virtual dtor */
   virtual ~SarRadiometricCalibrationToImageFilter() {}
 
+  /** Generate output information */
+  virtual void GenerateOutputInformation();
+
   /** Update the function list and input parameters*/
   virtual void BeforeThreadedGenerateData();
+
 private:
+
   SarRadiometricCalibrationToImageFilter(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
 
+
+  short m_LookupSelected;
+
 };
 
 } // end namespace otb
diff --git a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx
index 15b09c7fd73a1381545b48a64bcd16593fd24b38..ad0f5b47e035d1218ea856d7788567f40c67f9f9 100644
--- a/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx
+++ b/Modules/Radiometry/SARCalibration/include/otbSarRadiometricCalibrationToImageFilter.txx
@@ -22,8 +22,8 @@
 #define __otbSarRadiometricCalibrationToImageFilter_txx
 
 #include "otbSarRadiometricCalibrationToImageFilter.h"
-
 #include "otbSarImageMetadataInterfaceFactory.h"
+#include "otbSarCalibrationLookupData.h"
 
 namespace otb
 {
@@ -34,7 +34,33 @@ namespace otb
 template<class TInputImage, class TOutputImage>
 SarRadiometricCalibrationToImageFilter<TInputImage, TOutputImage>
 ::SarRadiometricCalibrationToImageFilter()
+: m_LookupSelected(0)
 {
+
+}
+
+template<class TInputImage, class TOutputImage>
+void
+SarRadiometricCalibrationToImageFilter<TInputImage, TOutputImage>
+::GenerateOutputInformation( )
+{
+  Superclass::GenerateOutputInformation();
+
+  // Retrieving input/output pointers
+  InputImagePointer      inputPtr = this->GetInput();
+
+  if (inputPtr.IsNull())
+    {
+    itkExceptionMacro(<< "At least one input is missing."
+                      << " Input is missing :" << inputPtr.GetPointer() )
+      }
+
+  OutputImagePointer outputPtr = this->GetOutput();
+  if (outputPtr.IsNull())
+    {
+    itkExceptionMacro(<< "At least one output is missing."
+                      << " Output is missing :" << outputPtr.GetPointer() )
+      }
 }
 
 template<class TInputImage, class TOutputImage>
@@ -45,60 +71,104 @@ SarRadiometricCalibrationToImageFilter<TInputImage, TOutputImage>
   // will SetInputImage on the function
   Superclass::BeforeThreadedGenerateData();
 
+  /** cretate a SarImageMetadataInterface instance from
+   * GetMetaDataDictionary(). This will return the appropriate IMI depending on
+   * the Sensor information & co available in GetMetaDataDictionary()  */
   SarImageMetadataInterface::Pointer imageMetadataInterface = SarImageMetadataInterfaceFactory::CreateIMI(
       this->GetInput()->GetMetaDataDictionary());
 
+  /** Get the SarRadiometricCalibrationFunction function instance.  */
   FunctionPointer function = this->GetFunction();
 
-  function->SetScale(imageMetadataInterface->GetRadiometricCalibrationScale());
+  /** check if there is a calibration lookupdata is available with the
+    * product. eg. Sentinel1. This means
+    * A. The computation of the backscatter is based on this lookup value which
+    * depends on the given product.*
+    * B. The other value such as antenna pattern gain, rangespread loss, incidence
+    * angle has no effect in calibration  */
+
+  bool apply = imageMetadataInterface->HasCalibrationLookupDataFlag();
+  /* Below lines will toggle the necessary flags which can help skip some
+   * computation. For example, if there is lookup value and ofcourse antenna
+   * pattern gain is not required. Even if we try to compute the value with
+   * SarParametricFuntion we  get 1. This is the safe side. But as we are so sure
+   * we skip all those calls to EvaluateParametricCoefficient and also the
+   * Evalute(). For the function the value is 1 by default.
+   */
+  function->SetApplyAntennaPatternGain(!apply);
+  function->SetApplyIncidenceAngleCorrection(!apply);
+  function->SetApplyRangeSpreadLossCorrection(!apply);
+  function->SetApplyRescalingFactor(!apply);
+  function->SetApplyLookupDataCorrection(apply);
 
-  ParametricFunctionPointer   noise;
-  ParametricFunctionPointer   antennaPatternNewGain;
-  ParametricFunctionPointer   antennaPatternOldGain;
-  ParametricFunctionPointer   incidenceAngle;
-  ParametricFunctionPointer   rangeSpreadLoss;
-
-  noise = function->GetNoise();
-  noise->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationNoise());
-  noise->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationNoisePolynomialDegree());
-  noise->EvaluateParametricCoefficient();
-
-  antennaPatternNewGain = function->GetAntennaPatternNewGain();
-  antennaPatternNewGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGain());
-  antennaPatternNewGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGainPolynomialDegree());
-  antennaPatternNewGain->EvaluateParametricCoefficient();
-
-  antennaPatternOldGain = function->GetAntennaPatternOldGain();
-  antennaPatternOldGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGain());
-  antennaPatternOldGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGainPolynomialDegree());
-  antennaPatternOldGain->EvaluateParametricCoefficient();
-
-  incidenceAngle = function->GetIncidenceAngle();
-  incidenceAngle->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle());
-
-  typename ParametricFunctionType::PointType point;
-  point.Fill(0);
-  typename ParametricFunctionType::PointSetType::PixelType pointValue;
-  pointValue = itk::NumericTraits<typename ParametricFunctionType::PointSetType::PixelType>::Zero;
-  unsigned int nbRecords = imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()->GetNumberOfPoints();
-
-  // Fill the linear system
-  for (unsigned int i = 0; i < nbRecords; ++i)
-  {
-      imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()->GetPoint(i, &point);
-      imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle()->GetPointData(i, &pointValue);
-  }
-  incidenceAngle->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationIncidenceAnglePolynomialDegree());
-
-  incidenceAngle->EvaluateParametricCoefficient();
-  rangeSpreadLoss = function->GetRangeSpreadLoss();
-  rangeSpreadLoss->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLoss());
-  rangeSpreadLoss->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLossPolynomialDegree());
-  rangeSpreadLoss->EvaluateParametricCoefficient();
+  function->SetScale(imageMetadataInterface->GetRadiometricCalibrationScale());
 
+  /* Compute noise if enabled */
+  if( function->GetEnableNoise())
+    {
+    ParametricFunctionPointer   noise;
+    noise = function->GetNoise();
+    noise->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationNoise());
+    noise->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationNoisePolynomialDegree());
+    noise->EvaluateParametricCoefficient();
+    }
+
+  /* Compute old and new antenna pattern gain */
+  if(function->GetApplyAntennaPatternGain())
+    {
+    ParametricFunctionPointer   antennaPatternNewGain;
+    antennaPatternNewGain = function->GetAntennaPatternNewGain();
+    antennaPatternNewGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGain());
+    antennaPatternNewGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternNewGainPolynomialDegree());
+    antennaPatternNewGain->EvaluateParametricCoefficient();
+
+    ParametricFunctionPointer   antennaPatternOldGain;
+    antennaPatternOldGain = function->GetAntennaPatternOldGain();
+    antennaPatternOldGain->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGain());
+    antennaPatternOldGain->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationAntennaPatternOldGainPolynomialDegree());
+    antennaPatternOldGain->EvaluateParametricCoefficient();
+    }
+
+  /* Compute incidence angle */
+  if (function->GetApplyIncidenceAngleCorrection())
+    {
+    ParametricFunctionPointer   incidenceAngle;
+    incidenceAngle = function->GetIncidenceAngle();
+    incidenceAngle->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationIncidenceAngle());
+    incidenceAngle->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationIncidenceAnglePolynomialDegree());
+    incidenceAngle->EvaluateParametricCoefficient();
+    }
+
+    /* Compute Range spread Loss */
+  if (function->GetApplyRangeSpreadLossCorrection())
+    {
+    ParametricFunctionPointer   rangeSpreadLoss;
+    rangeSpreadLoss = function->GetRangeSpreadLoss();
+    rangeSpreadLoss->SetPointSet(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLoss());
+    rangeSpreadLoss->SetPolynomalSize(imageMetadataInterface->GetRadiometricCalibrationRangeSpreadLossPolynomialDegree());
+    rangeSpreadLoss->EvaluateParametricCoefficient();
+    }
+
+  /** Get the lookupdata instance. unlike the all the above this is not a
+* parametricFunction instance. But rather an internal class in IMI called
+* SarCalibrationLookupData.
+*
+*NOTE: As the computation of lookup data for sensors is not universal. One must
+*provide a sub-class.
+See Also: otbSentinel1ImageMetadataInterface, otbTerraSarImageMetadataInterface,
+*otbRadarsat2ImageMetadataInterface  */
+  if (function->GetApplyLookupDataCorrection())
+    {
+    function->SetCalibrationLookupData(imageMetadataInterface->GetCalibrationLookupData(this->GetLookupSelected()));
+    }
+
+  /** This was introduced for cosmoskymed which required a rescaling factor */
+  if (function->GetApplyRescalingFactor())
+    {
+    function->SetRescalingFactor(imageMetadataInterface->GetRescalingFactor());
+    }
 }
 
-
 } // end namespace otb
 
 #endif
diff --git a/Modules/Radiometry/SARCalibration/test/CMakeLists.txt b/Modules/Radiometry/SARCalibration/test/CMakeLists.txt
index 0e3ddd573154ea1c3c393d1206cee83df23c20fc..09dde97aa2a6309a7c4cf555618952eeb1df4f07 100644
--- a/Modules/Radiometry/SARCalibration/test/CMakeLists.txt
+++ b/Modules/Radiometry/SARCalibration/test/CMakeLists.txt
@@ -18,8 +18,6 @@ otbSarRadiometricCalibrationToImageFilterCompareTest.cxx
 otbSarBrightnessFunctor.cxx
 otbSarBrightnessFunctionWithoutNoise.cxx
 otbSarRadiometricCalibrationFunction.cxx
-otbSarRadiometricCalibrationFunctor.cxx
-otbSarRadiometricCalibrationFunctorWithoutNoise.cxx
 otbSarRadiometricCalibrationFunctionWithoutNoise.cxx
 otbTerraSarBrightnessImageComplexFilterTest.cxx
 otbSarRadiometricCalibrationToImageFilterWithComplexPixelTest.cxx
@@ -127,6 +125,28 @@ otb_add_test(NAME raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWith
   1000 1000 250 250 # Extract
   )
 
+#Sentinel-1 L1, SLC
+otb_add_test(NAME raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1 COMMAND  otbSARCalibrationTestDriver
+  --compare-image ${EPSILON_12}
+  ${BASELINE}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1_VV.tif
+  ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1_VV.tif
+  otbSarRadiometricCalibrationToImageFilterWithComplexPixelTestWithoutNoise
+  LARGEINPUT{SENTINEL1/S1A_S6_SLC__1SSV_20150619T195043/measurement/s1a-s6-slc-vv-20150619t195043-20150619t195101-006447-00887d-001.tiff}
+  ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_SENTINEL1_VV.tif
+  1100 1900 450 450 # Extract
+  )
+
+#Radarsat2
+otb_add_test(NAME raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2 COMMAND  otbSARCalibrationTestDriver
+  --compare-image ${EPSILON_12}
+  ${BASELINE}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2_HV.tif
+  ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2_HV.tif
+  otbSarRadiometricCalibrationToImageFilterWithComplexPixelTestWithoutNoise
+  LARGEINPUT{RADARSAT2/ALTONA/Fine_Quad-Pol_Dataset/PK6621_DK406_FQ9_20080405_124900_HH_VV_HV_VH_SLC_Altona/imagery_HV.tif}
+  ${TEMP}/raTvSarRadiometricCalibrationToImageWithComplexPixelFilterWithoutNoise_RADARSAT2_HV.tif
+  11 11 650 750 # Extract
+  )
+
 otb_add_test(NAME raTuSarBrightnessFunctorWithoutNoise COMMAND otbSARCalibrationTestDriver
   otbSarBrightnessFunctorWithoutNoise
   )
@@ -190,13 +210,6 @@ otb_add_test(NAME raTvSarRadiometricCalibrationFunction COMMAND otbSARCalibratio
   ${TEMP}/raTvSarRadiometricCalibrationFunctionOutputAsciiWithNoise.txt
   )
 
-otb_add_test(NAME raTuSarRadiometricCalibrationFunctor COMMAND otbSARCalibrationTestDriver
-  otbSarRadiometricCalibrationFunctor
-  )
-
-otb_add_test(NAME raTuSarRadiometricCalibrationFunctorWithoutNoise COMMAND otbSARCalibrationTestDriver
-  otbSarRadiometricCalibrationFunctorWithoutNoise
-  )
 
 otb_add_test(NAME raTvSarRadiometricCalibrationFunctionWithoutNoise COMMAND otbSARCalibrationTestDriver
   --compare-ascii ${NOTOL}
@@ -259,4 +272,3 @@ otb_add_test(NAME raTvSarBrightnessToImageFilter COMMAND  otbSARCalibrationTestD
   ${TEMP}/raTvSarBrightnessToImageFilter_TSX_PANGKALANBUUN_HH.tif
   1000 1000 250 250 # Extract
   )
-
diff --git a/Modules/Radiometry/SARCalibration/test/otbSARCalibrationTestDriver.cxx b/Modules/Radiometry/SARCalibration/test/otbSARCalibrationTestDriver.cxx
index 19236b9438f890df8aefde837c12ad00692c636c..873a912bbe6538f0583e348a02184b4bcca4e6f9 100644
--- a/Modules/Radiometry/SARCalibration/test/otbSARCalibrationTestDriver.cxx
+++ b/Modules/Radiometry/SARCalibration/test/otbSARCalibrationTestDriver.cxx
@@ -17,8 +17,6 @@ void RegisterTests()
   REGISTER_TEST(otbSarBrightnessFunctor);
   REGISTER_TEST(otbSarBrightnessFunctionWithoutNoise);
   REGISTER_TEST(otbSarRadiometricCalibrationFunction);
-  REGISTER_TEST(otbSarRadiometricCalibrationFunctor);
-  REGISTER_TEST(otbSarRadiometricCalibrationFunctorWithoutNoise);
   REGISTER_TEST(otbSarRadiometricCalibrationFunctionWithoutNoise);
   REGISTER_TEST(otbTerraSarBrightnessImageComplexFilterTest);
   REGISTER_TEST(otbSarRadiometricCalibrationToImageFilterWithComplexPixelTest);
diff --git a/Modules/Registration/DisparityMap/include/otbDisparityTranslateFilter.txx b/Modules/Registration/DisparityMap/include/otbDisparityTranslateFilter.txx
index 2a0932c883e1c023d439b12bc7cb2b641943ae19..afd59f1caf21033f43f0f4cc8f4449f69a63b389 100644
--- a/Modules/Registration/DisparityMap/include/otbDisparityTranslateFilter.txx
+++ b/Modules/Registration/DisparityMap/include/otbDisparityTranslateFilter.txx
@@ -205,6 +205,18 @@ DisparityTranslateFilter<TDisparityImage,TGridImage,TSensorImage,TMaskImage>
 
   horizOut->CopyInformation(leftIn);
   vertiOut->CopyInformation(leftIn);
+
+  // Set the NoData value
+  std::vector<bool> noDataValueAvailable;
+  noDataValueAvailable.push_back(true);
+  std::vector<double> noDataValue;
+  noDataValue.push_back(m_NoDataValue);
+  itk::MetaDataDictionary& dict = horizOut->GetMetaDataDictionary();
+  itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
+  dict = vertiOut->GetMetaDataDictionary();
+  itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
 }
 
 template <class TDisparityImage, class TGridImage, class TSensorImage, class TMaskImage>
diff --git a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx
index 2c7a851f0446e45ca7ad3dbe0b47e8357d4a6af7..515161f4bb580acd054c6996fc7da7b9e1c24fdf 100644
--- a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx
+++ b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.txx
@@ -337,7 +337,14 @@ void Multi3DMapToDEMFilter<T3DImage, TMaskImage, TOutputDEMImage>::GenerateOutpu
     m_IsGeographic = oSRS.IsGeographic(); // TODO check if this test is valid for all projection systems
     }
 
-
+  // Set the NoData value
+  std::vector<bool> noDataValueAvailable;
+  noDataValueAvailable.push_back(true);
+  std::vector<double> noDataValue;
+  noDataValue.push_back(m_NoDataValue);
+  itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
+  itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
 }
 
 template<class T3DImage, class TMaskImage, class TOutputDEMImage>
diff --git a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx
index 997c4cb1382dc0c4b9b4f19545a7530f2407d79d..69b8e325f45c80d0dc20259fe885037e2f396c1c 100644
--- a/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx
+++ b/Modules/Segmentation/Conversion/include/otbOGRDataSourceToLabelImageFilter.txx
@@ -20,6 +20,8 @@
 #include "otbOGRIOHelper.h"
 #include "otbGdalDataTypeBridge.h"
 #include "otbImageMetadataInterfaceFactory.h"
+#include "itkMetaDataObject.h"
+#include "otbMetaDataKey.h"
 
 #include "gdal_alg.h"
 #include "stdint.h" //needed for uintptr_t
@@ -164,6 +166,15 @@ OGRDataSourceToLabelImageFilter<TOutputImage>
          m_SrcDataSetLayers.push_back( &(ogrDS->GetLayer(layer).ogr()) );
       }
     }
+
+  // Set the NoData value using the background
+  const unsigned int & nbBands =  outputPtr->GetNumberOfComponentsPerPixel();
+  std::vector<bool> noDataValueAvailable;
+  noDataValueAvailable.resize(nbBands,true);
+  std::vector<double> noDataValue;
+  noDataValue.resize(nbBands,static_cast<double>(m_BackgroundValue));
+  itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
+  itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,noDataValue);
 }
 
 template< class TOutputImage>
diff --git a/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.h b/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.h
index 32e8d621e92aedd98ebfe21bdac826257e191d20..ce68b0f989414ef4aee0971a5e8f17a744664a7f 100644
--- a/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.h
+++ b/Modules/Segmentation/Conversion/include/otbRasterizeVectorDataFilter.h
@@ -27,10 +27,8 @@
 
 #include "gdal.h"
 #include "gdal_alg.h"
-
-#include <ogrsf_frmts.h>
-#include "ogr_api.h"
 #include "ogr_srs_api.h"
+#include "otbOGRVersionProxy.h"
 
 namespace otb {
 
@@ -142,7 +140,7 @@ protected:
   {
     if (m_OGRDataSourcePointer != NULL)
       {
-      OGRDataSource::DestroyDataSource(m_OGRDataSourcePointer);
+      ogr::version_proxy::Close(m_OGRDataSourcePointer);
       }
   }
 
@@ -154,7 +152,7 @@ private:
   RasterizeVectorDataFilter(const Self&); //purposely not implemented
   void operator=(const Self&); //purposely not implemented
 
-  OGRDataSource*              m_OGRDataSourcePointer;
+  ogr::version_proxy::GDALDatasetType * m_OGRDataSourcePointer;
 
   // Vector Of LayersH
   std::vector< OGRLayerH >    m_SrcDataSetLayers;
diff --git a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h
index 0e51efb881d85c78b643c04e36247b88ef8e6114..24aa6e71c6c1a343275e0829cd412c6c7eb74ca8 100644
--- a/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h
+++ b/Modules/Segmentation/Conversion/include/otbVectorDataToLabelImageFilter.h
@@ -26,7 +26,7 @@
 
 #include "gdal.h"
 #include "ogr_api.h"
-#include <ogrsf_frmts.h>
+#include "otbOGRVersionProxy.h"
 
 namespace otb {
 
@@ -134,7 +134,7 @@ protected:
 
     if (m_OGRDataSourcePointer != NULL)
       {
-      OGRDataSource::DestroyDataSource(m_OGRDataSourcePointer);
+      ogr::version_proxy::Close(m_OGRDataSourcePointer);
       }
   }
 
@@ -146,7 +146,7 @@ private:
   VectorDataToLabelImageFilter(const Self&); //purposely not implemented
   void operator=(const Self&); //purposely not implemented
 
-  OGRDataSource*                m_OGRDataSourcePointer;
+  ogr::version_proxy::GDALDatasetType * m_OGRDataSourcePointer;
 
   // Vector Of OGRGeometyH
   std::vector< OGRGeometryH >   m_SrcDataSetGeometries;
diff --git a/Modules/ThirdParty/GDAL/gdalVersionTest.cxx b/Modules/ThirdParty/GDAL/gdalVersionTest.cxx
index 981cf8fe1c572a7cfcdffbf0040d3a5f699eb008..076a144dd5f368c6cc673983dd09f85aafb2f979 100644
--- a/Modules/ThirdParty/GDAL/gdalVersionTest.cxx
+++ b/Modules/ThirdParty/GDAL/gdalVersionTest.cxx
@@ -55,7 +55,7 @@ int main(int argc, char * argv[])
 	}
 
   
-  if ( (UIntVect[0]<MAJOR) || (UIntVect[1]<MINOR) )
+  if ( (UIntVect[0]==MAJOR && UIntVect[1]<MINOR) || (UIntVect[0]<MAJOR) )
 	{
 		cout << "WARNING : Version of GDAL must be >= " << MAJOR << "." << MINOR << " : " << UIntVect[0] << "." << UIntVect[1] << " detected)." << endl;
 		return 1;
diff --git a/Modules/ThirdParty/GDAL/otb-module-init.cmake b/Modules/ThirdParty/GDAL/otb-module-init.cmake
index 7222581bcc0a0766809697b5dce4fd4c731c23cb..74e86291e8f3c1e468b4d740a83eb3a129a2d218 100644
--- a/Modules/ThirdParty/GDAL/otb-module-init.cmake
+++ b/Modules/ThirdParty/GDAL/otb-module-init.cmake
@@ -23,7 +23,7 @@ if(GDAL_CONFIG_CHECKING)
 	#------------------- TESTS ---------------------
 	# Version of GDAL  
 	try_run(RUN_RESULT_VERSION COMPILE_RESULT_VERSION ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/Modules/ThirdParty/GDAL/gdalVersionTest.cxx CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GDAL_INCLUDE_DIR}" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}" ARGS ${TEMP}/gdalVersion.txt ${MIN_MAJOR_VERSION} ${MIN_MINOR_VERSION})
-
+  
 	# Has OGR
 	try_compile(GDAL_HAS_OGR ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/Modules/ThirdParty/GDAL/gdalOGRTest.cxx CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GDAL_INCLUDE_DIR}" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}")
 
@@ -85,6 +85,15 @@ if(GDAL_CONFIG_CHECKING)
 		file(READ "${TEMP}/gdalVersion.txt" DETECTED_VERSION)
 		message(WARNING "Version of GDAL must be >= " ${MIN_MAJOR_VERSION} "." ${MIN_MINOR_VERSION} " : " ${DETECTED_VERSION} " detected.")
 		set(GDAL_QUALIFIES FALSE)
+  else((${RUN_RESULT_VERSION} EQUAL 1))
+    file(READ "${TEMP}/gdalVersion.txt" DETECTED_VERSION)
+    string(SUBSTRING ${DETECTED_VERSION} 0 2 VER2)
+    if(${VER2} EQUAL "2.")
+      message("-- Gdal >= 2.0.0 detected")
+      set(OTB_USE_GDAL_20 true CACHE INTERNAL "True if GDAL >= 2.0.0 has been detected" FORCE )
+    else(${VER2} EQUAL "2.")
+      set(OTB_USE_GDAL_20 false CACHE INTERNAL "True if GDAL >= 2.0.0 has been detected" FORCE )
+    endif()
 	endif()
 		
 	if (NOT GDAL_HAS_OGR)
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.cpp
index c7e78de798ce0b89b77360089f69facb77572dbf..56719938ac1d516ddc7a71a7d42c73c8944072b8 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.cpp
@@ -47,21 +47,24 @@ RTTI_DEF1(ossimRadarSat2Model, "ossimRadarSat2Model", ossimGeometricSarSensorMod
 
 
 ossimRadarSat2Model::ossimRadarSat2Model()
-   :
-   ossimGeometricSarSensorModel(),
-   _n_srgr(0),
-   _srgr_update(),
-   _SrGr_R0()
+   :  ossimGeometricSarSensorModel()
+   , _n_srgr(0)
+   , _srgr_update()
+   , _SrGr_R0()
+   , theAcquisitionDateUTCString("")
+   , theProductionDateUTCString("")
 {
 }
 
 ossimRadarSat2Model::ossimRadarSat2Model(const ossimRadarSat2Model& rhs)
-   :
-   ossimGeometricSarSensorModel(rhs),
-   _n_srgr(rhs._n_srgr),
-   _srgr_update(rhs._srgr_update),
-   _SrGr_R0(rhs._SrGr_R0)
+   : ossimGeometricSarSensorModel(rhs)
+   , _n_srgr(rhs._n_srgr)
+   , _srgr_update(rhs._srgr_update)
+   , _SrGr_R0(rhs._SrGr_R0)
+   , theProductionDateUTCString(rhs.theProductionDateUTCString)
+   , theAcquisitionDateUTCString(rhs.theAcquisitionDateUTCString)
 {
+
 }
 
 ossimRadarSat2Model::~ossimRadarSat2Model()
@@ -81,15 +84,15 @@ ossimObject* ossimRadarSat2Model::dup() const
 double ossimRadarSat2Model::getSlantRangeFromGeoreferenced(double col) const
 {
    if (_n_srgr==0) return(-1) ;
-   
+
    double relativeGroundRange, slantRange = 0.0 ;
-   
+
    // in the case of Georeferenced images, _refPoint->get_distance()
    // contains the ground range
    relativeGroundRange = _refPoint->get_distance() + _sensor->get_col_direction() * (col-_refPoint->get_pix_col())* theGSD.x;
    //relativeGroundRange = 1 + _sensor->get_col_direction() * (col-_refPoint->get_pix_col())* theGSD.x;
    //relativeGroundRange = (8.78400000e+03)*theGSD.x;
-   
+
    if ( traceDebug() )
    {
       ossimNotify(ossimNotifyLevel_DEBUG)
@@ -100,15 +103,15 @@ double ossimRadarSat2Model::getSlantRangeFromGeoreferenced(double col) const
          << "\n_refPoint->get_pix_col() : " << _refPoint->get_pix_col()
          << "\n relativeGroundRange : " << relativeGroundRange << endl;
    }
-   
+
    int numSet = FindSRGRSetNumber((_refPoint->get_ephemeris())->get_date()) ;
    /**
     * @todo : could be improved (date choice)
     */
-   
+
    for (int i=0 ; i < static_cast<int>(_SrGr_coeffs[numSet].size()); i++)
    {
-      
+
       slantRange += _SrGr_coeffs[numSet][i]*pow(relativeGroundRange,i) ;
    }
 
@@ -160,6 +163,8 @@ bool ossimRadarSat2Model::open(const ossimFilename& file)
 
          if (result)
          {
+            _productXmlFile = xmlFile;
+
             if (traceDebug())
             {
                ossimNotify(ossimNotifyLevel_DEBUG)
@@ -204,13 +209,27 @@ bool ossimRadarSat2Model::open(const ossimFilename& file)
                result = rsDoc.getSatellite(xdoc, theSensorID);
             }
 
+            if (result)
+            {
             // Set the base class gsd:
             result = rsDoc.initGsd(xdoc, theGSD);
+            }
+
             if (result)
             {
                theMeanGSD = (theGSD.x + theGSD.y)/2.0;
             }
 
+            if (result)
+            {
+               result = rsDoc.getAcquistionDate(xdoc, theAcquisitionDateUTCString);
+            }
+
+            if (result)
+            {
+               result = rsDoc.getProductionDate(xdoc, theProductionDateUTCString);
+            }
+
             if (result)
             {
                result = initSRGR(xdoc, rsDoc);
@@ -226,7 +245,7 @@ bool ossimRadarSat2Model::open(const ossimFilename& file)
                      if (result)
                      {
                         result = initRefPoint(xdoc, rsDoc);
-                     
+
                      	  if (result)
                         {
                         result = InitRefNoiseLevel(xdoc);
@@ -246,7 +265,6 @@ bool ossimRadarSat2Model::open(const ossimFilename& file)
 
    if (result)
    {
-      _productXmlFile = xmlFile;
       ossimSupportFilesList::instance()->add(_productXmlFile);
    }
    else
@@ -273,7 +291,7 @@ bool ossimRadarSat2Model::open(const ossimFilename& file)
             << "ul, ur, lr, ll " << ul << ", " << ur
             << ", " << lr << " , " << ll << endl;
       }
-      
+
       setGroundRect(ul, ur, lr, ll);  // ossimSensorModel method.
 
       // OSSIM preferences specifies whether a coarse grid needs to be generated:
@@ -336,7 +354,7 @@ std::ostream& ossimRadarSat2Model::print(std::ostream& out) const
    }
 
    ossimGeometricSarSensorModel::print(out);
-   
+
 
    // Reset flags.
    out.setf(f);
@@ -523,7 +541,7 @@ bool ossimRadarSat2Model::InitRefPoint(const ossimKeywordlist &kwl,
       date->set_decimal(time - floor(time)) ;
    }
    delete date;//FIXME to confirm
-  
+
    if(_platformPosition != 0)
    {
       Ephemeris * ephemeris = _platformPosition->Interpolate((JSDDateTime)*date);
@@ -928,7 +946,7 @@ bool ossimRadarSat2Model::initRefPoint(const ossimXmlDocument* xdoc,
 
    double distance = 1;
 
-   // Only set distance to 
+   // Only set distance to
    if (!_isProductGeoreferenced)
    {
 	   if ( !rsDoc.getSlantRangeNearEdge(xdoc, s) )
@@ -936,9 +954,9 @@ bool ossimRadarSat2Model::initRefPoint(const ossimXmlDocument* xdoc,
 		   if (traceDebug())
 		   {
 			   ossimNotify(ossimNotifyLevel_DEBUG)
-    
+
 				   << MODULE << "getSlantRangeNearEdge error! exiting\n";
-		   }      
+		   }
 		   return false;
 	   }
 	   distance = s.toDouble();
@@ -981,7 +999,8 @@ bool ossimRadarSat2Model::initRefPoint(const ossimXmlDocument* xdoc,
 bool ossimRadarSat2Model::InitLut( const ossimXmlDocument* xmlDocument,
    			RadarSat2NoiseLevel& noise)
 {
-   static const char MODULE[] = "ossimRadarSat2Model::initLut";
+   static const char MODULE[] = "ossimRadarSat2Model::InitLut";
+
    if (traceDebug())
    {
       ossimNotify(ossimNotifyLevel_DEBUG)<< MODULE << " entered...\n";
@@ -992,8 +1011,8 @@ bool ossimRadarSat2Model::InitLut( const ossimXmlDocument* xmlDocument,
    std::vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
    std::vector<ossimRefPtr<ossimXmlNode> >::iterator node;
    ossimFilename  lutXmlFile;
-      
-   incidenceAngleCorrectionName = noise.get_incidenceAngleCorrectionName();     
+
+   incidenceAngleCorrectionName = noise.get_incidenceAngleCorrectionName();
 
    xpath = "/product/imageAttributes/lookupTable";
    xml_nodes.clear();
@@ -1009,8 +1028,8 @@ bool ossimRadarSat2Model::InitLut( const ossimXmlDocument* xmlDocument,
                		<< std::endl;
       }
       return false;
-   }  
-        
+   }
+
    node = xml_nodes.begin();
    while (node != xml_nodes.end())
    {
@@ -1024,56 +1043,67 @@ bool ossimRadarSat2Model::InitLut( const ossimXmlDocument* xmlDocument,
       			//---
       			// Instantiate the XML parser:
       			//---
-      			ossimXmlDocument* xmlLutDocument = new ossimXmlDocument();
-      			if ( xmlLutDocument->openFile(lutXmlFile) )
+           ossimRefPtr<ossimXmlDocument> xmlLutDocument;
+           xmlLutDocument = new ossimXmlDocument();
+           if ( xmlLutDocument.get()->openFile(lutXmlFile) )
       			{
-   					std::vector<ossimRefPtr<ossimXmlNode> > xml_lutNodes;
-   					ossimString s;
-   					
-   					xpath = "/lut/offset";
-   					xml_lutNodes.clear();
-   					xmlLutDocument->findNodes(xpath, xml_lutNodes);   					
-   					if(xml_lutNodes.size() == 0)
-   					{
-     					setErrorStatus();
-     					if(traceDebug())
-     					{
-  	    					ossimNotify(ossimNotifyLevel_DEBUG)
+               const ossimRefPtr<ossimXmlNode> lutRoot = xmlLutDocument.get()->getRoot(); //->findFirstNode("lut");
+
+               if(! lutRoot.get())
+               {
+                  setErrorStatus();
+                  if(traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
+    		      					<< MODULE << " DEBUG:"
+                        << "\nCould not find: lut"  << std::endl;
+                  }
+                  return false;
+               }
+
+               ossimString offsetVal = lutRoot->getChildTextValue("offset");
+               if( !offsetVal.empty())
+               {
+                  noise.set_offset(offsetVal.toFloat64());
+               }
+               else
+               {
+                  setErrorStatus();
+                  if(traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
     		      					<< MODULE << " DEBUG:"
-            	  					<< "\nCould not find: " << xpath
-               						<< std::endl;
-      					}
-      					return false;
-   					}
-   					ossim_float64 offset = xml_lutNodes[0]->getText().toFloat64();  
-					noise.set_offset(offset);				
-								
-   					xpath = "/lut/gains";
-   					xml_lutNodes.clear();
-   					xmlLutDocument->findNodes(xpath, xml_lutNodes);   					
-   					if(xml_lutNodes.size() == 0)
-   					{
-     					setErrorStatus();
-     					if(traceDebug())
-     					{
-  	    					ossimNotify(ossimNotifyLevel_DEBUG)
+                        << "\nCould not find: offset"  << std::endl;
+                  }
+                  return false;
+               }
+
+               ossimString gainVal = lutRoot->getChildTextValue("gains");
+               if( !gainVal.empty())
+               {
+                  noise.set_gain(gainVal);
+               }
+               else
+               {
+                  setErrorStatus();
+                  if(traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG)
     		      					<< MODULE << " DEBUG:"
-            	  					<< "\nCould not find: " << xpath
-               						<< std::endl;
-      					}
-      					return false;
-   					}  
-					noise.set_gain(xml_lutNodes[0]->getText());	
-				}
+                        << "\nCould not find: gains"  << std::endl;
+                  }
+                  return false;
+               }
+            }
    			}
 		}
-    	++node;	
+    	++node;
    }
 
    if (traceDebug())
    {
       ossimNotify(ossimNotifyLevel_DEBUG)<< MODULE << " leaving...\n";
-   }   
+   }
 
    return true;
 }
@@ -1095,8 +1125,8 @@ bool ossimRadarSat2Model::InitRefNoiseLevel(
    }
 
    _noiseLevel.clear();
-   
-   
+
+
    xpath = "/product/sourceAttributes/radarParameters/referenceNoiseLevel";
    xml_nodes.clear();
    xmlDocument->findNodes(xpath, xml_nodes);
@@ -1111,14 +1141,14 @@ bool ossimRadarSat2Model::InitRefNoiseLevel(
                		<< std::endl;
       }
       return false;
-   }  
-        
+   }
+
    node = xml_nodes.begin();
    while (node != xml_nodes.end())
    {
-   	
-   	ev.set_incidenceAngleCorrectionName( (*node)->getAttributeValue("incidenceAngleCorrection") ); 
-   	
+
+   	ev.set_incidenceAngleCorrectionName( (*node)->getAttributeValue("incidenceAngleCorrection") );
+
     sub_nodes.clear();
     xpath = "pixelFirstNoiseValue";
     (*node)->findChildNodes(xpath, sub_nodes);
@@ -1185,10 +1215,10 @@ bool ossimRadarSat2Model::InitRefNoiseLevel(
          }
       	return false;
     }
-   	ev.set_units( sub_nodes[0]->getAttributeValue("units") ); 
+   	ev.set_units( sub_nodes[0]->getAttributeValue("units") );
 
 
-    std::vector<ossimString> s2;      
+    std::vector<ossimString> s2;
     std::vector<ossim_float64> noiseLevelValues;
     s2.clear();
     noiseLevelValues.clear();
@@ -1197,7 +1227,7 @@ bool ossimRadarSat2Model::InitRefNoiseLevel(
 	{
 		noiseLevelValues.push_back( s2[i].toFloat64() );
 	}
-   	ev.set_noiseLevelValues( noiseLevelValues ); 
+   	ev.set_noiseLevelValues( noiseLevelValues );
 
 	InitLut(xmlDocument, ev);
 
@@ -1206,11 +1236,11 @@ bool ossimRadarSat2Model::InitRefNoiseLevel(
 
     ++node;
    }
- 
+
    if (traceDebug())
    {
       ossimNotify(ossimNotifyLevel_DEBUG)<< MODULE << " leaving...\n";
-   }   
+   }
 
    return true;
 }
@@ -1234,6 +1264,33 @@ bool ossimRadarSat2Model::saveState(ossimKeywordlist& kwl,
    kwl.add(prefix, PRODUCT_XML_FILE_KW, _productXmlFile.c_str());
    kwl.add(prefix, NUMBER_SRGR_COEFFICIENTS_KW, _n_srgr);
 
+   kwl.add("support_data.",
+           "calibration_lookup_flag",
+           "true",
+           true);
+
+
+   if(! theProductionDateUTCString.empty())
+      kwl.add("support_data.",
+              ossimKeywordNames::DATE_KW,
+              theProductionDateUTCString.c_str(),
+              true);
+
+   if(! theAcquisitionDateUTCString.empty())
+      kwl.add("support_data.",
+              ossimKeywordNames::IMAGE_DATE_KW,
+              theAcquisitionDateUTCString.c_str(),
+              true);
+
+   //RK ...fix this part as part of refractoring
+   //if(theSLC)// numBands*=2; // real and imaginary
+
+
+   kwl.add("support_data.",
+           ossimKeywordNames::NUMBER_BANDS_KW,
+           2,
+           true);
+
    // Make sure all the arrays are equal in size.
    const ossim_uint32 COUNT = static_cast<ossim_uint32>(_n_srgr);
 
@@ -1282,10 +1339,10 @@ bool ossimRadarSat2Model::saveState(ossimKeywordlist& kwl,
    if (result)
    {
       	for(ossim_uint32 i = 0; i < _noiseLevel.size(); ++i)
-   		{	
+   		{
    				_noiseLevel[i].saveState(kwl, prefix);
    		}
-       
+
    }
 
    //---
@@ -1485,9 +1542,9 @@ bool ossimRadarSat2Model::loadState (const ossimKeywordlist &kwl,
 	if(result)
 	{
       	for(ossim_uint32 i = 0; i < _noiseLevel.size(); ++i)
-   		{	
+   		{
    				_noiseLevel[i].loadState(kwl, prefix);
-   		}		
+   		}
 	}
 
    if (traceDebug())
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.h b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.h
index 2269a0266027a81dd1d39aae9c33b85b67a02a14..606e41af9bc8e6b4791e22fd288b9935a4015149 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.h
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2Model.h
@@ -169,6 +169,11 @@ private:
     */
    int   _n_srgr;
 
+   //RK remove this part soon and use kwl directly.
+   ossimString theAcquisitionDateUTCString;
+
+   ossimString theProductionDateUTCString;
+
    /**
     * @brief Slant Range FOR EACH Ground Range coefficient sets update times
     */
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.cpp
index 65a03bea50565382b7fb2fb3e82ff5616e0934dc..569f21e79fd9b945a5c54f7aa616d12db2976ab4 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.cpp
@@ -465,7 +465,7 @@ bool ossimRadarSat2ProductDoc::initGsd(const ossimXmlDocument* xdoc,
       ossimString s;
       if ( getSampledPixelSpacing(xdoc, s) )
       {
-         gsd.x = s.toFloat64();
+         gsd.x = ossimString::toFloat64(s);
       }
       else
       {
@@ -473,7 +473,7 @@ bool ossimRadarSat2ProductDoc::initGsd(const ossimXmlDocument* xdoc,
       }
       if ( getSampledLineSpacing(xdoc, s) )
       {
-         gsd.y = s.toFloat64(s);
+         gsd.y = ossimString::toFloat64(s);
       }
       else
       {
@@ -496,6 +496,20 @@ bool ossimRadarSat2ProductDoc::initGsd(const ossimXmlDocument* xdoc,
    return result;
 }
 
+
+
+bool ossimRadarSat2ProductDoc::getAcquistionDate(const ossimXmlDocument* xdoc, ossimString& adate)
+{
+   ossimString path = "/product/sourceAttributes/rawDataStartTime";
+   return ossim::getPath(path, xdoc, adate);
+}
+
+bool ossimRadarSat2ProductDoc::getProductionDate(const ossimXmlDocument* xdoc, ossimString& pdate)
+{
+   ossimString path = "/product/imageGenerationParameters/generalProcessingInformation/processingTime";
+   return ossim::getPath(path, xdoc, pdate);
+}
+
 bool ossimRadarSat2ProductDoc::initTiePoints(const ossimXmlDocument* xdoc,
                                              std::list<ossimGpt>& gcp,
                                              std::list<ossimDpt>& icp) const
@@ -889,15 +903,15 @@ bool ossimRadarSat2ProductDoc::getImageFile(const ossimXmlDocument* xdoc,
 {
    bool result = false;
    ossimString fileName;
-   
+
    ossimString path = "/product/imageAttributes/fullResolutionImageData";
-   
+
    if ( ossim::getPath(path, xdoc, fileName) )
    {
       result = true;
       s = fileName;
    }
-   
+
    return result;
 }
 
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.h b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.h
index 56bf0a7ab75915bd15c3281189bb72eeac80a10f..ae376b08f88bcab27af8d9c9b303b64bf12e5bed 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.h
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimRadarSat2ProductDoc.h
@@ -51,7 +51,7 @@ typedef struct
    vector<double> lineDenominatorCoefficients;
    vector<double> pixelNumeratorCoefficients;
    vector<double> pixelDenominatorCoefficients;
-   
+
 }RPCModel;
 
 namespace ossimplugins
@@ -59,17 +59,17 @@ namespace ossimplugins
 class PlatformPosition;
 class RefPoint;
 class SensorParams;
-   
+
 /** @brief Class to encapsulate parsing RadarSat2 product.xml file. */
 class OSSIM_PLUGINS_DLL ossimRadarSat2ProductDoc
 {
 public:
    /** @brief default constructor */
    ossimRadarSat2ProductDoc();
-      
+
    /** @brief destructor */
    ~ossimRadarSat2ProductDoc();
-      
+
    /**
     * @brief Checks for node /product/sourceAttributes/satellite containing
     * RADARSAT-2.
@@ -77,9 +77,9 @@ public:
     * @return true if present, false if not.
     */
    bool isRadarSat2(const ossimXmlDocument* xdoc) const;
-      
+
    RPCModel getRpcData(const ossimXmlDocument* xdoc) const;
-      
+
    /**
     * @brief Method to initialize PlatformPosition object from
     * RadarSat "product.xml" file.
@@ -89,7 +89,7 @@ public:
     */
    bool initPlatformPosition(const ossimXmlDocument* xdoc,
                              PlatformPosition* pos) const;
-      
+
    /**
     * @brief Method to initialize SensorParams object from
     * RadarSat "product.xml" file.
@@ -99,7 +99,7 @@ public:
     */
    bool initSensorParams(const ossimXmlDocument* xdoc,
                          SensorParams* sp) const;
-      
+
    /**
     * @brief Method to initialize image size from
     * RadarSat "product.xml" file.
@@ -109,7 +109,7 @@ public:
     */
    bool initImageSize(const ossimXmlDocument* xdoc,
                       ossimIpt& imageSize) const;
-      
+
    /**
     * @brief Method to initialize gsd from
     * RadarSat "product.xml" file.
@@ -119,7 +119,11 @@ public:
     */
    bool initGsd(const ossimXmlDocument* xdoc,
                 ossimDpt& gsd) const;
-      
+
+   bool getAcquistionDate(const ossimXmlDocument* xdoc, ossimString& adate);
+
+   bool getProductionDate(const ossimXmlDocument* xdoc, ossimString& pdate);
+
    /**
     * @brief Method to initialize image tie points from
     * RadarSat "product.xml" file.
@@ -132,7 +136,7 @@ public:
                       std::list<ossimDpt>& icp) const;
    bool getSatellite(const ossimXmlDocument* xdoc,
                      ossimString& s) const;
-      
+
    bool getSensor(const ossimXmlDocument* xdoc,
                   ossimString& s) const;
 
@@ -222,7 +226,7 @@ public:
 
    bool getIncidenceAngleFarRange(const ossimXmlDocument* xdoc,
                                   ossimString& s) const;
-   
+
    bool getSatelliteHeight(const ossimXmlDocument* xdoc,
                            ossimString& s) const;
 };
diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
index 9f45f1625222efb4dbd33b6c6f130686d26ac808..f0bd0d5b477546e035d4ee3dac1e748b9ca096af 100644
--- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
+++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSentinel1Model.cpp
@@ -42,7 +42,6 @@ namespace ossimplugins
       :ossimSarModel(rhs)
       , theOCN(rhs.theOCN)
       , theSLC(rhs.theSLC)
-
    {
 
    }
diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplicationRegistry.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplicationRegistry.h
index 4eeb7d7b12279cfbc6470962440dff6fe850801d..ba6a46771e7ae17bda62838de7a629f9af490790 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplicationRegistry.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplicationRegistry.h
@@ -58,16 +58,21 @@ public:
   /** Add the specified path to the list of application search path */
   static void AddApplicationPath(std::string path);
 
+  /** Return the application search path */
+  static std::string GetApplicationPath();
+
   /** Return the list of available applications */
-  static std::vector<std::string> GetAvailableApplications();
+  static std::vector<std::string> GetAvailableApplications(bool useFactory=true);
 
   /** Create the specified Application */
-  static Application::Pointer CreateApplication(const std::string& applicationName);
+  static Application::Pointer CreateApplication(const std::string& applicationName, bool useFactory=true);
 
   /** Create the specified Application (faster)
    *  method using dynamic library name to load the right module */
   static Application::Pointer CreateApplicationFaster(const std::string& applicationName);
 
+  /** Clean registry by releasing unused modules */
+  static void CleanRegistry();
 
 protected:
   ApplicationRegistry();
@@ -76,8 +81,9 @@ protected:
 private:
   ApplicationRegistry(const Self&); //purposely not implemented
   void operator=(const Self&); //purposely not implemented
-  
-  static void RefreshApplicationFactories();
+
+  /** Load an application from a shared library */
+  static Application::Pointer LoadApplicationFromPath(std::string path,std::string name);
 
 };
 
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx
index 49875353c22c9f4aefdd3968d428f05b0ea61e32..ea668936fe0b9d70de53a3190e8d14fa8f88d365 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplicationRegistry.cxx
@@ -20,6 +20,10 @@
 #include "otbMacro.h"
 #include "itksys/SystemTools.hxx"
 #include "itkDynamicLoader.h"
+#include "itkDirectory.h"
+#include "itkMutexLock.h"
+#include "itkMutexLockHolder.h"
+
 #include <iterator>
 
 namespace otb
@@ -27,6 +31,101 @@ namespace otb
 namespace Wrapper
 {
 
+// Constant : environment variable for application path
+static const char OTB_APPLICATION_VAR[] = "OTB_APPLICATION_PATH";
+
+class ApplicationPrivateRegistry
+{
+public:
+  typedef std::pair<Application*, void* > AppHandlePairType;
+  typedef std::list<AppHandlePairType>    AppHandleContainerType;
+
+  /** Add a pair (application, library handle) in the private registry */
+  bool AddPair(Application *app, void *handle)
+    {
+    AppHandlePairType pair;
+    if (app && handle)
+      {
+      // mutex lock to ensure thread safety
+      itk::MutexLockHolder<itk::SimpleMutexLock> mutexHolder(m_Mutex);
+      pair.first = app;
+      pair.second = handle;
+      m_Container.push_back(pair);
+      return true;
+      }
+    return false;
+    }
+
+  /** When an application is deleted, unregister its pointer from private registry */
+  void UnregisterApp(const Application *app)
+    {
+    if (app)
+      {
+      // mutex lock to ensure thread safety
+      itk::MutexLockHolder<itk::SimpleMutexLock> mutexHolder(m_Mutex);
+      AppHandleContainerType::iterator it = m_Container.begin();
+      while (it != m_Container.end())
+        {
+        if ((*it).first == app)
+          {
+          (*it).first = NULL;
+          }
+        ++it;
+        }
+      }
+    }
+
+  /** Release the library handles from applications already deleted */
+  void ReleaseUnusedHandle()
+    {
+    itk::MutexLockHolder<itk::SimpleMutexLock> mutexHolder(m_Mutex);
+    AppHandleContainerType::iterator it;
+    for (it = m_Container.begin() ; it != m_Container.end() ; ++it)
+      {
+      if ((*it).first == NULL)
+        {
+        itk::DynamicLoader::CloseLibrary( static_cast<itk::LibHandle>((*it).second));
+        (*it).second = NULL;
+        }
+      }
+    m_Container.remove(AppHandlePairType((Application*) NULL, (void*) NULL));
+    }
+
+  /** close all handles at program exit */
+  ~ApplicationPrivateRegistry()
+  {
+  // unregister all ITK factories, because some of them could have been
+  // registered by the shared libs we are about to close.
+  itk::ObjectFactoryBase::UnRegisterAllFactories();
+  // Close all opened shared libs
+  AppHandleContainerType::iterator it;
+  for (it = m_Container.begin() ; it != m_Container.end() ; ++it)
+    {
+    itk::DynamicLoader::CloseLibrary( static_cast<itk::LibHandle>((*it).second));
+    }
+  m_Container.clear();
+  }
+
+private:
+  AppHandleContainerType m_Container;
+
+  itk::SimpleMutexLock m_Mutex;
+};
+// static finalizer to close opened libraries
+static ApplicationPrivateRegistry m_ApplicationPrivateRegistryGlobal;
+
+// Define callbacks to unregister applications in ApplicationPrivateRegistry
+void DeleteAppCallback(itk::Object *obj,const itk::EventObject &, void *)
+  {
+  Application *appPtr = dynamic_cast<Application*>(obj);
+  m_ApplicationPrivateRegistryGlobal.UnregisterApp(appPtr);
+  }
+void DeleteAppConstCallback(const itk::Object *obj,const itk::EventObject &, void *)
+  {
+  const Application *appPtr = dynamic_cast<const Application*>(obj);
+  m_ApplicationPrivateRegistryGlobal.UnregisterApp(appPtr);
+  }
+
 ApplicationRegistry::ApplicationRegistry()
 {
 }
@@ -39,7 +138,7 @@ void
 ApplicationRegistry::SetApplicationPath(std::string newpath)
 {
   std::ostringstream putEnvPath;
-  putEnvPath << "OTB_APPLICATION_PATH=" << newpath;
+  putEnvPath << OTB_APPLICATION_VAR << "=" << newpath;
 
   // do NOT use putenv() directly, since the string memory must be managed carefully
   itksys::SystemTools::PutEnv(putEnvPath.str().c_str());
@@ -49,10 +148,10 @@ void
 ApplicationRegistry::AddApplicationPath(std::string newpath)
 {
   std::ostringstream putEnvPath;
-  putEnvPath << "OTB_APPLICATION_PATH=";
+  putEnvPath << OTB_APPLICATION_VAR <<"=";
 
   // Can be NULL if the env var is not set
-  const char* currentEnv = itksys::SystemTools::GetEnv("OTB_APPLICATION_PATH");
+  const char* currentEnv = itksys::SystemTools::GetEnv(OTB_APPLICATION_VAR);
 
 #if defined(WIN32)
   const char pathSeparator = ';';
@@ -71,35 +170,48 @@ ApplicationRegistry::AddApplicationPath(std::string newpath)
   itksys::SystemTools::PutEnv(putEnvPath.str().c_str());
 }
 
+std::string
+ApplicationRegistry::GetApplicationPath()
+{
+  std::string ret;
+  // Can be NULL if the env var is not set
+  const char* currentEnv = itksys::SystemTools::GetEnv(OTB_APPLICATION_VAR);
+  if (currentEnv)
+    {
+    ret = std::string(currentEnv);
+    }
+  return ret;
+}
+
 Application::Pointer
-ApplicationRegistry::CreateApplication(const std::string& name)
+ApplicationRegistry::CreateApplication(const std::string& name, bool useFactory)
 {
   ApplicationPointer appli;
 
-  // Fast search
+  // Fast search : uses OTB_APPLICATION_PATH
   appli = ApplicationRegistry::CreateApplicationFaster(name);
   if (appli.IsNotNull())
     {
     return appli;
     }
 
-  // Classic search
-  ApplicationRegistry::RefreshApplicationFactories();
-
-  LightObject::Pointer possibleApp = itk::ObjectFactoryBase::CreateInstance(name.c_str());
-  
-  if (possibleApp.IsNotNull())
+  // Classic search : uses factories registered by ITK ( see ITK_AUTOLOAD_PATH )
+  if (useFactory)
     {
-    // Downcast
-    Application* app = dynamic_cast<Application*> (possibleApp.GetPointer());
-    if (app)
+    LightObject::Pointer possibleApp = itk::ObjectFactoryBase::CreateInstance(name.c_str());
+    if (possibleApp.IsNotNull())
       {
-        appli = app;
-        appli->Init();
-      }
-    else
-      {
-      otbMsgDevMacro( << "Error ApplicationRegistry factory did not return an Application: " << possibleApp->GetNameOfClass() << std::endl );
+      // Downcast
+      Application* app = dynamic_cast<Application*> (possibleApp.GetPointer());
+      if (app)
+        {
+          appli = app;
+          appli->Init();
+        }
+      else
+        {
+        otbMsgDevMacro( << "Error ApplicationRegistry factory did not return an Application: " << possibleApp->GetNameOfClass() << std::endl );
+        }
       }
     }
   
@@ -132,20 +244,12 @@ ApplicationRegistry::CreateApplicationFaster(const std::string& name)
   const char sep = '/';
 #endif
 
-  const char* otbAppPath = itksys::SystemTools::GetEnv("OTB_APPLICATION_PATH");
-  const char* itkLoadPath = itksys::SystemTools::GetEnv("ITK_AUTOLOAD_PATH");
-
-  std::ostringstream currentPath;
-  if (otbAppPath)
+  std::string otbAppPath = GetApplicationPath();
+  std::vector<itksys::String> pathList;
+  if (!otbAppPath.empty())
     {
-    currentPath << otbAppPath << pathSeparator;
+    pathList = itksys::SystemTools::SplitString(otbAppPath.c_str(),pathSeparator,false);
     }
-  if (itkLoadPath)
-    {
-    currentPath << itkLoadPath;
-    }
-
-  std::vector<itksys::String> pathList = itksys::SystemTools::SplitString(currentPath.str().c_str(),pathSeparator,false);
   for (unsigned int i=0 ; i<pathList.size() ; ++i)
     {
     std::string possiblePath = pathList[i];
@@ -155,41 +259,10 @@ ApplicationRegistry::CreateApplicationFaster(const std::string& name)
       }
     possiblePath += appLibName.str();
 
-    if (itksys::SystemTools::FileExists(possiblePath.c_str(),true))
+    appli = LoadApplicationFromPath(possiblePath,name);
+    if (appli.IsNotNull())
       {
-      itk::LibHandle   lib = itk::DynamicLoader::OpenLibrary( possiblePath.c_str() );
-      if ( lib )
-        {
-        /**
-         * Look for the symbol itkLoad in the library
-         */
-        ITK_LOAD_FUNCTION loadfunction =
-          ( ITK_LOAD_FUNCTION ) itk::DynamicLoader::GetSymbolAddress(lib, "itkLoad");
-        /**
-         * if the symbol is found call it to create the factory
-         * from the library
-         */
-        if ( loadfunction )
-          {
-          itk::ObjectFactoryBase *newfactory = ( *loadfunction )( );
-          // Downcast
-          ApplicationFactoryBase* appFactory = dynamic_cast<ApplicationFactoryBase*>(newfactory);
-
-          if (appFactory)
-            {
-            appli = appFactory->CreateApplication(name.c_str());
-            appli->Init();
-            break;
-            }
-          }
-        else
-          {
-          // In the past, some platforms crashed on the call
-          // DynamicLoader::CloseLibrary(lib) if the lib has symbols
-          // that the current executable is using.
-          itk::DynamicLoader::CloseLibrary(lib);
-          }
-        }
+      break;
       }
     }
 
@@ -197,38 +270,88 @@ ApplicationRegistry::CreateApplicationFaster(const std::string& name)
 }
 
 std::vector<std::string>
-ApplicationRegistry::GetAvailableApplications()
+ApplicationRegistry::GetAvailableApplications(bool useFactory)
 {
   ApplicationPointer appli;
+  std::set<std::string> appSet;
+
+  std::string appPrefix("otbapp_");
+  std::string appExtension = itksys::DynamicLoader::LibExtension();
+#ifdef __APPLE__
+  appExtension = ".dylib";
+#endif
 
-  ApplicationRegistry::RefreshApplicationFactories();
+#if defined(WIN32)
+  const char pathSeparator = ';';
+#else
+  const char pathSeparator = ':';
+#endif
 
-  std::list<ApplicationPointer> possibleApp;
-  std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("otbWrapperApplication");
+#ifdef _WIN32
+  const char sep = '\\';
+#else
+  const char sep = '/';
+#endif
 
-  // Downcast and Sanity check
-  for (std::list<LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i)
+  std::string otbAppPath = GetApplicationPath();
+  std::vector<itksys::String> pathList;
+  if (!otbAppPath.empty())
+    {
+    pathList = itksys::SystemTools::SplitString(otbAppPath.c_str(),pathSeparator,false);
+    }
+  for (unsigned int k=0 ; k<pathList.size() ; ++k)
     {
-    Application* io = dynamic_cast<Application*> (i->GetPointer());
-    if (io)
+    itk::Directory::Pointer dir = itk::Directory::New();
+    if (!dir->Load(pathList[k].c_str()))
       {
-      possibleApp.push_back(io);
+      continue;
       }
-    else
+    for (unsigned int i = 0; i < dir->GetNumberOfFiles(); i++)
       {
-      otbMsgDevMacro( "Error ApplicationRegistry factory did not return an Application: " << (*i)->GetNameOfClass() << std::endl );
+      const char *filename = dir->GetFile(i);
+      std::string sfilename(filename);
+      std::string::size_type extPos = sfilename.rfind(appExtension);
+      std::string::size_type prefixPos = sfilename.find(appPrefix);
+
+      // Check if current file is a shared lib with the right pattern
+      if (extPos + appExtension.size() == sfilename.size() &&
+          prefixPos == 0)
+        {
+        std::string name = sfilename.substr(appPrefix.size(),extPos-appPrefix.size());
+        std::string fullpath = pathList[k];
+        if (!fullpath.empty() && fullpath[fullpath.size() - 1] != sep)
+          {
+          fullpath.push_back(sep);
+          }
+        fullpath.append(sfilename);
+        appli = LoadApplicationFromPath(fullpath,name);
+        if (appli.IsNotNull())
+          {
+          appSet.insert(name);
+          }
+        appli = NULL;
+        }
       }
     }
 
-  // Get all the app names
-  // If ITK_AUTOLOAD_PATH contains several times the same path, then the same app appear several times
-  // Use a temporary std::set to fix this
-  std::set<std::string> appSet;
-  for(std::list<ApplicationPointer>::iterator k = possibleApp.begin();
-      k != possibleApp.end(); ++k)
+  if (useFactory)
     {
-    (*k)->Init();
-    appSet.insert((*k)->GetName());
+    std::list<LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("otbWrapperApplication");
+    // Downcast and Sanity check
+    for (std::list<LightObject::Pointer>::iterator i = allobjects.begin(); i != allobjects.end(); ++i)
+      {
+      Application* app = dynamic_cast<Application*> (i->GetPointer());
+      if (app)
+        {
+        app->Init();
+        std::string curName(app->GetName());
+        appSet.insert(curName);
+        }
+      else
+        {
+        otbMsgDevMacro( << "Error ApplicationRegistry factory did not return an Application: " << (*i)->GetNameOfClass() << std::endl );
+        }
+      }
     }
 
   std::vector<std::string> appVec;
@@ -237,46 +360,57 @@ ApplicationRegistry::GetAvailableApplications()
 }
 
 void
-ApplicationRegistry::RefreshApplicationFactories()
+ApplicationRegistry::CleanRegistry()
 {
-  std::ostringstream putEnvPath;
-  putEnvPath << "ITK_AUTOLOAD_PATH=";
-
-  // Can be NULL if the env var is not set
-  const char* currentEnv = itksys::SystemTools::GetEnv("ITK_AUTOLOAD_PATH");
-
-  // OTB specific application path
-  const char* otbApplicationPath = itksys::SystemTools::GetEnv("OTB_APPLICATION_PATH");
-
-#if defined(WIN32)
-  const char pathSeparator = ';';
-#else
-  const char pathSeparator = ':';
-#endif
+  m_ApplicationPrivateRegistryGlobal.ReleaseUnusedHandle();
+}
 
-  if (otbApplicationPath)
-    {
-    putEnvPath << otbApplicationPath << pathSeparator;
-    }
+Application::Pointer
+ApplicationRegistry::LoadApplicationFromPath(std::string path,std::string name)
+{
+  Application::Pointer appli;
 
-  if (currentEnv)
+  if (itksys::SystemTools::FileExists(path.c_str(),true))
     {
-    putEnvPath << currentEnv;
-    }
-
-  // do NOT use putenv() directly, since the string memory must be managed carefully
-  itksys::SystemTools::PutEnv(putEnvPath.str().c_str());
-
-  // Reload factories to take into account new path
-  itk::ObjectFactoryBase::ReHash();
+    itk::LibHandle lib = itk::DynamicLoader::OpenLibrary(path.c_str());
+    if (lib)
+      {
+      /**
+       * Look for the symbol itkLoad in the library
+       */
+      ITK_LOAD_FUNCTION loadfunction =
+        ( ITK_LOAD_FUNCTION ) itk::DynamicLoader::GetSymbolAddress(lib, "itkLoad");
+      /**
+       * if the symbol is found call it to create the factory
+       * from the library
+       */
+      if ( loadfunction )
+        {
+        itk::ObjectFactoryBase *newfactory = ( *loadfunction )( );
+        // Downcast
+        ApplicationFactoryBase* appFactory = dynamic_cast<ApplicationFactoryBase*>(newfactory);
 
-  std::ostringstream resetEnvPath;
-  resetEnvPath << "ITK_AUTOLOAD_PATH=";
-  if (currentEnv)
-    {
-    resetEnvPath << currentEnv;
+        if (appFactory)
+          {
+          appli = appFactory->CreateApplication(name.c_str());
+          if (appli.IsNotNull())
+            {
+            appli->Init();
+            // register library handle
+            m_ApplicationPrivateRegistryGlobal.AddPair(appli.GetPointer(), (void*) lib);
+            // set a callback on DeleteEvent
+            itk::CStyleCommand::Pointer command = itk::CStyleCommand::New();
+            command->SetCallback(&DeleteAppCallback);
+            command->SetConstCallback(&DeleteAppConstCallback);
+            appli->AddObserver(itk::DeleteEvent(),command);
+            return appli;
+            }
+          }
+        }
+      itk::DynamicLoader::CloseLibrary(lib);
+      }
     }
-  itksys::SystemTools::PutEnv(resetEnvPath.str().c_str());
+  return appli;
 }
 
 
diff --git a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
index dcc59f91dccf05c975fa1e74e9eaa860a65da8c8..c3cd479b1791c7fdd14906dcffd7166f6b6d91b1 100644
--- a/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
+++ b/Modules/Wrappers/CommandLine/src/otbWrapperCommandLineLauncher.cxx
@@ -321,9 +321,8 @@ void CommandLineLauncher::LoadApplication()
   if (m_Application.IsNull())
     {
     std::cerr << "ERROR: Could not find application \"" << moduleName << "\"" << std::endl;
-
-    const char * ITK_AUTOLOAD_PATH = itksys::SystemTools::GetEnv("ITK_AUTOLOAD_PATH");
-    std::cerr << "ERROR: Module search path: " << (ITK_AUTOLOAD_PATH ? ITK_AUTOLOAD_PATH : "none (check ITK_AUTOLOAD_PATH)") << std::endl;
+    std::string modulePath = ApplicationRegistry::GetApplicationPath();
+    std::cerr << "ERROR: Module search path: " << (modulePath.empty() ? "none (check OTB_APPLICATION_PATH)" : modulePath) << std::endl;
 
     std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
     if (list.size() == 0)
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputFilenameParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputFilenameParameter.h
index 31641899e080989c3f1680b84eb228b81a6a705e..d2c4370b7f8a98c6305cbb606e61d3c90dd4ccea 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputFilenameParameter.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputFilenameParameter.h
@@ -42,6 +42,9 @@ public:
   QtWidgetOutputFilenameParameter(OutputFilenameParameter*, QtWidgetModel*);
   virtual ~QtWidgetOutputFilenameParameter();
 
+  inline const QLineEdit* GetInput() const;
+  inline QLineEdit* GetInput();
+
 protected slots:
   void SetFileName( const QString& value );
   void SelectFile();
@@ -63,6 +66,23 @@ private:
 };
 
 
+inline
+const QLineEdit*
+QtWidgetOutputFilenameParameter
+::GetInput() const
+{
+  return m_Input;
+}
+
+inline
+QLineEdit*
+QtWidgetOutputFilenameParameter
+::GetInput()
+{
+  return m_Input;
+}
+
+
 }
 }
 
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputImageParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputImageParameter.h
index 4d9e2b59a035c3c10a4029633f0eb0ef2e2b1f26..d0906049e1be304af383749692a695db8d015466 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputImageParameter.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputImageParameter.h
@@ -42,6 +42,9 @@ public:
   QtWidgetOutputImageParameter(OutputImageParameter*, QtWidgetModel*);
   virtual ~QtWidgetOutputImageParameter();
 
+  inline const QLineEdit* GetInput() const;
+  inline QLineEdit* GetInput();
+
   /** Get the PixelType*/
   //itkGetMacro(PixelType, int);
 
@@ -72,6 +75,22 @@ private:
 };
 
 
+inline
+const QLineEdit*
+QtWidgetOutputImageParameter
+::GetInput() const
+{
+  return m_Input;
+}
+
+inline
+QLineEdit*
+QtWidgetOutputImageParameter
+::GetInput()
+{
+  return m_Input;
+}
+
 }
 }
 
diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputVectorDataParameter.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputVectorDataParameter.h
index 140d7666e460daf7536d814d437f0f4c34edf4ba..43af269455983142d5a50b7b532f9facb827c95a 100644
--- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputVectorDataParameter.h
+++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetOutputVectorDataParameter.h
@@ -42,6 +42,9 @@ public:
   QtWidgetOutputVectorDataParameter(OutputVectorDataParameter*, QtWidgetModel*);
   virtual ~QtWidgetOutputVectorDataParameter();
 
+  inline const QLineEdit* GetInput() const;
+  inline QLineEdit* GetInput();
+
   /** Get the PixelType*/
   //itkGetMacro(PixelType, int);
 
@@ -69,6 +72,23 @@ private:
 };
 
 
+
+inline
+const QLineEdit*
+QtWidgetOutputVectorDataParameter
+::GetInput() const
+{
+  return m_Input;
+}
+
+inline
+QLineEdit*
+QtWidgetOutputVectorDataParameter
+::GetInput()
+{
+  return m_Input;
+}
+
 }
 }
 
diff --git a/Modules/Wrappers/QtWidget/src/otbApplicationLauncherQt.cxx b/Modules/Wrappers/QtWidget/src/otbApplicationLauncherQt.cxx
index 24036ac4ac4ab276a50635fd9da69152547502c9..99e0779a571dd5ebcb88e8b87d1a9f51f7b44290 100644
--- a/Modules/Wrappers/QtWidget/src/otbApplicationLauncherQt.cxx
+++ b/Modules/Wrappers/QtWidget/src/otbApplicationLauncherQt.cxx
@@ -53,7 +53,6 @@ int main(int argc, char* argv[])
     std::copy(argv + 2, argv + argc, std::back_inserter(modulePathList));
 
     // Load the path in the environment
-    std::string specificEnv("ITK_AUTOLOAD_PATH=");
     std::list<std::string>::const_iterator it = modulePathList.begin();
     while( it != modulePathList.end() )
       {
@@ -68,9 +67,8 @@ int main(int argc, char* argv[])
 
     {
     std::cerr << "Could not find application " << moduleName << std::endl;
-
-    const char* modulePath = itksys::SystemTools::GetEnv("ITK_AUTOLOAD_PATH");
-    std::cout << "Module search path : " << (modulePath ? modulePath : "") << std::endl;
+    std::string modulePath = ApplicationRegistry::GetApplicationPath();
+    std::cout << "Module search path : " << modulePath << std::endl;
     std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
 
     std::cout << "Available applications : " << (list.empty() ? "None" : "") << std::endl;
diff --git a/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetShowWidget.cxx b/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetShowWidget.cxx
index c3e3086e236552147cf0d71ed0deebde104f74bd..3dae376a4f942ac760dfda3860d59f67b517dc53 100644
--- a/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetShowWidget.cxx
+++ b/Modules/Wrappers/QtWidget/test/otbWrapperQtWidgetShowWidget.cxx
@@ -41,7 +41,6 @@ int otbWrapperQtWidgetShowWidget(int argc, char* argv[])
     std::copy(argv + 1, argv + argc, std::back_inserter(modulePathList));
 
     // Load the path in the environment
-    std::string specificEnv("ITK_AUTOLOAD_PATH=");
     std::list<std::string>::const_iterator it = modulePathList.begin();
     while( it != modulePathList.end() )
       {
diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i
index 3a8247b761fc0dadf99bc6aa1e372ec5f005e93b..ff3e4fc597e5f48342d507603a4594ac06b19e8c 100644
--- a/Modules/Wrappers/SWIG/src/otbApplication.i
+++ b/Modules/Wrappers/SWIG/src/otbApplication.i
@@ -247,13 +247,13 @@ public:
         otb::Wrapper::Parameter *parameter = $self->GetParameterList()->GetParameterByKey(pkey); \
         InputImageParameter* inputImageParam = dynamic_cast<InputImageParameter*>(parameter); \
         typedef otb::##ImageClass##<##PixelDataType##>   ImageType;     \
-        typename ImageType::Pointer output = ImageType::New();          \
-        typedef typename ImageType::SizeType        SizeType;           \
-        typedef typename ImageType::IndexType       IndexType;          \
-        typedef typename ImageType::RegionType      RegionType;         \
-        typedef typename ImageType::PointType       PointType;          \
-        typedef typename ImageType::SpacingType     SpacingType;        \
-        typedef typename ImageType::DirectionType   DirectionType;      \
+        ImageType::Pointer output = ImageType::New();          \
+        typedef ImageType::SizeType        SizeType;           \
+        typedef ImageType::IndexType       IndexType;          \
+        typedef ImageType::RegionType      RegionType;         \
+        typedef ImageType::PointType       PointType;          \
+        typedef ImageType::SpacingType     SpacingType;        \
+        typedef ImageType::DirectionType   DirectionType;      \
         IndexType start;                                                \
         DirectionType direction;                                        \
         start.Fill( 0 );                                                \
@@ -313,14 +313,14 @@ public:
         otb::Wrapper::Parameter *parameter = $self->GetParameterList()->GetParameterByKey(pkey); \
         OutputImageParameter* outputImageParam = dynamic_cast<OutputImageParameter*>(parameter); \
         typedef itk::ImageBase<2> ImageBaseType;                        \
-        typedef typename ImageBaseType::RegionType RegionType;          \
+        typedef ImageBaseType::RegionType RegionType;          \
         ImageBaseType::Pointer imageBase;                               \
         imageBase = outputImageParam->GetValue();                       \
         imageBase->Update();                                            \
-        typedef typename ImageBaseType::SizeType        SizeType;       \
-        typedef typename ImageBaseType::IndexType       IndexType;      \
-        typedef typename ImageBaseType::PointType       PointType;      \
-        typedef typename ImageBaseType::SpacingType     SpacingType;    \
+        typedef ImageBaseType::SizeType        SizeType;       \
+        typedef ImageBaseType::IndexType       IndexType;      \
+        typedef ImageBaseType::PointType       PointType;      \
+        typedef ImageBaseType::SpacingType     SpacingType;    \
         RegionType region = imageBase->GetBufferedRegion();             \
         SizeType size =  region.GetSize();                              \
         *dim1 = size[1];                                                \
diff --git a/Modules/Wrappers/SWIG/test/java/CMakeLists.txt b/Modules/Wrappers/SWIG/test/java/CMakeLists.txt
index 993160e4fb8500ce0de0079cac57e5ce1700d888..3b0917f47872a0f4444c3992754904e04f584eb7 100644
--- a/Modules/Wrappers/SWIG/test/java/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/java/CMakeLists.txt
@@ -1,7 +1,7 @@
 include( UseJava )
 
 set(TEST_DRIVER otbTestDriver
-    --add-before-env ITK_AUTOLOAD_PATH $<TARGET_FILE_DIR:otbapp_Smoothing>
+    --add-before-env OTB_APPLICATION_PATH $<TARGET_FILE_DIR:otbapp_Smoothing>
 )
 
 set( PATH_SEPARATOR ":")
diff --git a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
index 2eb46785fb95436f872bfec5c724d7070f1ce62b..c93fb38965b0791888e2c613221c388fd7ea0f77 100644
--- a/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
+++ b/Modules/Wrappers/SWIG/test/python/CMakeLists.txt
@@ -1,7 +1,7 @@
 set(TEST_DRIVER otbTestDriver
     --add-before-env PYTHONPATH        "${OTBSWIGWrapper_BINARY_DIR}/src"
     --add-before-env PYTHONPATH        $<TARGET_FILE_DIR:_otbApplication>
-    --add-before-env ITK_AUTOLOAD_PATH $<TARGET_FILE_DIR:otbapp_Smoothing> )
+    --add-before-env OTB_APPLICATION_PATH $<TARGET_FILE_DIR:otbapp_Smoothing> )
 
 add_test( NAME pyTvSmoothing
           COMMAND ${TEST_DRIVER} Execute