diff --git a/Modules/Wrappers/SWIG/src/otbApplication.i b/Modules/Wrappers/SWIG/src/otbApplication.i
index 3cf79c5d8991ba6e59eeb21ea75b39f6775b60f5..2f4139254868b91935628529664031ff5fff91e1 100644
--- a/Modules/Wrappers/SWIG/src/otbApplication.i
+++ b/Modules/Wrappers/SWIG/src/otbApplication.i
@@ -271,8 +271,10 @@ public:
           logger = self.GetLogger()
           logger.AddLogOutput(_libraryLogOutput.GetPointer())
           
+          self.progressReportManager = ProgressReporterManager_New()
+          self.progressReportManager.SetLogOutputCallback(_libraryLogCallback)
           self.AddObserver(AddProcessToWatchEvent(),
-                           _libraryProgressReportManager.GetAddProcessCommand()
+                           self.progressReportManager.GetAddProcessCommand()
                           )
       }
     }
@@ -605,146 +607,149 @@ class ApplicationProxy(object):
   %pythoncode
     {
 
-		def GetParameterTypeAsString(self, parameter_type):
-			return {
-				ParameterType_String : 'ParameterType_String',
-				ParameterType_InputFilename : 'ParameterType_InputFilename',
-				ParameterType_OutputImage : 'ParameterType_OutputImage',
-				ParameterType_OutputVectorData : 'ParameterType_OutputVectorData',
-				ParameterType_OutputFilename : 'ParameterType_OutputFilename',
-				ParameterType_Directory : 'ParameterType_Directory',
-				ParameterType_InputImage : 'ParameterType_InputImage',
-				ParameterType_InputVectorData : 'ParameterType_InputVectorData',
-				ParameterType_InputImageList : 'ParameterType_InputImageList',
-				ParameterType_InputVectorDataList : 'ParameterType_InputImageList',
-				ParameterType_InputFilenameList : 'ParameterType_InputFilenameList',
-				ParameterType_StringList : 'ParameterType_StringList',
-				ParameterType_ListView : 'ParameterType_ListView',
-				ParameterType_Int : 'ParameterType_Int',
-				ParameterType_Radius : 'ParameterType_Radius',
-				ParameterType_RAM : 'ParameterType_RAM',
-				ParameterType_Float : 'ParameterType_Float',
-				ParameterType_Choice : 'ParameterType_Choice',
-				ParameterType_Group : 'ParameterType_Group',
-				ParameterType_Bool : 'ParameterType_Bool'
-			}.get(parameter_type, 'ParameterType_UNKNOWN')
-
-		def __str__(self):
-			s  = self.GetName()
-			s += '\n'
-			s += self.GetDocLongDescription()
-			return s
-
-		def SetParameters(self, dict_params):
-			for param_key, param_value in dict_params.items():
-				self.SetParameterValue(param_key, param_value)
-
-		def SetParameterValue(self, paramKey, value):
-			paramType = self.GetParameterType(paramKey)
-			if paramType in [ParameterType_RAM,
-											 ParameterType_String, ParameterType_InputFilename,
-											 ParameterType_OutputImage, ParameterType_OutputVectorData,
-											 ParameterType_OutputFilename,
-											 ParameterType_Directory, ParameterType_InputImage,
-											 ParameterType_InputVectorData]:
-			  return self.SetParameterString(paramKey, value)
-			elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList,
-												 ParameterType_InputFilenameList, ParameterType_StringList,
-												 ParameterType_ListView]:
-			  return self.SetParameterStringList(paramKey, value)
-			elif paramType in [ParameterType_Int, ParameterType_Radius]:
-			  return self.SetParameterInt(paramKey, value)
-			elif paramType in [ParameterType_Float]:
-			  return self.SetParameterFloat(paramKey, value)
-			elif paramType in [ParameterType_Bool]:
-			  return self.SetParameterString(paramKey, str(value) )
-			elif paramType in [ParameterType_Group]:
-			  return ApplicationProxy(self, paramKey)
-			elif paramType in [ParameterType_Choice]:
-			  return ApplicationProxy(self, paramKey, value)
-			else:
-			  print ("Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey))
-			return
-
-		def GetParameters(self):
-			ret = {}
-			for key in self.GetParametersKeys():
-				if self.HasValue(key) and self.IsParameterEnabled(key) and self.GetParameterRole(key) == 0:
-					ret[key] = self.GetParameterValue(key)
-			return ret
-
-		def GetParameterValue(self, paramKey):
-			paramType = self.GetParameterType(paramKey)
-			if paramType in [
-											 ParameterType_String, ParameterType_InputFilename,
-											 ParameterType_OutputImage, ParameterType_OutputVectorData,
-											 ParameterType_OutputFilename,
-											 ParameterType_Directory, ParameterType_InputImage,
-											 ParameterType_InputVectorData]:
-			  return self.GetParameterString(paramKey)
-			elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList,
-												 ParameterType_InputFilenameList, ParameterType_StringList,
-												 ParameterType_ListView]:
-			  return self.GetParameterStringList(paramKey)
-			elif paramType in [ParameterType_Int, ParameterType_Radius, ParameterType_RAM]:
-			  return self.GetParameterInt(paramKey)
-			elif paramType in [ParameterType_Float]:
-			  return self.GetParameterFloat(paramKey)
-			elif paramType in [ParameterType_Bool]:
-			  return bool(self.GetParameterInt(paramKey))
-			elif paramType in [ParameterType_Group, ParameterType_Choice]:
-			  return ApplicationProxy(self, paramKey)
-			else:
-			  print ("Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey))
-			return None
-
-		def __getattr__(self,name):
-			"""
-			__get_attribute__ is called whenever an instance request an attribute.
-			eg: App.SetParameterString(), App.GetName() ..
-			__getattr__ is only called if the attribute is not found by __get_attribute__ call
-			So we keep hide the GetParameter** calls within this method so that it seems like
-			an obivous call for users. App.IN , App.OUT , where 'in' and 'out' are
-			parameters in the 'otb application' with instance App
-			Since SWIG also uses this function, we have to copy their code before
-			using custom OTB behaviour
-			"""
-			if (name == "thisown"):
-				return self.this.own()
-			method = Application.__swig_getmethods__.get(name, None)
-			if method:
-				return method(self)
-			key_list = [k.upper() for k in self.GetParametersKeys(True)]
-			if name in key_list:
-				return self.GetParameterValue(name.lower())
-			raise AttributeError("'%s' object has no attribute '%s'" % (Application.__name__, name))
-
-		def __setattr__(self, name, value):
-			"""
-			__setattr__ is called if the attribute requested is not found in the attribute list.
-			So these attributes are supposed to be 'key' of parameters used. Here we
-			keep hide the SetParameter** calls within this method so that it seems like
-			an obivous call for users. App.IN='my-input-file-name' , App.OUT='my-output-file-name'w
-			here 'in' and 'out' are    parameters in the 'otb application' with instance App
-			Ofcourse, we don't blindly accept any attributes as python, we check them against
-			list of existing parameters for application with 'self.GetParametersKeys(True)'
-			Since SWIG also uses this function, we have to copy their code before
-			using custom OTB behaviour
-			"""
-			if (name == "thisown"):
-				return self.this.own(value)
-			if (name == "this"):
-				if type(value).__name__ == 'SwigPyObject':
-					self.__dict__[name] = value
-					return
-			method = Application.__swig_setmethods__.get(name, None)
-			if method:
-				return method(self, value)
-			key_list = [k.upper() for k in self.GetParametersKeys(True)]
-			if name in key_list:
-				self.SetParameterValue(name.lower(), value)
-			else:
-				raise AttributeError("You cannot add attributes to %s" % self)
+    def GetParameterTypeAsString(self, parameter_type):
+      return {
+        ParameterType_String : 'ParameterType_String',
+        ParameterType_InputFilename : 'ParameterType_InputFilename',
+        ParameterType_OutputImage : 'ParameterType_OutputImage',
+        ParameterType_OutputVectorData : 'ParameterType_OutputVectorData',
+        ParameterType_OutputFilename : 'ParameterType_OutputFilename',
+        ParameterType_Directory : 'ParameterType_Directory',
+        ParameterType_InputImage : 'ParameterType_InputImage',
+        ParameterType_InputVectorData : 'ParameterType_InputVectorData',
+        ParameterType_InputImageList : 'ParameterType_InputImageList',
+        ParameterType_InputVectorDataList : 'ParameterType_InputImageList',
+        ParameterType_InputFilenameList : 'ParameterType_InputFilenameList',
+        ParameterType_StringList : 'ParameterType_StringList',
+        ParameterType_ListView : 'ParameterType_ListView',
+        ParameterType_Int : 'ParameterType_Int',
+        ParameterType_Radius : 'ParameterType_Radius',
+        ParameterType_RAM : 'ParameterType_RAM',
+        ParameterType_Float : 'ParameterType_Float',
+        ParameterType_Choice : 'ParameterType_Choice',
+        ParameterType_Group : 'ParameterType_Group',
+        ParameterType_Bool : 'ParameterType_Bool'
+      }.get(parameter_type, 'ParameterType_UNKNOWN')
+
+    def __str__(self):
+      s  = self.GetName()
+      s += '\n'
+      s += self.GetDocLongDescription()
+      return s
+
+    def SetParameters(self, dict_params):
+      for param_key, param_value in dict_params.items():
+        self.SetParameterValue(param_key, param_value)
+
+    def SetParameterValue(self, paramKey, value):
+      paramType = self.GetParameterType(paramKey)
+      if paramType in [ParameterType_RAM,
+                       ParameterType_String, ParameterType_InputFilename,
+                       ParameterType_OutputImage, ParameterType_OutputVectorData,
+                       ParameterType_OutputFilename,
+                       ParameterType_Directory, ParameterType_InputImage,
+                       ParameterType_InputVectorData]:
+        return self.SetParameterString(paramKey, value)
+      elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList,
+                         ParameterType_InputFilenameList, ParameterType_StringList,
+                         ParameterType_ListView]:
+        return self.SetParameterStringList(paramKey, value)
+      elif paramType in [ParameterType_Int, ParameterType_Radius]:
+        return self.SetParameterInt(paramKey, value)
+      elif paramType in [ParameterType_Float]:
+        return self.SetParameterFloat(paramKey, value)
+      elif paramType in [ParameterType_Bool]:
+        return self.SetParameterString(paramKey, str(value) )
+      elif paramType in [ParameterType_Group]:
+        return ApplicationProxy(self, paramKey)
+      elif paramType in [ParameterType_Choice]:
+        return ApplicationProxy(self, paramKey, value)
+      else:
+        print ("Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey))
+      return
+
+    def GetParameters(self):
+      ret = {}
+      for key in self.GetParametersKeys():
+        if self.HasValue(key) and self.IsParameterEnabled(key) and self.GetParameterRole(key) == 0:
+          ret[key] = self.GetParameterValue(key)
+      return ret
+
+    def GetParameterValue(self, paramKey):
+      paramType = self.GetParameterType(paramKey)
+      if paramType in [
+                       ParameterType_String, ParameterType_InputFilename,
+                       ParameterType_OutputImage, ParameterType_OutputVectorData,
+                       ParameterType_OutputFilename,
+                       ParameterType_Directory, ParameterType_InputImage,
+                       ParameterType_InputVectorData]:
+        return self.GetParameterString(paramKey)
+      elif paramType in [ParameterType_InputImageList, ParameterType_InputVectorDataList,
+                         ParameterType_InputFilenameList, ParameterType_StringList,
+                         ParameterType_ListView]:
+        return self.GetParameterStringList(paramKey)
+      elif paramType in [ParameterType_Int, ParameterType_Radius, ParameterType_RAM]:
+        return self.GetParameterInt(paramKey)
+      elif paramType in [ParameterType_Float]:
+        return self.GetParameterFloat(paramKey)
+      elif paramType in [ParameterType_Bool]:
+        return bool(self.GetParameterInt(paramKey))
+      elif paramType in [ParameterType_Group, ParameterType_Choice]:
+        return ApplicationProxy(self, paramKey)
+      else:
+        print ("Unsupported parameter type '%s' with key '%s'" %(self.GetParameterTypeAsString(paramType) ,paramKey))
+      return None
+
+    def __getattr__(self,name):
+      """
+      __get_attribute__ is called whenever an instance request an attribute.
+      eg: App.SetParameterString(), App.GetName() ..
+      __getattr__ is only called if the attribute is not found by __get_attribute__ call
+      So we keep hide the GetParameter** calls within this method so that it seems like
+      an obivous call for users. App.IN , App.OUT , where 'in' and 'out' are
+      parameters in the 'otb application' with instance App
+      Since SWIG also uses this function, we have to copy their code before
+      using custom OTB behaviour
+      """
+      if (name == "thisown"):
+        return self.this.own()
+      method = Application.__swig_getmethods__.get(name, None)
+      if method:
+        return method(self)
+      key_list = [k.upper() for k in self.GetParametersKeys(True)]
+      if name in key_list:
+        return self.GetParameterValue(name.lower())
+      raise AttributeError("'%s' object has no attribute '%s'" % (Application.__name__, name))
+
+    def __setattr__(self, name, value):
+      """
+      __setattr__ is called if the attribute requested is not found in the attribute list.
+      So these attributes are supposed to be 'key' of parameters used. Here we
+      keep hide the SetParameter** calls within this method so that it seems like
+      an obivous call for users. App.IN='my-input-file-name' , App.OUT='my-output-file-name'w
+      here 'in' and 'out' are    parameters in the 'otb application' with instance App
+      Ofcourse, we don't blindly accept any attributes as python, we check them against
+      list of existing parameters for application with 'self.GetParametersKeys(True)'
+      Since SWIG also uses this function, we have to copy their code before
+      using custom OTB behaviour
+      """
+      if (name == "thisown"):
+        return self.this.own(value)
+      if (name == "this"):
+        if type(value).__name__ == 'SwigPyObject':
+          self.__dict__[name] = value
+          return
+      if (name == "progressReportManager"):
+        super().__setattr__(name, value)
+        return
+      method = Application.__swig_setmethods__.get(name, None)
+      if method:
+        return method(self, value)
+      key_list = [k.upper() for k in self.GetParametersKeys(True)]
+      if name in key_list:
+        self.SetParameterValue(name.lower(), value)
+      else:
+        raise AttributeError("You cannot add attributes to %s" % self)
 
     }
 }
