diff --git a/Code/BasicFilters/otbMeanShiftImageFilter.txx b/Code/BasicFilters/otbMeanShiftImageFilter.txx
index 9d8614950eadd46135dcd357fe596d61b9ca16f1..1bd3aa742e13f6f475fc51356f41dfe62fdeaef8 100644
--- a/Code/BasicFilters/otbMeanShiftImageFilter.txx
+++ b/Code/BasicFilters/otbMeanShiftImageFilter.txx
@@ -192,7 +192,7 @@ MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledOutput, TBufferConverter
 template <class TInputImage, class TOutputImage, class TLabeledOutput, class TBufferConverter>
 void
 MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledOutput, TBufferConverter>
-::ThreadedGenerateData(const RegionType& outputRegionForThread, int threadId)
+::ThreadedGenerateData(const RegionType& outputRegionForThread, int itkNotUsed(threadId))
 {
   // Input and output pointers
   typename InputImageType::ConstPointer inputPtr  = this->GetInput();
diff --git a/Code/BasicFilters/otbStreamingShrinkImageFilter.cxx b/Code/BasicFilters/otbStreamingShrinkImageFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3d4bd8d9e92b175790fb5236b101caa10bd7bf1e
--- /dev/null
+++ b/Code/BasicFilters/otbStreamingShrinkImageFilter.cxx
@@ -0,0 +1,103 @@
+/*=========================================================================
+
+  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 "otbStreamingShrinkImageFilter.h"
+
+namespace otb
+{
+
+unsigned int
+StreamingShrinkImageRegionSplitter
+::GetNumberOfSplits(const RegionType& region, unsigned int requestedNumber)
+{
+  unsigned int theoricalNbPixelPerTile = region.GetNumberOfPixels() / requestedNumber;
+  unsigned int theoricalTileDimension = static_cast<unsigned int> (vcl_sqrt(static_cast<double>(theoricalNbPixelPerTile)) );
+
+  // Take the previous multiple of m_TileSizeAlignment (eventually generate more splits than requested)
+  m_TileDimension = theoricalTileDimension / m_TileSizeAlignment * m_TileSizeAlignment;
+
+  // Minimal tile size is m_TileSizeAlignment * m_TileSizeAlignment
+  if (m_TileDimension < m_TileSizeAlignment)
+    {
+    otbMsgDevMacro(<< "Using the minimal tile size : " << m_TileSizeAlignment << " * " << m_TileSizeAlignment);
+    m_TileDimension = m_TileSizeAlignment;
+    }
+
+  // Use the computed tile size, and generate (m_TileDimension * 1) tiles
+  const SizeType&  regionSize = region.GetSize();
+  m_SplitsPerDimension[0] = (regionSize[0] + m_TileDimension - 1) / m_TileDimension;
+  m_SplitsPerDimension[1] = regionSize[1] / m_TileSizeAlignment;
+
+  unsigned int numPieces = 1;
+  for (unsigned int j = 0; j < ImageDimension; ++j)
+    {
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  otbMsgDevMacro(<< "Tile dimension : " << m_TileDimension)
+  otbMsgDevMacro(<< "Number of splits per dimension : " << m_SplitsPerDimension[0] << " " <<  m_SplitsPerDimension[1])
+
+  return numPieces;
+}
+
+StreamingShrinkImageRegionSplitter::RegionType
+StreamingShrinkImageRegionSplitter
+::GetSplit(unsigned int i, unsigned int numberOfPieces, const RegionType& region)
+{
+  RegionType splitRegion;
+  IndexType  splitIndex;
+
+  // Compute the actual number of splits
+  unsigned int numPieces = 1;
+  for (unsigned int j = 0; j < ImageDimension; ++j)
+    {
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  if (i >= numPieces)
+    {
+    itkExceptionMacro("Requested split number " << i << " but region contains only " << numPieces << " splits");
+    }
+
+  // Compute the split index in the streaming grid
+  splitIndex[1] = i / m_SplitsPerDimension[0];
+  splitIndex[0] = i % m_SplitsPerDimension[0];
+
+  // Transform the split index to the actual coordinates
+  splitRegion.SetIndex(0, region.GetIndex(0) + m_TileDimension * splitIndex[0]);
+  splitRegion.SetIndex(1, region.GetIndex(1) + m_TileSizeAlignment * splitIndex[1]);
+
+  splitRegion.SetSize(0, m_TileDimension);
+  splitRegion.SetSize(1, 1);
+
+  // Handle the borders
+  splitRegion.Crop(region);
+
+  return splitRegion;
+}
+
+void
+StreamingShrinkImageRegionSplitter
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "SplitsPerDimension : " << m_SplitsPerDimension << std::endl;
+  os << indent << "TileDimension      : " << m_TileDimension << std::endl;
+  os << indent << "TileSizeAlignment  : " << m_TileSizeAlignment << std::endl;
+}
+
+} // End namespace otb
diff --git a/Code/BasicFilters/otbStreamingShrinkImageFilter.h b/Code/BasicFilters/otbStreamingShrinkImageFilter.h
index c077557e021e7e242895479b509ad395c5efa305..b6b3e9eabc91da4b5c32fc56b3e5d7b8f29e407b 100644
--- a/Code/BasicFilters/otbStreamingShrinkImageFilter.h
+++ b/Code/BasicFilters/otbStreamingShrinkImageFilter.h
@@ -25,11 +25,134 @@
 #include "otbPersistentImageFilter.h"
 #include "otbPersistentFilterStreamingDecorator.h"
 
-#include "itkTimeProbe.h"
+#include "otbStreamingManager.h"
 
 namespace otb
 {
 
+class ITK_EXPORT StreamingShrinkImageRegionSplitter : public itk::ImageRegionSplitter<2>
+{
+public:
+  /** Standard class typedefs. */
+  typedef StreamingShrinkImageRegionSplitter        Self;
+  typedef itk::ImageRegionSplitter<2>               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(StreamingShrinkImageRegionSplitter, itk::Object);
+
+  /** Dimension of the image available at compile time. */
+  itkStaticConstMacro(ImageDimension, unsigned int, 2);
+
+  /** Dimension of the image available at run time. */
+  static unsigned int GetImageDimension()
+  {
+    return ImageDimension;
+  }
+
+  /** Index typedef support. An index is used to access pixel values. */
+  typedef itk::Index<ImageDimension>         IndexType;
+  typedef IndexType::IndexValueType IndexValueType;
+
+  /** Size typedef support. A size is used to define region bounds. */
+  typedef itk::Size<ImageDimension>        SizeType;
+  typedef SizeType::SizeValueType SizeValueType;
+
+  /** Region typedef support.   */
+  typedef itk::ImageRegion<ImageDimension> RegionType;
+
+  /** How many pieces can the specified region be split? A given region
+   *  cannot always be divided into the requested number of pieces.  For
+   *  instance, if the numberOfPieces exceeds the number of pixels along
+   *  a certain dimensions, then some splits will not be possible.
+   */
+  virtual unsigned int GetNumberOfSplits(const RegionType& region,
+                                         unsigned int requestedNumber);
+
+  /** Get a region definition that represents the ith piece a specified region.
+   * The "numberOfPieces" specified should be less than or equal to what
+   * GetNumberOfSplits() returns. */
+  virtual RegionType GetSplit(unsigned int i, unsigned int numberOfPieces,
+                              const RegionType& region);
+
+  itkGetMacro(TileSizeAlignment, unsigned int);
+  itkSetMacro(TileSizeAlignment, unsigned int);
+
+  itkGetMacro(TileDimension, unsigned int);
+
+  itkSetMacro(ShrinkFactor, unsigned int);
+  itkGetMacro(ShrinkFactor, unsigned int);
+
+protected:
+  StreamingShrinkImageRegionSplitter() : m_SplitsPerDimension(0U), m_ShrinkFactor(10) {}
+  virtual ~StreamingShrinkImageRegionSplitter() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+private:
+  StreamingShrinkImageRegionSplitter(const StreamingShrinkImageRegionSplitter &); //purposely not implemented
+  void operator =(const StreamingShrinkImageRegionSplitter&); //purposely not implemented
+
+  itk::FixedArray<unsigned int, ImageDimension> m_SplitsPerDimension;
+  unsigned int m_TileDimension;
+  unsigned int m_TileSizeAlignment;
+  unsigned int m_ShrinkFactor;
+};
+
+
+template <class TInputImage>
+class ITK_EXPORT StreamingShrinkStreamingManager : public StreamingManager<TInputImage>
+{
+public:
+  /** Standard class typedefs. */
+  typedef StreamingShrinkStreamingManager Self;
+  typedef StreamingManager<TInputImage>   Superclass;
+  typedef itk::SmartPointer<Self>         Pointer;
+  typedef itk::SmartPointer<const Self>   ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Runtime information support. */
+  itkTypeMacro(StreamingShrinkStreamingManager, StreamingManager);
+
+  typedef TInputImage                            ImageType;
+  typedef typename ImageType::Pointer            ImagePointerType;
+  typedef typename ImageType::RegionType         RegionType;
+  typedef typename RegionType::IndexType         IndexType;
+  typedef typename RegionType::SizeType          SizeType;
+  typedef typename ImageType::InternalPixelType  PixelType;
+
+  itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension);
+
+  /** Actually computes the stream divisions, according to the specified streaming mode,
+   * eventually using the input parameter to estimate memory consumption */
+  virtual void PrepareStreaming(itk::DataObject * input, const RegionType &region);
+
+  void SetShrinkFactor(unsigned int val)
+  {
+    m_ShrinkFactor = val;
+  }
+
+  unsigned int GetShrinkFactor() const
+  {
+    return m_ShrinkFactor;
+  }
+
+protected:
+  StreamingShrinkStreamingManager();
+  virtual ~StreamingShrinkStreamingManager();
+
+private:
+  StreamingShrinkStreamingManager(const StreamingShrinkStreamingManager &); //purposely not implemented
+  void operator =(const StreamingShrinkStreamingManager&); //purposely not implemented
+
+  unsigned int m_ShrinkFactor;
+};
+
 
 /** \class PersistentShrinkImageFilter
  * \brief
@@ -116,9 +239,6 @@ private:
 
   /** The shrink factor */
   unsigned int m_ShrinkFactor;
-
-  itk::TimeProbe m_Chrono;
-
 }; // end of class PersistentStatisticsVectorImageFilter
 
 
@@ -156,10 +276,14 @@ public:
   typedef TOutputImage                                OutputImageType;
   typedef typename Superclass::FilterType             PersistentFilterType;
 
+  typedef StreamingShrinkStreamingManager<InputImageType>       StreamingShrinkStreamingManagerType;
+  typedef typename StreamingShrinkStreamingManagerType::Pointer StreamingShrinkStreamingManagerPointerType;
+
   void SetInput(InputImageType * input)
   {
     this->GetFilter()->SetInput(input);
   }
+
   const InputImageType * GetInput()
   {
     return this->GetFilter()->GetInput();
@@ -173,15 +297,29 @@ public:
   otbSetObjectMemberMacro(Filter, ShrinkFactor, unsigned int);
   otbGetObjectMemberMacro(Filter, ShrinkFactor, unsigned int);
 
+  virtual void Update(void)
+  {
+    m_StreamingManager->SetShrinkFactor( this->GetFilter()->GetShrinkFactor() );
+    Superclass::Update();
+  }
+
 protected:
   /** Constructor */
-  StreamingShrinkImageFilter() {}
+  StreamingShrinkImageFilter()
+  {
+    // Use a specific StreamingManager implementation
+    m_StreamingManager = StreamingShrinkStreamingManagerType::New();
+    this->GetStreamer()->SetStreamingManager( m_StreamingManager );
+  }
+
   /** Destructor */
   virtual ~StreamingShrinkImageFilter() {}
 
 private:
   StreamingShrinkImageFilter(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
+
+  StreamingShrinkStreamingManagerPointerType m_StreamingManager;
 };
 
 } // End namespace otb
diff --git a/Code/BasicFilters/otbStreamingShrinkImageFilter.txx b/Code/BasicFilters/otbStreamingShrinkImageFilter.txx
index 4c7a810c1bf1d2ea5026ed9822ccd697cae73ca0..cd045e31f27cf8c625ed7bb97dda07de7a163956 100644
--- a/Code/BasicFilters/otbStreamingShrinkImageFilter.txx
+++ b/Code/BasicFilters/otbStreamingShrinkImageFilter.txx
@@ -26,6 +26,34 @@
 namespace otb
 {
 
+template <class TImage>
+StreamingShrinkStreamingManager<TImage>::StreamingShrinkStreamingManager()
+{
+}
+
+template <class TImage>
+StreamingShrinkStreamingManager<TImage>::~StreamingShrinkStreamingManager()
+{
+}
+
+template <class TImage>
+void
+StreamingShrinkStreamingManager<TImage>::PrepareStreaming( itk::DataObject * input, const RegionType &region )
+{
+  typedef otb::StreamingShrinkImageRegionSplitter TileSplitterType;
+  TileSplitterType::Pointer splitter = TileSplitterType::New();
+  splitter->SetTileSizeAlignment(m_ShrinkFactor);
+  this->m_Splitter = splitter;
+
+  unsigned long nbDivisions = EstimateOptimalNumberOfDivisions(input, region);
+  this->m_ComputedNumberOfSplits = this->m_Splitter->GetNumberOfSplits(region, nbDivisions);
+  otbMsgDevMacro(<< "Number of split : " << this->m_ComputedNumberOfSplits)
+
+  // Save the region to generate the splits later
+  this->m_Region = region;
+}
+
+
 /** Constructor */
 template <class TInputImage, class TOutputImage>
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
@@ -79,31 +107,22 @@ PersistentShrinkImageFilter<TInputImage, TOutputImage>
   // Nothing that needs to be allocated for the remaining outputs
 }
 
+
 template<class TInputImage, class TOutputImage>
 void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::Reset()
 {
-  // Reinit the chrono
-  m_Chrono = itk::TimeProbe();
-
-  // get pointers to the input and output
+  // Get pointers to the input and output
   InputImageType* inputPtr = const_cast<InputImageType*>(this->GetInput());
   inputPtr->UpdateOutputInformation();
 
   m_ShrinkedOutput = OutputImageType::New();
 
-  // we need to compute the output spacing, the output image size, and the
-  // output image start index
   const typename InputImageType::SpacingType&
                                            inputSpacing = inputPtr->GetSpacing();
   const typename InputImageType::SizeType& inputSize
     = inputPtr->GetLargestPossibleRegion().GetSize();
-  const typename InputImageType::IndexType& inputStartIndex
-    = inputPtr->GetLargestPossibleRegion().GetIndex();
-  
-  otbMsgDebugMacro(<< "Input index " << inputStartIndex);
-  otbMsgDebugMacro(<< "Input size: " << inputSize);
 
   typename OutputImageType::SpacingType shrinkedOutputSpacing;
   typename OutputImageType::RegionType  shrinkedOutputLargestPossibleRegion;
@@ -113,9 +132,7 @@ PersistentShrinkImageFilter<TInputImage, TOutputImage>
   for (unsigned int i = 0; i < OutputImageType::ImageDimension; ++i)
     {
     shrinkedOutputSpacing[i] = inputSpacing[i] * static_cast<double>(m_ShrinkFactor);
-    //shrinkedOutputSize[i] = static_cast<int>(static_cast<double>(inputSize[i]) / static_cast<double>(m_ShrinkFactor));
     shrinkedOutputSize[i] = inputSize[i] / m_ShrinkFactor;
-    //outputStartIndex[i] = inputStartIndex[i];
     shrinkedOutputStartIndex[i] = 0;
     }
 
@@ -134,7 +151,6 @@ void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::Synthetize()
 {
-  otbMsgDevMacro( "Shrink time : " << m_Chrono.GetTotal() )
 }
 
 template<class TInputImage, class TOutputImage>
@@ -142,7 +158,6 @@ void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::BeforeThreadedGenerateData()
 {
-  m_Chrono.Start();
 }
 
 template<class TInputImage, class TOutputImage>
@@ -175,7 +190,6 @@ void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::AfterThreadedGenerateData()
 {
-  m_Chrono.Stop();
 }
 
 template <class TImage, class TOutputImage>
diff --git a/Code/Common/otbFilterWatcherBase.cxx b/Code/Common/otbFilterWatcherBase.cxx
index 2e47d89fc3ba3fc19c98f3368af84b29b705ac8d..742eb90d370ac5ece85d2ae495e7a9e3a5bf48ca 100644
--- a/Code/Common/otbFilterWatcherBase.cxx
+++ b/Code/Common/otbFilterWatcherBase.cxx
@@ -46,11 +46,11 @@ FilterWatcherBase
 
   // Assign the callbacks
   m_StartFilterCommand->SetCallbackFunction(this,
-                                            &FilterWatcherBase::StartFilter);
+                                            &FilterWatcherBase::StartFilterCallback);
   m_EndFilterCommand->SetCallbackFunction(this,
-                                          &FilterWatcherBase::EndFilter);
+                                          &FilterWatcherBase::EndFilterCallback);
   m_ProgressFilterCommand->SetCallbackFunction(this,
-                                               &FilterWatcherBase::ShowProgress);
+                                               &FilterWatcherBase::ShowProgressCallback);
 
   // Add the commands as observers
   m_StartTag = m_Process->AddObserver(itk::StartEvent(),
@@ -90,11 +90,11 @@ FilterWatcherBase
 
     // Assign the callbacks
     m_StartFilterCommand->SetCallbackFunction(this,
-                                              &FilterWatcherBase::StartFilter);
+                                              &FilterWatcherBase::StartFilterCallback);
     m_EndFilterCommand->SetCallbackFunction(this,
-                                            &FilterWatcherBase::EndFilter);
+                                            &FilterWatcherBase::EndFilterCallback);
     m_ProgressFilterCommand->SetCallbackFunction(this,
-                                                 &FilterWatcherBase::ShowProgress);
+                                                 &FilterWatcherBase::ShowProgressCallback);
 
     // Add the commands as observers
     m_StartTag = m_Process->AddObserver(itk::StartEvent(), m_StartFilterCommand);
@@ -132,11 +132,11 @@ FilterWatcherBase
 
     // Assign the callbacks
     m_StartFilterCommand->SetCallbackFunction(this,
-                                              &FilterWatcherBase::StartFilter);
+                                              &FilterWatcherBase::StartFilterCallback);
     m_EndFilterCommand->SetCallbackFunction(this,
-                                            &FilterWatcherBase::EndFilter);
+                                            &FilterWatcherBase::EndFilterCallback);
     m_ProgressFilterCommand->SetCallbackFunction(this,
-                                                 &FilterWatcherBase::ShowProgress);
+                                                 &FilterWatcherBase::ShowProgressCallback);
 
     // Add the commands as observers
     m_StartTag = m_Process->AddObserver(itk::StartEvent(), m_StartFilterCommand);
diff --git a/Code/Common/otbFilterWatcherBase.h b/Code/Common/otbFilterWatcherBase.h
index 9e64c176323186f99f421e1e8bc31933df6fbf41..ef739e490c713ab76d91a39705275a4fbd4711ae 100644
--- a/Code/Common/otbFilterWatcherBase.h
+++ b/Code/Common/otbFilterWatcherBase.h
@@ -85,6 +85,24 @@ public:
 
 protected:
 
+  /** Callback method to show the ProgressEvent */
+  virtual void ShowProgressCallback()
+  {
+    this->ShowProgress();
+  }
+
+  /** Callback method to show the StartEvent */
+  virtual void StartFilterCallback()
+  {
+    this->StartFilter();
+  }
+
+  /** Callback method to show the EndEvent */
+  virtual void EndFilterCallback()
+  {
+    this->EndFilter();
+  }
+
   /** Callback method to show the ProgressEvent */
   virtual void ShowProgress() = 0;
 