diff --git a/Modules/Wrappers/SWIG/src/otbPythonLogOutput.i b/Modules/Wrappers/SWIG/src/otbPythonLogOutput.i
index 748c8bfef4820b6bd9a04c6d19d8c57f61ca7a84..044942d56dfef11fef66bcc2d40fb5595097948d 100644
--- a/Modules/Wrappers/SWIG/src/otbPythonLogOutput.i
+++ b/Modules/Wrappers/SWIG/src/otbPythonLogOutput.i
@@ -91,9 +91,7 @@ class ProgressReporterManager: public itkObject
 {
 public:
   /** Default constructor */
-  
   static ProgressReporterManager_Pointer New();
-  virtual void Delete();
   void DeleteWatcherList();
   void SetLogOutputCallback(otb::SwigPrintCallback* callback);
   itkCommand* GetAddProcessCommand();
@@ -109,14 +107,10 @@ DECLARE_REF_COUNT_CLASS( ProgressReporterManager )
 %pythoncode {
   _libraryLogOutput = PythonLogOutput_New()
   _libraryLogCallback = PythonPrintCallback()
-  _libraryProgressReportManager = ProgressReporterManager_New()
-  
+
   Logger.Instance().ResetOutputs()
   _libraryLogOutput.SetCallback(_libraryLogCallback)
   Logger.Instance().AddLogOutput(_libraryLogOutput.GetPointer())
-  
-  _libraryProgressReportManager.SetLogOutputCallback(_libraryLogCallback)
-
 }
 
 #endif
diff --git a/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.cxx b/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.cxx
index e3a6ac541739b337fea15b1597a186b559031042..ff53453bbeac70dbf42b17a5d8c091bbe0d1e55c 100644
--- a/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.cxx
+++ b/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.cxx
@@ -38,11 +38,6 @@ ProgressReporterManager::~ProgressReporterManager()
 
 void ProgressReporterManager::DeleteWatcherList()
 {
-  //Delete all stored progress reporter
-  for (auto watcher: m_WatcherList)
-  {
-    delete watcher;
-  }
   m_WatcherList.clear();
 }
 
@@ -52,9 +47,9 @@ void ProgressReporterManager::LinkWatchers(itk::Object* itkNotUsed(caller), cons
   {
     const Wrapper::AddProcessToWatchEvent* eventToWatch = dynamic_cast<const Wrapper::AddProcessToWatchEvent*>(&event);
 
-    auto watch = new WatcherType(eventToWatch->GetProcess(), eventToWatch->GetProcessDescription());
+    auto watch = std::make_unique< WatcherType>(eventToWatch->GetProcess(), eventToWatch->GetProcessDescription());
     watch->SetCallback(m_Callback);
-    m_WatcherList.push_back(watch);
+    m_WatcherList.push_back(std::move(watch));
   }
 }
 }
diff --git a/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.h b/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.h
index ec15926fd20ad0b91ac238f0fbc1b7e61b0e4c1b..59d0cafd26b5ad962290553f9f2d9d013dd5cbad 100644
--- a/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.h
+++ b/Modules/Wrappers/SWIG/src/python/otbProgressReporterManager.h
@@ -27,6 +27,8 @@
 #include "otbSwigPrintCallback.h"
 #include "otbStandardOneLineFilterWatcher.h"
 
+#include <memory>
+
 namespace otb
 {
 
@@ -54,7 +56,7 @@ public:
   typedef StandardOneLineFilterWatcher<CallbackType> WatcherType;
   
   /** Filter watcher list type */
-  typedef std::vector<WatcherType *> WatcherListType;
+  typedef std::vector<std::unique_ptr <WatcherType> > WatcherListType;
 
   /** Command Member */
   typedef itk::MemberCommand<Self> AddProcessCommandType;