diff --git a/Code/Common/otbImageRegionSquareTileSplitter.h b/Code/Common/otbImageRegionSquareTileSplitter.h
new file mode 100644
index 0000000000000000000000000000000000000000..10dd5b71e45436d6640a2e1f401d2a46d0ca59ed
--- /dev/null
+++ b/Code/Common/otbImageRegionSquareTileSplitter.h
@@ -0,0 +1,146 @@
+/*=========================================================================
+
+  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 __otbImageRegionSquareTileSplitter_h
+#define __otbImageRegionSquareTileSplitter_h
+
+#include "itkObject.h"
+#include "itkRegion.h"
+#include "itkImageRegion.h"
+#include "itkImageRegionSplitter.h"
+#include "itkObjectFactory.h"
+#include "itkIndex.h"
+#include "itkSize.h"
+
+namespace otb
+{
+
+/** \class ImageRegionSquareTileSplitter
+   * \brief Divide a region into several pieces.
+   *
+   * ImageRegionSquareTileSplitter divides an ImageRegion into smaller regions.
+   * ImageRegionSquareTileSplitter is used by the StreamingImageFilter to divide a
+   * requested output region into a series of smaller requests of the
+   * pipeline.  This object has two basic methods: GetNumberOfSplits()
+   * and GetSplit().
+   *
+   * GetNumberOfSplits() is used to determine how may subregions a given
+   * region can be divided.  You call GetNumberOfSplits with an argument
+   * that is the number of subregions you want.  If the image region can
+   * support that number of subregions, that number is returned.
+   * Otherwise, the maximum number of splits a region can support will
+   * be returned.  For example, if a region splitter class only divides
+   * a region into horizontal slabs, then the maximum number of splits
+   * will be the number of rows in the region.
+   *
+   * GetSplit() returns the ith of N subregions (as an ImageRegion object).
+   *
+   * This ImageRegionSquareTileSplitter class divides a region along the outermost
+   * dimension. If the outermost dimension has size 1 (i.e. a volume
+   * with a single slice), the ImageRegionSquareTileSplitter will divide the
+   * region along the next outermost dimension. If that dimension has size 1,
+   * the process continues with the next outermost dimension.
+   *
+   * Regions obtained by the ImageRegionSquareTileSplitter are aligned on a grid
+   * with width of 256. Divisions can occur only at line defined as k*256.
+   *
+   * Other ImageRegionSquareTileSplitter subclasses could divide an image into
+   * more uniform shaped regions instead of slabs.
+   *
+   * \sa ImageRegionMultidimensionalSplitter
+   *
+   * \ingroup ITKSystemObjects
+   * \ingroup DataProcessing
+ */
+
+template <unsigned int VImageDimension>
+class ITK_EXPORT ImageRegionSquareTileSplitter : public itk::ImageRegionSplitter<VImageDimension>
+{
+public:
+  /** Standard class typedefs. */
+  typedef ImageRegionSquareTileSplitter                Self;
+  typedef itk::ImageRegionSplitter<VImageDimension> 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(ImageRegionSquareTileSplitter, itk::Object);
+
+  /** Dimension of the image available at compile time. */
+  itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
+
+  /** Dimension of the image available at run time. */
+  static unsigned int GetImageDimension()
+  {
+    return VImageDimension;
+  }
+
+  /** Index typedef support. An index is used to access pixel values. */
+  typedef itk::Index<VImageDimension>        IndexType;
+  typedef typename IndexType::IndexValueType IndexValueType;
+
+  /** Size typedef support. A size is used to define region bounds. */
+  typedef itk::Size<VImageDimension>       SizeType;
+  typedef typename SizeType::SizeValueType SizeValueType;
+
+  /** Region typedef support.   */
+  typedef itk::ImageRegion<VImageDimension> RegionType;
+
+  /** How many pieces can the specified region be split? A given region
+   *  cannot always be divided into the requested number of pieces.  For
+   *  instance, if the numberOfPieces exceeds the number of pixels along
+   *  a certain dimensions, then some splits will not be possible.
+   */
+  virtual unsigned int GetNumberOfSplits(const RegionType& region,
+                                         unsigned int requestedNumber);
+
+  /** Get a region definition that represents the ith piece a specified region.
+   * The "numberOfPieces" specified should be less than or equal to what
+   * GetNumberOfSplits() returns. */
+  virtual RegionType GetSplit(unsigned int i, unsigned int numberOfPieces,
+                              const RegionType& region);
+
+  itkGetMacro(TileSizeAlignment, unsigned int);
+  itkSetMacro(TileSizeAlignment, unsigned int);
+
+  itkGetMacro(TileDimension, unsigned int);
+
+protected:
+  ImageRegionSquareTileSplitter() : m_SplitsPerDimension(0U), m_TileDimension(0), m_TileSizeAlignment(16) {}
+  virtual ~ImageRegionSquareTileSplitter() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+private:
+  ImageRegionSquareTileSplitter(const ImageRegionSquareTileSplitter &); //purposely not implemented
+  void operator =(const ImageRegionSquareTileSplitter&); //purposely not implemented
+
+  itk::FixedArray<unsigned int, VImageDimension> m_SplitsPerDimension;
+  unsigned int m_TileDimension;
+  unsigned int m_TileSizeAlignment;
+};
+
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+# include "otbImageRegionSquareTileSplitter.txx"
+#endif
+
+#endif
diff --git a/Code/Common/otbImageRegionSquareTileSplitter.txx b/Code/Common/otbImageRegionSquareTileSplitter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..6870b8dd034b2cef25ba00ab21b28721a2aa40bd
--- /dev/null
+++ b/Code/Common/otbImageRegionSquareTileSplitter.txx
@@ -0,0 +1,120 @@
+/*=========================================================================
+
+  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 __otbImageRegionSquareTileSplitter_txx
+#define __otbImageRegionSquareTileSplitter_txx
+
+#include "otbImageRegionSquareTileSplitter.h"
+#include "otbMath.h"
+#include "otbMacro.h"
+
+namespace otb
+{
+
+template <unsigned int VImageDimension>
+unsigned int
+ImageRegionSquareTileSplitter<VImageDimension>
+::GetNumberOfSplits(const RegionType& region, unsigned int requestedNumber)
+{
+  unsigned int theoricalNbPixelPerTile = region.GetNumberOfPixels() / requestedNumber;
+  unsigned int theoricalTileDimension = static_cast<unsigned int> (vcl_sqrt(static_cast<double>(theoricalNbPixelPerTile)) );
+
+  // Take the previous multiple of m_TileSizeAlignment (eventually generate more splits than requested)
+  m_TileDimension = theoricalTileDimension / m_TileSizeAlignment * m_TileSizeAlignment;
+
+  // Minimal tile size is m_TileSizeAlignment * m_TileSizeAlignment
+  if (m_TileDimension < m_TileSizeAlignment)
+    {
+    otbMsgDevMacro(<< "Warning: clamping tile size to " << m_TileSizeAlignment << " * " << m_TileSizeAlignment);
+    m_TileDimension = m_TileSizeAlignment;
+    }
+
+  unsigned int numPieces = 1;
+  const SizeType&  regionSize = region.GetSize();
+  for (unsigned int j = 0; j < VImageDimension; ++j)
+    {
+    m_SplitsPerDimension[j] = (regionSize[j] + m_TileDimension - 1) / m_TileDimension;
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  otbMsgDevMacro(<< "Tile dimension : " << m_TileDimension)
+  otbMsgDevMacro(<< "Number of splits per dimension : " << m_SplitsPerDimension[0] << " " <<  m_SplitsPerDimension[1])
+
+  return numPieces;
+}
+
+template <unsigned int VImageDimension>
+itk::ImageRegion<VImageDimension>
+ImageRegionSquareTileSplitter<VImageDimension>
+::GetSplit(unsigned int i, unsigned int itkNotUsed(numberOfPieces), const RegionType& region)
+{
+  RegionType splitRegion;
+  IndexType  splitIndex;
+
+  // Compute the actual number of splits
+  unsigned int numPieces = 1;
+  for (unsigned int j = 0; j < VImageDimension; ++j)
+    {
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  // Sanity check
+  if (i >= numPieces)
+    {
+    itkExceptionMacro("Asked for split number " << i << " but region contains only " << numPieces << " splits");
+    }
+
+  // Compute the split index in the streaming grid
+  unsigned int remaining = i;
+  for (unsigned int j = VImageDimension - 1; j > 0; --j)
+    {
+    splitIndex[j] = remaining / m_SplitsPerDimension[VImageDimension - 1 - j];
+    remaining = remaining % m_SplitsPerDimension[VImageDimension - 1 - j];
+    }
+  splitIndex[0] = remaining;
+
+  // Transform the split index to the actual coordinates
+  for (unsigned int j = 0; j < VImageDimension; ++j)
+    {
+    splitRegion.SetIndex(j, region.GetIndex(j) + m_TileDimension * splitIndex[j]);
+    splitRegion.SetSize(j, m_TileDimension);
+    }
+
+  // Handle the borders
+  splitRegion.Crop(region);
+
+  return splitRegion;
+}
+
+/**
+ *
+ */
+template <unsigned int VImageDimension>
+void
+ImageRegionSquareTileSplitter<VImageDimension>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "SplitsPerDimension : " << m_SplitsPerDimension << std::endl;
+  os << indent << "TileDimension      : " << m_TileDimension << std::endl;
+  os << indent << "TileSizeAlignment  : " << m_TileSizeAlignment << std::endl;
+
+}
+
+} // end namespace itk
+
+#endif
diff --git a/Code/Common/otbPersistentImageFilter.h b/Code/Common/otbPersistentImageFilter.h
index ccea263130c7e5727c5757df6b5802dc8fc1a4b1..87d78f2202c5f16572dae4d689f5bc005c0e4ce6 100644
--- a/Code/Common/otbPersistentImageFilter.h
+++ b/Code/Common/otbPersistentImageFilter.h
@@ -66,7 +66,7 @@ public:
 
 protected:
   /** Constructor */
-  PersistentImageFilter() {};
+  PersistentImageFilter() {}
   /** Destructor */
   virtual ~PersistentImageFilter() {}
   /**PrintSelf method */
diff --git a/Code/Common/otbPipelineMemoryPrintCalculator.cxx b/Code/Common/otbPipelineMemoryPrintCalculator.cxx
index 397ba8b1126fbb30d860dccc6d5d8967c3cf5e6c..b8dff8c995087bc77f8d936ed71e8a3c18ad58d7 100644
--- a/Code/Common/otbPipelineMemoryPrintCalculator.cxx
+++ b/Code/Common/otbPipelineMemoryPrintCalculator.cxx
@@ -61,7 +61,7 @@ void
 PipelineMemoryPrintCalculator
 ::Compute()
 {
-  // Clear the visisted process objects set
+  // Clear the visited process objects set
   m_VisitedProcessObjects.clear();
 
   // Dry run of pipeline synchronisation
@@ -96,6 +96,7 @@ PipelineMemoryPrintCalculator::MemoryPrintType
 PipelineMemoryPrintCalculator
 ::EvaluateMemoryPrint(ProcessObjectType * process)
 {
+  otbMsgDevMacro(<< "EvaluateMemoryPrint for " << process->GetNameOfClass() << " (" << process << ")")
   // This variable will store the final print
   MemoryPrintType print = 0;
 
@@ -150,6 +151,7 @@ PipelineMemoryPrintCalculator::MemoryPrintType
 PipelineMemoryPrintCalculator
 ::EvaluateDataObjectPrint(DataObjectType * data) const
 {
+  otbMsgDevMacro(<< "EvaluateMemoryPrint for " << data->GetNameOfClass() << " (" << data << ")")
 
 #define OTB_IMAGE_SIZE_BLOCK(type)                                      \
   if(dynamic_cast<itk::Image<type, 2> *>(data) != NULL)                  \
diff --git a/Code/Common/otbStandardFilterWatcher.cxx b/Code/Common/otbStandardFilterWatcher.cxx
index 1fd3e7d4dc90205145af320af5f45e75f5238914..ce47e316a5e22818ab789ac98a6a59c4994f788e 100644
--- a/Code/Common/otbStandardFilterWatcher.cxx
+++ b/Code/Common/otbStandardFilterWatcher.cxx
@@ -29,6 +29,7 @@ StandardFilterWatcher
   : FilterWatcherBase(process, comment)
 {
   m_StarsCount = 50;
+  m_CurrentNbStars = -1;
 }
 
 StandardFilterWatcher
@@ -80,9 +81,14 @@ StandardFilterWatcher
       progressPercent = 100;
       }
 
-    std::string stars(nbStars, '*');
-    std::string blanks(nbBlanks, ' ');
-    std::cout << "\rProcessing progress: " << progressPercent << "% [" << stars << blanks << "]" << std::flush;
+    if (nbStars > m_CurrentNbStars)
+      {
+      std::string stars(nbStars, '*');
+      std::string blanks(nbBlanks, ' ');
+      std::cout << "\rProcessing progress: " << progressPercent << "% [" << stars << blanks << "]" << std::flush;
+      }
+
+    m_CurrentNbStars = nbStars;
     }
 }
 
diff --git a/Code/Common/otbStandardFilterWatcher.h b/Code/Common/otbStandardFilterWatcher.h
index 1f3cbe6e91d41608d74108a307b628b6e6f3198c..5e4fd7f69037855a477e3e2c9b89a0605bf2bc07 100644
--- a/Code/Common/otbStandardFilterWatcher.h
+++ b/Code/Common/otbStandardFilterWatcher.h
@@ -92,6 +92,8 @@ private:
 
   /** Stars coutning */
   int m_StarsCount;
+
+  int m_CurrentNbStars;
 };
 
 } // end namespace otb
diff --git a/Code/Common/otbStreamingManager.h b/Code/Common/otbStreamingManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d5d81b43aca507d7c8b05df9fb7ba93dc099047
--- /dev/null
+++ b/Code/Common/otbStreamingManager.h
@@ -0,0 +1,196 @@
+/*=========================================================================
+
+  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 __otbStreamingManager_h
+#define __otbStreamingManager_h
+
+#include "otbMacro.h"
+#include "otbConfigure.h"
+
+#include "itkLightObject.h"
+#include "itkImageRegionSplitter.h"
+
+namespace otb
+{
+
+namespace StreamingManagement
+{
+  enum StreamingMode
+  {
+    /** Estimates the memory used by the pipeline
+     * and set the strips size to fit the specified
+     * available RAM
+     */
+    STRIPPED_AVAILABLE_RAM,
+
+    /** Force the use of a specific number of lines per strips
+     */
+    STRIPPED_SET_NUMBEROFLINES,
+
+    /** Estimates the memory used that will be used during the pipeline
+     * execution and set the tile size to fit the specified
+     * available RAM.
+     */
+    TILED_AVAILABLE_RAM,
+
+    /** Force the use of a specific tile dimension
+     * The associated parameter is the size used in each dimension
+     */
+    TILED_SET_TILE_SIZE,
+  };
+}
+
+/** \class StreamingManager
+ *  \brief This class handles the streaming process used in the writers implementation
+ *
+ *  The streaming mode can be chosen with either SetStrippedRAMStreamingMode, SetStrippedNumberOfLinesStreamingMode,
+ *  SetTiledRAMStreamingMode, or SetTiledTileDimensionStreamingMode.
+ *
+ *  Then, PrepareStreaming must be called so that the stream type and dimensions are computed
+ *  This involves passing the actual DataObject who will be written, since it will be used
+ *  during memory estimation for some specific streaming modes.
+ *
+ *  After PrepareStreaming has been called, the actual number of splits and streaming mode which will be used
+ *  can be retrieved with GetStreamingMode and GetNumberOfSplits.
+ *  The different splits can be retrieved with GetSplit
+ *
+ * \sa StreamingImageFileWriter
+ * \sa StreamingImageVirtualFileWriter
+ */
+template<class TImage>
+class ITK_EXPORT StreamingManager : public itk::LightObject
+{
+public:
+  /** Standard class typedefs. */
+  typedef StreamingManager               Self;
+  typedef itk::LightObject               Superclass;
+  typedef itk::SmartPointer<Self>        Pointer;
+  typedef itk::SmartPointer<const Self>  ConstPointer;
+
+  typedef TImage                                 ImageType;
+  typedef typename ImageType::Pointer            ImagePointerType;
+  typedef typename ImageType::RegionType         RegionType;
+  typedef typename RegionType::IndexType         IndexType;
+  typedef typename RegionType::SizeType          SizeType;
+  typedef typename ImageType::InternalPixelType  PixelType;
+
+  typedef StreamingManagement::StreamingMode     StreamingModeType;
+
+  /** Creation through object factory macro */
+  itkNewMacro(Self);
+
+  /** Type macro */
+  itkTypeMacro(StreamingManager, itk::LightObject);
+
+  /** Dimension of input image. */
+  itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+
+  /** Use stripped mode.
+   * The number of lines of the strips are computed by estimating the
+   * memory footprint of the pipeline, and chosen so that no more than
+   * availableRAM MBytes of memory are used.
+   * If no parameter is given, then the available RAM is retrieved from the
+   * OTB configuration file or build configuration option */
+  virtual void SetStrippedRAMStreamingMode( unsigned int availableRAMInMB = 0 );
+
+  /** Use stripped mode.
+   * The number of lines of the strips are explicitely specified */
+  virtual void SetStrippedNumberOfLinesStreamingMode( unsigned int numberOfLines );
+
+  /** Use tiled mode.
+   * The dimensions of the tiles are computed by estimating the
+   * memory footprint of the pipeline, and chosen so that no more than
+   * availableRAM MBytes of memory are used.
+   *
+   * If no parameter is given, then the available RAM is retrieved from the
+   * OTB configuration file or build configuration option.
+   *
+   * The tiles are set to be square, with dimension aligned with multiple of 16 */
+  virtual void SetTiledRAMStreamingMode( unsigned int availableRAMInMB = 0 );
+
+  /** Use tiled mode.
+   * The dimension of the tile are explicitely specified.
+   * The parameter specifies the size of the tile in each dimension.  */
+  virtual void SetTiledTileDimensionStreamingMode( unsigned int tileDimension );
+
+  /** Actually computes the stream divisions, accorfing to the specified streaming mode,
+   * eventually using the input parameter to estimate memory consumption */
+  virtual void PrepareStreaming(itk::DataObject * input, const RegionType &region);
+
+  /** Returns the actual streaming mode that will be used to process the image.
+   * PrepareStreaming() must have been called before.
+   * This can be different than the required streaming mode. For example, if
+   * the input passed to PrepareStreaming() is fully buffered, then
+   * the STRIPPED_SET_NUMBEROFLINES mode is used with only one strip */
+  virtual StreamingManagement::StreamingMode GetStreamingMode();
+
+  /** Returns the actual number of pieces that will be used to process the image.
+   * PrepareStreaming() must have been called before.
+   * This can be different than the requested number */
+  virtual unsigned int GetNumberOfSplits();
+
+  /** Get a region definition that represents the ith piece a specified region.
+   * The "numberOfPieces" must be equal to what
+   * GetNumberOfSplits() returns. */
+  virtual RegionType GetSplit(unsigned int i);
+
+
+public:
+  StreamingManager();
+  virtual ~StreamingManager();
+
+  virtual unsigned int EstimateOptimalNumberOfDivisions(itk::DataObject * input, const RegionType &region);
+
+  /** The desired streaming mode specified by the user */
+  StreamingManagement::StreamingMode m_DesiredMode;
+
+  /** The actual streaming mode which will be used */
+  StreamingManagement::StreamingMode m_ActualMode;
+
+  /** The available RAM set as parameter when using the STRIPPED_AVAILABLE_RAM or TILED_AVAILABLE_RAM mode */
+  unsigned int m_AvailableRAMInMB;
+
+  /** The desired number of lines when using the STRIPPED_SET_NUMBEROFLINES streaming mode */
+  unsigned int m_DesiredNumberOfLines;
+
+  /** The desired tile dimension when using the TILED_SET_TILE_SIZE streaming mode */
+  unsigned int m_DesiredTileDimension;
+
+  /** The computed number of splits after PrepareStreaming has been called */
+  unsigned int m_ComputedNumberOfSplits;
+
+  /** The region to stream */
+  RegionType m_Region;
+
+  /** The splitter used to compute the different strips */
+  typedef itk::ImageRegionSplitter<itkGetStaticConstMacro(ImageDimension)> AbstractSplitterType;
+  typedef typename AbstractSplitterType::Pointer AbstractSplitterPointerType;
+  AbstractSplitterPointerType m_Splitter;
+
+private:
+  StreamingManager(const StreamingManager &); //purposely not implemented
+  void operator =(const StreamingManager&); //purposely not implemented
+
+};
+
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbStreamingManager.txx"
+#endif
+
+#endif
diff --git a/Code/Common/otbStreamingManager.txx b/Code/Common/otbStreamingManager.txx
new file mode 100644
index 0000000000000000000000000000000000000000..5816141f677d42ef900cf42331ef8ae89ac12a7a
--- /dev/null
+++ b/Code/Common/otbStreamingManager.txx
@@ -0,0 +1,291 @@
+/*=========================================================================
+
+  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 __otbStreamingManager_txx
+#define __otbStreamingManager_txx
+
+#include "otbStreamingManager.h"
+#include "otbMacro.h"
+#include "otbConfigure.h"
+#include "otbConfigurationFile.h"
+#include "otbPipelineMemoryPrintCalculator.h"
+#include "itkExtractImageFilter.h"
+
+#include "otbImageRegionSquareTileSplitter.h"
+#include "itkImageRegionSplitter.h"
+
+namespace otb
+{
+
+template <class TImage>
+StreamingManager<TImage>::StreamingManager()
+  : m_DesiredMode(StreamingManagement::TILED_AVAILABLE_RAM),
+    m_ActualMode(StreamingManagement::TILED_AVAILABLE_RAM),
+    m_AvailableRAMInMB(0),
+    m_DesiredNumberOfLines(0),
+    m_DesiredTileDimension(0),
+    m_ComputedNumberOfSplits(0)
+{
+}
+
+template <class TImage>
+StreamingManager<TImage>::~StreamingManager()
+{
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetStrippedRAMStreamingMode( unsigned int availableRAMInMB )
+{
+  m_DesiredMode = StreamingManagement::STRIPPED_AVAILABLE_RAM;
+  m_AvailableRAMInMB = availableRAMInMB;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetStrippedNumberOfLinesStreamingMode( unsigned int numberOfLines )
+{
+  m_DesiredMode = StreamingManagement::STRIPPED_SET_NUMBEROFLINES;
+  m_DesiredNumberOfLines = numberOfLines;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetTiledRAMStreamingMode( unsigned int availableRAMInMB )
+{
+  otbMsgDevMacro(<< "StreamingManager::SetTiledRAMStreamingMode " << availableRAMInMB)
+  m_DesiredMode = StreamingManagement::TILED_AVAILABLE_RAM;
+  m_AvailableRAMInMB = availableRAMInMB;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetTiledTileDimensionStreamingMode( unsigned int tileDimension )
+{
+  m_DesiredMode = StreamingManagement::TILED_SET_TILE_SIZE;
+  m_DesiredTileDimension = tileDimension;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::PrepareStreaming( itk::DataObject * input, const RegionType &region )
+{
+  switch (m_DesiredMode)
+  {
+    case StreamingManagement::STRIPPED_AVAILABLE_RAM:
+      {
+      otbMsgDevMacro(<< "Activating STRIPPED_AVAILABLE_RAM streaming mode")
+      unsigned long nbDivisions = EstimateOptimalNumberOfDivisions(input, region);
+      m_Splitter = itk::ImageRegionSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbDivisions);
+
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+
+    case StreamingManagement::STRIPPED_SET_NUMBEROFLINES:
+      {
+      otbMsgDevMacro(<< "Activating STRIPPED_SET_NUMBEROFLINES streaming mode")
+      if (m_DesiredNumberOfLines < 1)
+        {
+        itkWarningMacro(<< "DesiredNumberOfLines set to 0 : use 1 as strip number of lines")
+        m_DesiredNumberOfLines = 1;
+        }
+
+      /* Calculate number of split */
+      unsigned long numberLinesOfRegion = region.GetSize()[1]; // Y dimension
+      unsigned long nbSplit;
+      if (numberLinesOfRegion > m_DesiredNumberOfLines)
+        {
+        nbSplit =
+          static_cast<unsigned long>(vcl_ceil(static_cast<double>(numberLinesOfRegion) /
+                                              static_cast<double>(m_DesiredNumberOfLines)));
+        }
+      else
+        {
+        // Don't stream
+        nbSplit = 1;
+        }
+
+      m_Splitter = itk::ImageRegionSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbSplit);
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+
+    case StreamingManagement::TILED_AVAILABLE_RAM:
+      {
+      otbMsgDevMacro(<< "Activating TILED_AVAILABLE_RAM streaming mode")
+      unsigned long nbDivisions = EstimateOptimalNumberOfDivisions(input, region);
+      m_Splitter = otb::ImageRegionSquareTileSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbDivisions);
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+
+    case StreamingManagement::TILED_SET_TILE_SIZE:
+      {
+      otbMsgDevMacro(<< "Activating TILED_SET_TILE_SIZE streaming mode")
+      if (m_DesiredTileDimension < 16)
+        {
+        itkWarningMacro(<< "DesiredTileDimension inferior to 16 : use 16 as tile dimension")
+        m_DesiredTileDimension = 16;
+        }
+
+      // Calculate number of split
+      m_Splitter = otb::ImageRegionSquareTileSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      unsigned int nbDesiredTiles = itk::Math::Ceil<unsigned int>( double(region.GetNumberOfPixels()) / (m_DesiredTileDimension * m_DesiredTileDimension) );
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbDesiredTiles);
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+  }
+
+  // Save the region to generate the splits later
+  m_Region = region;
+}
+
+
+template <class TImage>
+unsigned int
+StreamingManager<TImage>::EstimateOptimalNumberOfDivisions(itk::DataObject * input, const RegionType &region)
+{
+  otbMsgDevMacro(<< "m_AvailableRAMInMB " << m_AvailableRAMInMB)
+  unsigned int availableRAMInBytes = m_AvailableRAMInMB * 1024 * 1024;
+
+  if (availableRAMInBytes == 0)
+    {
+    otbMsgDevMacro(<< "Retrieving available RAM size from configuration")
+    // Retrieve it from the configuration
+    try
+      {
+      typedef otb::ConfigurationFile ConfigurationType;
+      ConfigurationType::Pointer conf = ConfigurationType::GetInstance();
+
+      availableRAMInBytes = conf->GetParameter<unsigned int>(
+        "OTB_STREAM_MAX_SIZE_BUFFER_FOR_STREAMING");
+      }
+    catch(...)
+      {
+      // We should never have to go here if the configuration file is
+      // correct and found.
+      // In case it is not fallback on the cmake
+      // defined constants.
+      availableRAMInBytes = OTB_STREAM_MAX_SIZE_BUFFER_FOR_STREAMING;
+      }
+    }
+
+  otbMsgDevMacro("RAM used to estimate memory footprint : " << availableRAMInBytes / 1024 / 1024  << " MB")
+
+  otb::PipelineMemoryPrintCalculator::Pointer memoryPrintCalculator;
+  memoryPrintCalculator = otb::PipelineMemoryPrintCalculator::New();
+
+  memoryPrintCalculator->SetAvailableMemory( availableRAMInBytes );
+
+  // Trick to avoid having the resampler compute the whole
+  // deformation field
+  double regionTrickFactor = 1;
+  ImageType* inputImage = dynamic_cast<ImageType*>(input);
+  //inputImage = 0;
+  if (inputImage)
+    {
+
+    typedef itk::ExtractImageFilter<ImageType,ImageType> ExtractFilterType;
+    typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
+    extractFilter->SetInput(inputImage);
+
+    // Define a small region to run the memory footprint estimation,
+    // around the image center, 100 pixels wide in each dimension
+    SizeType smallSize;
+    smallSize.Fill(100);
+    IndexType index;
+    index[0] = region.GetIndex()[0] + region.GetSize()[0]/2 - 50;
+    index[1] = region.GetIndex()[1] + region.GetSize()[1]/2 - 50;
+
+    RegionType smallRegion;
+    smallRegion.SetSize(smallSize);
+    smallRegion.SetIndex(index);
+
+    // In case the image is smaller than 100 pixels in a direction
+    smallRegion.Crop(region);
+
+    extractFilter->SetExtractionRegion(smallRegion);
+
+    bool smallRegionSuccess = smallRegion.Crop(region);
+
+    if (smallRegionSuccess)
+      {
+      otbMsgDevMacro("Using an extract to estimate memory : " << smallRegion)
+      // the region is well behaved, inside the largest possible region
+      memoryPrintCalculator->SetDataToWrite(extractFilter->GetOutput());
+      regionTrickFactor = static_cast<double>( region.GetNumberOfPixels() )
+          / static_cast<double>(smallRegion.GetNumberOfPixels());
+
+      memoryPrintCalculator->SetBiasCorrectionFactor(regionTrickFactor);
+      }
+    else
+      {
+      otbMsgDevMacro("Using the input region to estimate memory : " << region)
+      // the region is not well behaved
+      // use the full region
+      memoryPrintCalculator->SetDataToWrite(input);
+      memoryPrintCalculator->SetBiasCorrectionFactor(1.0);
+      }
+
+    memoryPrintCalculator->Compute();
+    }
+  else
+    {
+    // Use the original object to estimate memory footprint
+    memoryPrintCalculator->SetDataToWrite(input);
+    memoryPrintCalculator->SetBiasCorrectionFactor(1.0);
+
+    memoryPrintCalculator->Compute();
+    }
+
+  otbMsgDevMacro( "Estimated Memory print for the full image : "
+                   << static_cast<unsigned int>(memoryPrintCalculator->GetMemoryPrint() / 1024 / 1024 ) << std::endl)
+  otbMsgDevMacro( "Optimal number of stream divisions: "
+                   << memoryPrintCalculator->GetOptimalNumberOfStreamDivisions() << std::endl)
+
+  return memoryPrintCalculator->GetOptimalNumberOfStreamDivisions();
+}
+
+template <class TImage>
+StreamingManagement::StreamingMode
+StreamingManager<TImage>::GetStreamingMode()
+{
+  return m_ActualMode;
+}
+
+template <class TImage>
+unsigned int
+StreamingManager<TImage>::GetNumberOfSplits()
+{
+  return m_ComputedNumberOfSplits;
+}
+
+template <class TImage>
+typename StreamingManager<TImage>::RegionType
+StreamingManager<TImage>::GetSplit(unsigned int i)
+{
+  return m_Splitter->GetSplit(i, m_ComputedNumberOfSplits, m_Region);
+}
+
+} // End namespace otb
+
+#endif
diff --git a/Code/Gui/otbFltkFilterWatcher.cxx b/Code/Gui/otbFltkFilterWatcher.cxx
index 65ef6e5452a735dac780f2733e76410593149bf7..8136428c449e14a816a93b49b6cf025d22edb686 100644
--- a/Code/Gui/otbFltkFilterWatcher.cxx
+++ b/Code/Gui/otbFltkFilterWatcher.cxx
@@ -27,7 +27,8 @@ FltkFilterWatcher
 ::FltkFilterWatcher(itk::ProcessObject* process,
                     int x, int y, int w, int h,
                     const char *comment)
-  : FilterWatcherBase(process, comment)
+  : FilterWatcherBase(process, comment),
+    m_CurrentProgress(0)
 {
   m_Window = new Fl_Window(x, y, w + 10, h + 10);
   m_Window->label(m_Comment.c_str());
@@ -46,4 +47,39 @@ FltkFilterWatcher
   delete m_Window;
 }
 
+void
+FltkFilterWatcher
+::StartFilter()
+{
+  m_Window->show();
+  m_Progress->value(0);
+  m_Progress->show();
+  Fl::check();
+}
+
+void
+FltkFilterWatcher
+::ShowProgress()
+{
+  if (m_Process)
+    {
+    double progress = m_Process->GetProgress();
+
+    // Update only at each 0.5 percent
+    if (progress - m_CurrentProgress > 0.005)
+      {
+      m_Progress->value(progress);
+      m_CurrentProgress = progress;
+      Fl::check();
+      }
+    }
+}
+
+void
+FltkFilterWatcher
+::EndFilter()
+{
+  m_Window->hide();
+}
+
 } // end namespace otb
diff --git a/Code/Gui/otbFltkFilterWatcher.h b/Code/Gui/otbFltkFilterWatcher.h
index f15a47bcf437d41aaf4bc240c279e1c384010451..c8bc02ce51516d685557265c15eee4f8f847fc77 100644
--- a/Code/Gui/otbFltkFilterWatcher.h
+++ b/Code/Gui/otbFltkFilterWatcher.h
@@ -38,9 +38,6 @@ namespace otb
 class ITK_EXPORT FltkFilterWatcher : public FilterWatcherBase
 {
 public:
-  /** Classes that need access to filter's private data */
-  // friend class XMLFilterWatcher;
-
   /** Constructor. Takes a ProcessObject to monitor and an optional
    * comment string that is prepended to each event message. */
   FltkFilterWatcher(itk::ProcessObject * process,
@@ -50,35 +47,21 @@ public:
   /** Destructor. */
   virtual ~FltkFilterWatcher();
 
-  /** Callback method to show the EndEvent */
-  virtual void EndFilter()
-  {
-    m_Window->hide();
-  }
-
 protected:
-
   /** Callback method to show the ProgressEvent */
-  virtual void ShowProgress()
-  {
-    if (m_Process)
-      {
-      m_Progress->value(m_Process->GetProgress());
-      Fl::check();
-      }
-  }
+  virtual void ShowProgress();
 
   /** Callback method to show the StartEvent */
-  virtual void StartFilter()
-  {
-    m_Window->show();
-    m_Progress->show();
-  }
+  virtual void StartFilter();
 
-private:
+  /** Callback method to show the EndEvent */
+  virtual void EndFilter();
 
+private:
   Fl_Window *   m_Window;
   Fl_Progress * m_Progress;
+
+  double m_CurrentProgress;
 };
 
 } // end namespace otb
diff --git a/Code/Gui/otbFltkWriterWatcher.cxx b/Code/Gui/otbFltkWriterWatcher.cxx
index a3779c4ba24d427f5a20683485808ebaf9d2de2f..b99700274ff272789ca907bca81041a67e105b1f 100644
--- a/Code/Gui/otbFltkWriterWatcher.cxx
+++ b/Code/Gui/otbFltkWriterWatcher.cxx
@@ -27,7 +27,9 @@ FltkWriterWatcher
 ::FltkWriterWatcher(itk::ProcessObject* process,
                     int x, int y, int w, int h,
                     const char *comment)
-  : WriterWatcherBase(process, comment)
+  : WriterWatcherBase(process, comment),
+    m_CurrentFilterProgress(0),
+    m_CurrentWriterProgress(0)
 {
   this->BuildGUI(x, y, w, h, comment);
 }
@@ -37,7 +39,9 @@ FltkWriterWatcher
                     itk::ProcessObject* source,
                     int x, int y, int w, int h,
                     const char *comment)
-  : WriterWatcherBase(process, source, comment)
+  : WriterWatcherBase(process, source, comment),
+    m_CurrentFilterProgress(0),
+    m_CurrentWriterProgress(0)
 {
   this->BuildGUI(x, y, w, h, comment);
 }
@@ -78,4 +82,74 @@ FltkWriterWatcher
   delete m_Window;
 }
 
+
+void
+FltkWriterWatcher
+::StartFilter()
+{
+  m_Window->show();
+  m_FilterProgress->show();
+  m_WriterProgress->show();
+  Fl::check();
+}
+
+void
+FltkWriterWatcher
+::ShowFilterProgress()
+{
+  if (m_SourceProcess)
+    {
+    double progress = m_SourceProcess->GetProgress();
+
+    // Update only at each 0.5 percent
+    if (progress - m_CurrentFilterProgress > 0.005)
+      {
+      m_FilterProgress->value(progress);
+      m_CurrentFilterProgress = progress;
+      Fl::check();
+      }
+    }
+}
+
+void
+FltkWriterWatcher
+::EndFilter()
+{
+}
+
+void
+FltkWriterWatcher
+::StartWriter()
+{
+  m_Window->show();
+  m_FilterProgress->show();
+  m_WriterProgress->show();
+  Fl::check();
+}
+
+void
+FltkWriterWatcher
+::ShowWriterProgress()
+{
+  if (m_Process)
+    {
+    double progress = m_Process->GetProgress();
+
+    // Update only at each 0.5 percent
+    if (progress - m_CurrentWriterProgress > 0.005)
+      {
+      m_WriterProgress->value(progress);
+      m_CurrentWriterProgress = progress;
+      Fl::check();
+      }
+    }
+}
+
+void
+FltkWriterWatcher
+::EndWriter()
+{
+  m_Window->hide();
+}
+
 } // end namespace otb
diff --git a/Code/Gui/otbFltkWriterWatcher.h b/Code/Gui/otbFltkWriterWatcher.h
index e03ecd03f0586060f5618936177461f1535c1814..224d69a6ea55db32fa13f022e5e5fc720ad8c1e1 100644
--- a/Code/Gui/otbFltkWriterWatcher.h
+++ b/Code/Gui/otbFltkWriterWatcher.h
@@ -55,54 +55,25 @@ public:
   /** Destructor. */
   virtual ~FltkWriterWatcher();
 
-  /** Callback method to show the EndEvent */
-  virtual void EndWriter()
-  {
-    m_Window->hide();
-  }
+protected:
 
-  virtual void EndFilter()
-  {}
+  /** Callback method to show the ProgressEvent from the writer */
+  virtual void ShowWriterProgress();
 
-protected:
+  /** Callback method to show the StartEvent from the writer*/
+  virtual void StartWriter();
+
+  /** Callback method to show the EndEvent from the writer*/
+  virtual void EndWriter();
 
-  /** Callback method to show the ProgressEvent */
-  virtual void ShowFilterProgress()
-  {
-    if (m_SourceProcess)
-      {
-      m_FilterProgress->value(m_SourceProcess->GetProgress());
-      Fl::check();
-      }
-  }
-
-  /** Callback method to show the ProgressEvent */
-  virtual void ShowWriterProgress()
-  {
-    if (m_Process)
-      {
-      m_WriterProgress->value(m_Process->GetProgress());
-      Fl::check();
-      }
-  }
-
-  /** Callback method to show the StartEvent */
-  virtual void StartWriter()
-  {
-    m_Window->show();
-    m_FilterProgress->show();
-    m_WriterProgress->show();
-    Fl::check();
-  }
-
-  /** Callback method to show the StartEvent */
-  virtual void StartFilter()
-  {
-    m_Window->show();
-    m_FilterProgress->show();
-    m_WriterProgress->show();
-    Fl::check();
-  }
+  /** Callback method to show the ProgressEvent from the filter */
+  virtual void ShowFilterProgress();
+
+  /** Callback method to show the StartEvent from the filter*/
+  virtual void StartFilter();
+
+  /** Callback method to show the EndEvent from the filter*/
+  virtual void EndFilter();
 
   void BuildGUI(int x, int y, int w, int h, const char * comment);
 
@@ -111,6 +82,9 @@ private:
   Fl_Window *   m_Window;
   Fl_Progress * m_WriterProgress;
   Fl_Progress * m_FilterProgress;
+
+  double m_CurrentFilterProgress;
+  double m_CurrentWriterProgress;
 };
 
 } // end namespace otb
diff --git a/Code/IO/otbMapFileProductWriter.txx b/Code/IO/otbMapFileProductWriter.txx
index 1463bb05def7feb40c1bb7f8079eb38dcff4f9b0..f74f55fff44dc25647c890a3cf25f03b7468a24e 100644
--- a/Code/IO/otbMapFileProductWriter.txx
+++ b/Code/IO/otbMapFileProductWriter.txx
@@ -237,6 +237,7 @@ MapFileProductWriter<TInputImage>
 
       m_StreamingShrinkImageFilter->SetShrinkFactor(sampleRatioValue);
       m_StreamingShrinkImageFilter->SetInput(m_VectorImage);
+      m_StreamingShrinkImageFilter->Update();
 
       m_VectorRescaleIntensityImageFilter = VectorRescaleIntensityImageFilterType::New();
       m_VectorRescaleIntensityImageFilter->SetInput(m_StreamingShrinkImageFilter->GetOutput());
diff --git a/Code/IO/otbStreamingImageVirtualWriter.h b/Code/IO/otbStreamingImageVirtualWriter.h
index 9ae59e84295c01dce381482e85a1852d6378d888..99e72c1c06736795f2aedfb9f58b02bfa16a7e82 100644
--- a/Code/IO/otbStreamingImageVirtualWriter.h
+++ b/Code/IO/otbStreamingImageVirtualWriter.h
@@ -20,8 +20,7 @@
 
 #include "itkMacro.h"
 #include "itkImageToImageFilter.h"
-#include "itkImageRegionSplitter.h"
-#include "otbStreamingTraits.h"
+#include "otbStreamingManager.h"
 
 namespace otb
 {
@@ -45,7 +44,7 @@ namespace otb
  * \sa PersistentStatisticsImageFilter
  * \sa PersistentImageStreamingDecorator.
  */
-template <class TInputImage>
+template <class TInputImage, class TStreamingManager = StreamingManager<TInputImage> >
 class ITK_EXPORT StreamingImageVirtualWriter : public itk::ImageToImageFilter<TInputImage, TInputImage>
 {
 public:
@@ -68,86 +67,62 @@ public:
   typedef typename InputImageType::PixelType  InputImagePixelType;
 
   /** Streaming traits helper typedef */
-  typedef StreamingTraits<InputImageType> StreamingTraitsType;
+  typedef TStreamingManager                      StreamingManagerType;
+  typedef typename StreamingManagerType::Pointer StreamingManagerPointerType;
 
   /** Dimension of input image. */
   itkStaticConstMacro(InputImageDimension, unsigned int,
                       InputImageType::ImageDimension);
 
-  /** Set/Get the image input of this writer.  */
-  void SetInput(const InputImageType *input);
-  const InputImageType * GetInput(void);
-  const InputImageType * GetInput(unsigned int idx);
+  StreamingManagerType* GetStreamingManager(void)
+    {
+    return m_StreamingManager;
+    }
 
-  void SetNthInput(unsigned int idx, const InputImageType *input);
-
-
-  /** SmartPointer to a region splitting object */
-  typedef itk::ImageRegionSplitter<itkGetStaticConstMacro(InputImageDimension)> SplitterType;
-  typedef typename SplitterType::Pointer                                        RegionSplitterPointer;
-
-  /**  Set buffer memory size (in bytes) use to calculate the number of stream divisions */
-  void SetBufferMemorySize(unsigned long);
-
-  /**  Set the buffer number of lines use to calculate the number of stream divisions */
-  void SetBufferNumberOfLinesDivisions(unsigned long);
-
-  /**  The number of stream divisions is calculate by using
-   * OTB_STREAM_IMAGE_SIZE_TO_ACTIVATE_STREAMING and
-   * OTB_STREAM_MAX_SIZE_BUFFER_FOR_STREAMING cmake variables.
-   */
-  void SetAutomaticNumberOfStreamDivisions(void);
-
-  /** Set the tiling automatic mode for streaming division */
-  void SetTilingStreamDivisions(void);
-  /** Choose number of divisions in tiling streaming division */
-  void SetTilingStreamDivisions(unsigned long);
-
-  /** Return the string to indicate the method use to calculate number of stream divisions. */
-  std::string GetMethodUseToCalculateNumberOfStreamDivisions(void);
-
-  /** Set the number of pieces to divide the input.  The upstream pipeline
-   * will be executed this many times. */
-  void SetNumberOfStreamDivisions(unsigned long);
-
-  /** Get the number of pieces to divide the input. The upstream pipeline
-   * will be executed this many times. */
-  unsigned long GetNumberOfStreamDivisions(void);
-
-  /** Set the helper class for dividing the input into chunks. */
-  itkSetObjectMacro(RegionSplitter, SplitterType);
-
-  /** Get the helper class for dividing the input into chunks. */
-  itkGetObjectMacro(RegionSplitter, SplitterType);
-
-  /** Type use to define number of divisions */
-  typedef StreamingMode CalculationDivisionEnumType;
-
-  virtual void GenerateInputRequestedRegion(void);
+  void SetStreamingManager(StreamingManagerType* streamingManager)
+    {
+    m_StreamingManager = streamingManager;
+    }
 
 protected:
   StreamingImageVirtualWriter();
+
   virtual ~StreamingImageVirtualWriter();
+
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
   virtual void GenerateData(void);
 
+  virtual void GenerateInputRequestedRegion(void);
+
 private:
   StreamingImageVirtualWriter(const StreamingImageVirtualWriter &); //purposely not implemented
   void operator =(const StreamingImageVirtualWriter&); //purposely not implemented
 
-  /** This method calculate the number of stream divisions, by using the CalculationDivision type */
-  unsigned long CalculateNumberOfStreamDivisions(void);
+  void ObserveSourceFilterProgress(itk::Object* object, const itk::EventObject & event )
+  {
+    if (typeid(event) != typeid(itk::ProgressEvent))
+      {
+      return;
+      }
+
+    itk::ProcessObject* processObject = dynamic_cast<itk::ProcessObject*>(object);
+    if (processObject)
+      m_DivisionProgress = processObject->GetProgress();
+
+    this->UpdateFilterProgress();
+  }
 
-  /** Use to define the method used to calculate number of divisions */
-  unsigned long m_BufferMemorySize;
-  unsigned long m_BufferNumberOfLinesDivisions;
-  unsigned long m_NumberOfStreamDivisions;
+  void UpdateFilterProgress()
+  {
+    this->UpdateProgress( (m_DivisionProgress + m_CurrentDivision) / m_NumberOfDivisions );
+  }
 
-  RegionSplitterPointer m_RegionSplitter;
+  unsigned int m_NumberOfDivisions;
+  unsigned int m_CurrentDivision;
+  float m_DivisionProgress;
 
-  /** Use to determine method of calculation number of divisions */
-  CalculationDivisionEnumType m_CalculationDivision;
+  StreamingManagerPointerType m_StreamingManager;
 };
 
 } // end namespace otb
diff --git a/Code/IO/otbStreamingImageVirtualWriter.txx b/Code/IO/otbStreamingImageVirtualWriter.txx
index ce0b5938974e80d17265524e360b278f9aa013df..6ffd8621b5b05c4adf5c3439fb772b80694dcdd6 100644
--- a/Code/IO/otbStreamingImageVirtualWriter.txx
+++ b/Code/IO/otbStreamingImageVirtualWriter.txx
@@ -19,231 +19,55 @@
 #define __otbStreamingImageVirtualWriter_txx
 #include "otbStreamingImageVirtualWriter.h"
 
-#include "itkCommand.h"
-#include "itkImageRegionIterator.h"
-#include "itkObjectFactoryBase.h"
-#include "itkImageFileWriter.h"
-#include "itkImageRegionMultidimensionalSplitter.h"
-
 #include "otbMacro.h"
 #include "otbConfigure.h"
+#include "itkCommand.h"
 
 namespace otb
 {
-/**
- *
- */
-template <class TInputImage>
-StreamingImageVirtualWriter<TInputImage>
+
+template <class TInputImage, class TStreamingManager>
+StreamingImageVirtualWriter<TInputImage,TStreamingManager>
 ::StreamingImageVirtualWriter()
 {
-  m_BufferMemorySize = 0;
-  m_BufferNumberOfLinesDivisions = 0;
-  // default to 10 divisions
-  m_NumberOfStreamDivisions = 0;
-  // default to AUTOMATIC_NUMBER_OF_DIVISIONS
-  m_CalculationDivision = SET_AUTOMATIC_NUMBER_OF_STREAM_DIVISIONS;
-
-  // create default region splitter
-  m_RegionSplitter = itk::ImageRegionSplitter<InputImageDimension>::New();
+  m_StreamingManager = StreamingManagerType::New();
 }
 
-/**
- *
- */
-template <class TInputImage>
-StreamingImageVirtualWriter<TInputImage>
+template <class TInputImage, class TStreamingManager>
+StreamingImageVirtualWriter<TInputImage,TStreamingManager>
 ::~StreamingImageVirtualWriter()
 {
 }
 
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetBufferMemorySize(unsigned long memory_size_divisions)
-{
-  m_BufferMemorySize = memory_size_divisions;
-  m_CalculationDivision = SET_BUFFER_MEMORY_SIZE;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetBufferNumberOfLinesDivisions(unsigned long nb_lines_divisions)
-{
-  m_BufferNumberOfLinesDivisions = nb_lines_divisions;
-  m_CalculationDivision = SET_BUFFER_NUMBER_OF_LINES;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetNumberOfStreamDivisions(unsigned long nb_divisions)
-{
-  m_NumberOfStreamDivisions = nb_divisions;
-  m_CalculationDivision = SET_NUMBER_OF_STREAM_DIVISIONS;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetAutomaticNumberOfStreamDivisions(void)
-{
-  m_CalculationDivision = SET_AUTOMATIC_NUMBER_OF_STREAM_DIVISIONS;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
+template <class TInputImage, class TStreamingManager>
 void
-StreamingImageVirtualWriter<TInputImage>
-::SetTilingStreamDivisions(void)
-{
-  m_CalculationDivision = SET_TILING_WITH_SET_AUTOMATIC_NUMBER_OF_STREAM_DIVISIONS;
-  m_RegionSplitter = itk::ImageRegionMultidimensionalSplitter<InputImageDimension>::New();
-  this->Modified();
-}
-
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetTilingStreamDivisions(unsigned long nb_divisions)
-{
-  m_CalculationDivision = SET_TILING_WITH_SET_NUMBER_OF_STREAM_DIVISIONS;
-  m_NumberOfStreamDivisions = nb_divisions;
-  m_RegionSplitter = itk::ImageRegionMultidimensionalSplitter<InputImageDimension>::New();
-  this->Modified();
-}
-
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetInput(const InputImageType *input)
-{
-  this->SetNthInput(0, input);
-}
-
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetNthInput(unsigned int idx, const InputImageType *input)
-{
-  // ProcessObject is not const_correct so this cast is required here.
-  this->itk::ProcessObject::SetNthInput(idx,
-                                        const_cast<TInputImage *>(input));
-}
-
-template <class TInputImage>
-const typename StreamingImageVirtualWriter<TInputImage>::InputImageType *
-StreamingImageVirtualWriter<TInputImage>
-::GetInput(void)
-{
-  if (this->GetNumberOfInputs() < 1)
-    {
-    return 0;
-    }
-
-  return static_cast<TInputImage*>
-           (this->itk::ProcessObject::GetInput(0));
-}
-
-template <class TInputImage>
-const typename StreamingImageVirtualWriter<TInputImage>::InputImageType *
-StreamingImageVirtualWriter<TInputImage>
-::GetInput(unsigned int idx)
+StreamingImageVirtualWriter<TInputImage,TStreamingManager>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
 {
-  return static_cast<TInputImage*> (this->itk::ProcessObject::GetInput(idx));
+  Superclass::PrintSelf(os, indent);
 }
 
-template <class TInputImage>
+template <class TInputImage, class TStreamingManager>
 void
-StreamingImageVirtualWriter<TInputImage>
+StreamingImageVirtualWriter<TInputImage,TStreamingManager>
 ::GenerateInputRequestedRegion(void)
 {
   InputImagePointer                        inputPtr = const_cast<InputImageType *>(this->GetInput(0));
+
+  InputImageRegionType                     region;
   typename InputImageRegionType::SizeType  size;
   typename InputImageRegionType::IndexType index;
-  InputImageRegionType                     region;
+
   index.Fill(0);
   size.Fill(0);
   region.SetSize(size);
   region.SetIndex(index);
   inputPtr->SetRequestedRegion(region);
 }
-/**
- *
- */
-template <class TInputImage>
-unsigned long
-StreamingImageVirtualWriter<TInputImage>
-::GetNumberOfStreamDivisions(void)
-{
-  return (CalculateNumberOfStreamDivisions());
-}
-template<class TInputImage>
-unsigned long
-StreamingImageVirtualWriter<TInputImage>
-::CalculateNumberOfStreamDivisions(void)
-{
-  return StreamingTraitsType
-         ::CalculateNumberOfStreamDivisions(this->GetInput(),
-                                            this->GetInput()->GetLargestPossibleRegion(),
-                                            m_RegionSplitter,
-                                            m_CalculationDivision,
-                                            m_NumberOfStreamDivisions,
-                                            m_BufferMemorySize,
-                                            m_BufferNumberOfLinesDivisions);
-}
-/**
- *
- */
-template <class TInputImage>
-std::string
-StreamingImageVirtualWriter<TInputImage>
-::GetMethodUseToCalculateNumberOfStreamDivisions(void)
-{
-  return (StreamingTraitsType::GetMethodUseToCalculateNumberOfStreamDivisions(m_CalculationDivision));
-}
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-  os << indent << "Number of stream divisions: " << m_NumberOfStreamDivisions
-     << std::endl;
-  if (m_RegionSplitter)
-    {
-    os << indent << "Region splitter:" << m_RegionSplitter << std::endl;
-    }
-  else
-    {
-    os << indent << "Region splitter: (none)" << std::endl;
-    }
-}
-template<class TInputImage>
+
+template<class TInputImage, class TStreamingManager>
 void
-StreamingImageVirtualWriter<TInputImage>
+StreamingImageVirtualWriter<TInputImage,TStreamingManager>
 ::GenerateData(void)
 {
   /**
@@ -257,6 +81,7 @@ StreamingImageVirtualWriter<TInputImage>
    * Tell all Observers that the filter is starting
    */
   this->InvokeEvent(itk::StartEvent());
+
   /**
    * Grab the input
    */
@@ -267,25 +92,47 @@ StreamingImageVirtualWriter<TInputImage>
    * minimum of what the user specified via SetNumberOfStreamDivisions()
    * and what the Splitter thinks is a reasonable value.
    */
-  unsigned int numDivisions;
-  numDivisions = static_cast<unsigned int>(CalculateNumberOfStreamDivisions());
+  m_StreamingManager->PrepareStreaming(inputPtr, outputRegion);
+  m_NumberOfDivisions = m_StreamingManager->GetNumberOfSplits();
+
+  /**
+   * Register to the ProgressEvent of the source filter
+   */
+  // Get the source process object
+  itk::ProcessObject* source = inputPtr->GetSource();
+
+  // Check if source exists
+  if(source)
+    {
+    typedef itk::MemberCommand<Self> CommandType;
+    typedef typename CommandType::Pointer CommandPointerType;
+
+    CommandPointerType command = CommandType::New();
+    command->SetCallbackFunction(this, &Self::ObserveSourceFilterProgress);
+
+    source->AddObserver(itk::ProgressEvent(), command);
+    }
+  else
+    {
+    itkWarningMacro(<< "Could not get the source process object. Progress report might be buggy");
+    }
 
   /**
    * Loop over the number of pieces, execute the upstream pipeline on each
    * piece, and copy the results into the output image.
    */
   InputImageRegionType streamRegion;
-  unsigned int         piece;
-  for (piece = 0;
-       piece < numDivisions && !this->GetAbortGenerateData();
-       piece++)
+  for (m_CurrentDivision = 0;
+       m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateData();
+       m_CurrentDivision++, m_DivisionProgress = 0, this->UpdateFilterProgress())
     {
-    streamRegion = m_RegionSplitter->GetSplit(piece, numDivisions, outputRegion);
+    streamRegion = m_StreamingManager->GetSplit(m_CurrentDivision);
+    otbMsgDevMacro(<< "Processing region : " << streamRegion )
     inputPtr->ReleaseData();
     inputPtr->SetRequestedRegion(streamRegion);
     inputPtr->Update();
-    this->UpdateProgress((float) piece / numDivisions);
     }
+
   /**
    * If we ended due to aborting, push the progress up to 1.0 (since
    * it probably didn't end there)
@@ -308,11 +155,14 @@ StreamingImageVirtualWriter<TInputImage>
       this->GetOutput(idx)->DataHasBeenGenerated();
       }
     }
+
   /**
    * Release any inputs if marked for release
    */
   this->ReleaseInputs();
 }
+
+
 } // end namespace otb
 
 #endif
diff --git a/Code/Projections/otbUtmMapProjection.h b/Code/Projections/otbUtmMapProjection.h
index f30ba4e544d5556335f0d9dd1a83dba8b073404c..b031c63ba05f9d1af083d8a87db9774d4dd34a51 100644
--- a/Code/Projections/otbUtmMapProjection.h
+++ b/Code/Projections/otbUtmMapProjection.h
@@ -53,7 +53,7 @@ public:
   virtual void SetZone(long zone);
   virtual void SetHemisphere(char hemisphere);
   virtual int GetZone() const;
-  virtual const char GetHemisphere() const;
+  virtual char GetHemisphere() const;
 
   virtual void SetZoneAndHemisphereFromGeoPoint(const InputPointType& geoPoint);
   virtual int GetZoneFromGeoPoint(const InputPointType& geoPoint) const;
diff --git a/Code/Projections/otbUtmMapProjection.txx b/Code/Projections/otbUtmMapProjection.txx
index 6d1ffd46ea162ca99625b078f2b89c2b653aba1b..450e166099ed39206dfaeda9483066bc5a1e91db 100644
--- a/Code/Projections/otbUtmMapProjection.txx
+++ b/Code/Projections/otbUtmMapProjection.txx
@@ -68,7 +68,7 @@ int UtmMapProjection<TTransform>
 
 ///\return the hemisphere
 template <TransformDirection::TransformationDirection TTransform>
-const char UtmMapProjection<TTransform>
+char UtmMapProjection<TTransform>
 ::GetHemisphere() const
 {
   char hemisphere = this->m_MapProjection->getHemisphere();
diff --git a/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx b/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx
index 60c2881d52cccbf547e65e3942088de115aacdb8..483d6afb84f6a5749726343a7fdcb0da0601e64f 100644
--- a/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx
+++ b/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx
@@ -28,9 +28,6 @@
 
 int otbMatrixImageFilterNew(int argc, char * argv[])
 {
-  const char * inputFilename  = argv[1];
-  const char * outputFilename = argv[2];
-
   typedef std::complex<double> PixelType;
 
   typedef otb::VectorImage<PixelType> ImageType;
diff --git a/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx b/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx
index beebc71c1231462c0535364c697f48eab7e090c4..2d9a433f506d4827fd86b45a3c46b07c64c976b8 100644
--- a/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx
@@ -50,7 +50,7 @@ int otbMatrixTransposeMatrixImageFilter(int argc, char * argv[])
   reader2->SetFileName(infname2);
 
   // filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  //filter->GetStreamer()->SetNumberOfStreamDivisions(200);
   filter->SetFirstInput(reader1->GetOutput());
   filter->SetSecondInput(reader2->GetOutput());
   filter->SetUsePadFirstInput(true);
diff --git a/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx
index 2987a0f63604e0d6c49050e4f7a50c7fef9babd6..bf4c392613c74d4c7786a4d823b0391e0c797bf2 100644
--- a/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx
@@ -40,7 +40,7 @@ int otbStreamingInnerProductVectorImageFilter(int argc, char* argv[])
   // Instantiation object
   FilterType::Pointer filter = FilterType::New();
 
-  filter->GetStreamer()->SetNumberOfStreamDivisions(10);
+  //filter->GetStreamer()->SetNumberOfStreamDivisions(10);
   filter->SetCenterData(centerdata);
   filter->SetInput(reader->GetOutput());
   filter->Update();
diff --git a/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx
index 0a4493c8306a063c2fb731fcc211a1684372a1a9..5f59b2d7f794a45b011c71968eb507af71c54355 100644
--- a/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx
@@ -43,7 +43,7 @@ int otbStreamingMinMaxImageFilter(int argc, char * argv[])
   reader->SetFileName(infname);
 
   //filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  //filter->GetStreamer()->SetNumberOfStreamDivisions(200);
   filter->SetInput(reader->GetOutput());
   otb::StandardFilterWatcher watcher(filter, "Min Max Computation");
   filter->Update();
diff --git a/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx
index 778df22c3a34f2eddc7ae02ed10113fb4bdd8985..f8f2e265fec84ee19cb7547e1ee2e4f52ca303a4 100644
--- a/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx
@@ -43,7 +43,7 @@ int otbStreamingMinMaxVectorImageFilter(int argc, char * argv[])
   reader->SetFileName(infname);
 
   //filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  //filter->GetStreamer()->SetNumberOfStreamDivisions(200);
   filter->SetInput(reader->GetOutput());
   otb::StandardFilterWatcher watcher(filter, "Min Max Computation");
   filter->Update();
diff --git a/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx
index adb2fc6c71399e1afc7f9dd2c4d40aa702d292a5..22fae71fb8c86d644fc9d2c273cfb4b75d8fcacb 100644
--- a/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx
@@ -43,7 +43,7 @@ int otbStreamingStatisticsImageFilter(int argc, char * argv[])
   reader->SetFileName(infname);
 
   //filter->GetStreamer()->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  //filter->GetStreamer()->SetNumberOfStreamDivisions(200);
   filter->SetInput(reader->GetOutput());
   filter->Update();
 
diff --git a/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx
index e0c312c80be531fb50907cce675f0ec7d0bbd90a..8316823fb3a819eeac2e09edf5de9099875fd64f 100644
--- a/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx
@@ -42,7 +42,7 @@ int otbStreamingStatisticsVectorImageFilter(int argc, char * argv[])
   reader->SetFileName(infname);
 
   //filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  //filter->GetStreamer()->SetNumberOfStreamDivisions(200);
   filter->SetInput(reader->GetOutput());
   filter->Update();
 
diff --git a/Testing/Code/Common/CMakeLists.txt b/Testing/Code/Common/CMakeLists.txt
index a598f4ed523f02bf5972055c2e6eaaef5588f577..ef1cf514ef8833f72f36486c0297351017271db5 100644
--- a/Testing/Code/Common/CMakeLists.txt
+++ b/Testing/Code/Common/CMakeLists.txt
@@ -736,6 +736,19 @@ ADD_TEST(coTvImageRegionTileMapSplitter ${COMMON_TESTS8}
         ${TEMP}/coImageRegionTileMapSplitter.txt
 )
 
+# -------------  otb::ImageRegionSquareTileSplitter ----------------------------
+ADD_TEST(coTuImageRegionSquareTileSplitterNew ${COMMON_TESTS8}
+         otbImageRegionSquareTileSplitterNew
+)
+
+ADD_TEST(coTvImageRegionSquareTileSplitter ${COMMON_TESTS8}
+    --compare-ascii ${NOTOL}
+        ${BASELINE_FILES}/coImageRegionSquareTileSplitter.txt
+        ${TEMP}/coImageRegionSquareTileSplitter.txt
+    otbImageRegionSquareTileSplitter
+        ${TEMP}/coImageRegionSquareTileSplitter.txt
+)
+
 # -------------  otb::ImageOfVectorsToMonoChannelExtractROI ----------------------------
 ADD_TEST(coTuImageOfVectorsToMonoChannelExtractROINew ${COMMON_TESTS8}
 otbImageOfVectorsToMonoChannelExtractROINew
@@ -1103,6 +1116,7 @@ otbQuickLookImageGeneratorNew.cxx
 otbQuickLookImageGenerator.cxx
 otbImageRegionTileMapSplitterNew.cxx
 otbImageRegionTileMapSplitter.cxx
+otbImageRegionSquareTileSplitter.cxx
 otbImageOfVectorsToMonoChannelExtractROINew.cxx
 otbImageOfVectorsToMonoChannelExtractROI.cxx
 otbImageRegionNonUniformMultidimensionalSplitterNew.cxx
diff --git a/Testing/Code/Common/otbCommonTests8.cxx b/Testing/Code/Common/otbCommonTests8.cxx
index 63e946336f54ae8d97a12ce41cfe3478225f0214..c948600503a217f1a6f89e33618659d644aab84a 100644
--- a/Testing/Code/Common/otbCommonTests8.cxx
+++ b/Testing/Code/Common/otbCommonTests8.cxx
@@ -30,6 +30,8 @@ void RegisterTests()
   REGISTER_TEST(otbQuickLookImageGenerator);
   REGISTER_TEST(otbImageRegionTileMapSplitterNew);
   REGISTER_TEST(otbImageRegionTileMapSplitter);
+  REGISTER_TEST(otbImageRegionSquareTileSplitterNew);
+  REGISTER_TEST(otbImageRegionSquareTileSplitter);
   REGISTER_TEST(otbImageOfVectorsToMonoChannelExtractROINew);
   REGISTER_TEST(otbImageOfVectorsToMonoChannelExtractROI);
   REGISTER_TEST(otbImageRegionNonUniformMultidimensionalSplitterNew);
diff --git a/Testing/Code/Common/otbImageRegionSquareTileSplitter.cxx b/Testing/Code/Common/otbImageRegionSquareTileSplitter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..89c790ebca52e0ceb456886d77d74b2a98bd1460
--- /dev/null
+++ b/Testing/Code/Common/otbImageRegionSquareTileSplitter.cxx
@@ -0,0 +1,146 @@
+/*=========================================================================
+
+  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 "otbImageRegionSquareTileSplitter.h"
+#include <fstream>
+
+const int Dimension = 2;
+typedef otb::ImageRegionSquareTileSplitter<Dimension> SquareTileSplitterType;
+typedef SquareTileSplitterType::IndexType                       IndexType;
+typedef SquareTileSplitterType::SizeType                        SizeType;
+typedef SquareTileSplitterType::RegionType                      RegionType;
+
+
+int otbImageRegionSquareTileSplitterNew(int argc, char * argv[])
+{
+  SquareTileSplitterType::Pointer splitter = SquareTileSplitterType::New();
+
+  std::cout << splitter << std::endl;
+
+  return EXIT_SUCCESS;
+}
+
+int TestSplitter(const RegionType& region, unsigned int PixelSize, unsigned int MaxTileSize, std::ostream& os)
+{
+  os << "----------------------------------" << std::endl;
+  os << "Region    : " << region << std::endl;
+  os << "PixelSize : " << PixelSize << std::endl;
+  os << "MaxTileSize  : " << MaxTileSize << std::endl;
+
+  SquareTileSplitterType::Pointer splitter;
+  splitter = SquareTileSplitterType::New();
+
+  unsigned int requestedNbSplits = region.GetNumberOfPixels() * PixelSize / MaxTileSize;
+  if (requestedNbSplits == 0)
+    requestedNbSplits = 1;
+  os << "Requested Number of splits  : " << requestedNbSplits << std::endl;
+
+  const unsigned int nbSplits = splitter->GetNumberOfSplits(region, requestedNbSplits);
+  os << "Actual Number of splits  : " << nbSplits << std::endl;
+
+
+  RegionType split;
+
+  // First split :
+  split = splitter->GetSplit(0, nbSplits, region);
+  os << "First Split : " << split
+     << "(" << split.GetNumberOfPixels() * PixelSize << " bytes)" << std::endl;
+
+  if (nbSplits > 1)
+    {
+    // Second split :
+    split = splitter->GetSplit(1, nbSplits, region);
+    os << "Second Split : " << split
+       << "(" << split.GetNumberOfPixels() * PixelSize << " bytes)" << std::endl;
+    }
+
+  if (nbSplits > 2)
+    {
+    // Last split :
+    split = splitter->GetSplit(nbSplits - 1, nbSplits, region);
+    os << "Last Split : " << split
+       << "(" << split.GetNumberOfPixels() * PixelSize << " bytes)" << std::endl;
+    }
+
+  return EXIT_SUCCESS;
+}
+
+
+int otbImageRegionSquareTileSplitter(int argc, char * argv[])
+{
+  std::ofstream outfile(argv[1]);
+  RegionType region;
+
+  // Test with a 0-based indexed region
+  region.SetIndex(0, 0);
+  region.SetIndex(1, 0);
+  region.SetSize(0, 1024);
+  region.SetSize(1, 1024);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a shifted region
+  region.SetIndex(0, 42);
+  region.SetIndex(1, 42);
+  region.SetSize(0, 1000);
+  region.SetSize(1, 1000);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a negative shift
+  region.SetIndex(0, -42);
+  region.SetIndex(1, -42);
+  region.SetSize(0, 1000);
+  region.SetSize(1, 1000);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a reduced size
+  region.SetIndex(0, 0);
+  region.SetIndex(1, 0);
+  region.SetSize(0, 1);
+  region.SetSize(1, 1);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a reduced size, shifted
+  region.SetIndex(0, 42);
+  region.SetIndex(1, 42);
+  region.SetSize(0, 1);
+  region.SetSize(1, 1);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  outfile.close();
+
+  return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/Common/otbQuickLookImageGenerator.cxx b/Testing/Code/Common/otbQuickLookImageGenerator.cxx
index 071f7fd5c642a1bccebd3e308f9f994181a34261..8e86c247de19a0801e2741ae603c9c1805a68608 100644
--- a/Testing/Code/Common/otbQuickLookImageGenerator.cxx
+++ b/Testing/Code/Common/otbQuickLookImageGenerator.cxx
@@ -49,6 +49,8 @@ int otbQuickLookImageGenerator(int argc, char* argv[])
   filter->SetMaximumKernelWidth(atoi(argv[6]));
   filter->UseImageSpacing(atoi(argv[7]));
 
+  filter->Update();
+
   writer->SetInput(filter->GetOutput());
   writer->SetFileName(outputFileName);
 
diff --git a/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx
index d6576ab6e6be1de99c0fdb18cfc6ae756c807d08..6c9733dadd957382625aba51c521c9e133aae49b 100644
--- a/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx
@@ -70,9 +70,6 @@ int otbImageScalarFileWriterTestWithoutInputGeneric(int argc, char* argv[])
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
-  ImagePixelType pixVal;
-
   while (!it.IsAtEnd())
     {
     it.Set(static_cast<PixelType> (size[0] * it.GetIndex()[1] + it.GetIndex()[0]));
diff --git a/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx
index 372218fe4c2692489c0d638f1ff19d39c30f8507..cff8ed3b03c25fbcfde335d591029c4d29b541c4 100644
--- a/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx
@@ -71,9 +71,6 @@ int otbImageScalarStreamingFileWriterTestWithoutInputGeneric(int argc, char* arg
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
-  ImagePixelType pixVal;
-
   while (!it.IsAtEnd())
     {
     it.Set(static_cast<PixelType> (size[0] * it.GetIndex()[1] + it.GetIndex()[0]));
diff --git a/Testing/Code/IO/otbSarImageMetadataInterfaceTest.cxx b/Testing/Code/IO/otbSarImageMetadataInterfaceTest.cxx
index 41b5e99ebdf81e7efd0e0eae6519102f3b39fff4..22531c528d8375652c9f8e4a4cbc87debbfef4b7 100644
--- a/Testing/Code/IO/otbSarImageMetadataInterfaceTest.cxx
+++ b/Testing/Code/IO/otbSarImageMetadataInterfaceTest.cxx
@@ -36,7 +36,9 @@ void printPointSet(otb::SarImageMetadataInterface::PointSetPointer pointSet, std
     {
     stream << "PointSet values :" << std::endl;
     otb::SarImageMetadataInterface::PointSetType::PointType point;
+    point.Fill(0);
     otb::SarImageMetadataInterface::PointSetType::PixelType pointValue;
+    pointValue.Fill(0);
     for (unsigned int i = 0; i < pointSet->GetNumberOfPoints(); ++i)
        {
        pointSet->GetPoint(i, &point);
diff --git a/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx
index fbb4b31b2992fd0911f2ff9ab669c934721448e4..00ce431586e39b497718303d0fcc25d1c691d5b6 100644
--- a/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx
@@ -84,7 +84,6 @@ int otbVectorImageFileWriterScalarTestWithoutInputGeneric(int argc, char* argv[]
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
@@ -179,7 +178,6 @@ int otbVectorImageFileWriterComplexTestWithoutInputGeneric(int argc, char* argv[
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
diff --git a/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
index b5768ec8717bca133d584a2605f5cb3da1750502..023d3c6adb4941ae625c5d63d45370e3f3bc1ba5 100644
--- a/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
@@ -84,7 +84,6 @@ int otbVectorImageStreamingFileWriterScalarTestWithoutInputGeneric(int argc, cha
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
@@ -105,7 +104,6 @@ int otbVectorImageStreamingFileWriterScalarTestWithoutInputGeneric(int argc, cha
   writer->SetInput(image);
   writer->Update();
 
-
   return EXIT_SUCCESS;
 }
 
@@ -180,7 +178,6 @@ int otbVectorImageStreamingFileWriterComplexTestWithoutInputGeneric(int argc, ch
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
diff --git a/Testing/Code/Visualization/otbImageLayerScalar.cxx b/Testing/Code/Visualization/otbImageLayerScalar.cxx
index d14ac1518b77547d8c0632cd6bc211dbe82fe467..515e5e8dd2209a42cf008fc5bc35693202113bc7 100644
--- a/Testing/Code/Visualization/otbImageLayerScalar.cxx
+++ b/Testing/Code/Visualization/otbImageLayerScalar.cxx
@@ -53,6 +53,7 @@ int otbImageLayerScalar(int argc, char * argv[])
   // Quicklook
   shrinker->SetInput(reader->GetOutput());
   shrinker->SetShrinkFactor(ssrate);
+  shrinker->Update();
 
   // new layer
   LayerType::Pointer layer = LayerType::New();
diff --git a/Testing/Code/Visualization/otbImageLayerVector.cxx b/Testing/Code/Visualization/otbImageLayerVector.cxx
index 04ab0b7ca10fd739ef33b9336cdf88fb10a9ad8d..94e46a11af24b5373a0fc062b236dc7152119f13 100644
--- a/Testing/Code/Visualization/otbImageLayerVector.cxx
+++ b/Testing/Code/Visualization/otbImageLayerVector.cxx
@@ -65,6 +65,7 @@ int otbImageLayerVector(int argc, char * argv[])
   // Quicklook
   shrinker->SetInput(reader->GetOutput());
   shrinker->SetShrinkFactor(ssrate);
+  shrinker->Update();
 
   // new layer
   LayerType::Pointer layer = LayerType::New();
diff --git a/otbConfigure.h.in b/otbConfigure.h.in
index ab1f7d425524181d86d0022f76f02bbb8822b9be..29e21a97c10853e99033fb7e2de510ead5f3b417 100644
--- a/otbConfigure.h.in
+++ b/otbConfigure.h.in
@@ -1,5 +1,5 @@
 /*
- * here is where system comupted values get stored these values should only
+ * here is where system computed values get stored these values should only
  * change when the target compile platform changes
  */