diff --git a/Data/Baseline/OTB/Images/apTvUtSmoothingTestAnisotropic.tif b/Data/Baseline/OTB/Images/apTvUtSmoothingTestAnisotropic.tif
new file mode 100644
index 0000000000000000000000000000000000000000..5336d199981b5d04949f5975d7db85891472cc02
--- /dev/null
+++ b/Data/Baseline/OTB/Images/apTvUtSmoothingTestAnisotropic.tif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bdd0ce0f98ec479767e9e4cbb8f118753963f9a91c689870c3f02758de94d15e
+size 3422183
diff --git a/Data/Baseline/OTB/Images/apTvUtSmoothingTestGaussian.tif b/Data/Baseline/OTB/Images/apTvUtSmoothingTestGaussian.tif
new file mode 100644
index 0000000000000000000000000000000000000000..539c8486c84743e13cdaccf1c654fd11e3191975
--- /dev/null
+++ b/Data/Baseline/OTB/Images/apTvUtSmoothingTestGaussian.tif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5a9e56c55f2cb4f16ad31b762f1a38283c664d5570671fdf5f8a905f03a53a13
+size 3308861
diff --git a/Data/Input/apTvUtSmoothingTest_OutXML.xml b/Data/Input/apTvUtSmoothingTest_OutXML.xml
deleted file mode 100644
index 2f95025e38bfb54bf6b8d5d9accf3e91b02c62f4..0000000000000000000000000000000000000000
--- a/Data/Input/apTvUtSmoothingTest_OutXML.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" ?>
-<OTB>
-    <version>3.18</version>
-    <build>18-05-2013</build>
-    <platform>Linux</platform>
-    <application>
-        <name>Smoothing</name>
-        <descr>Apply a smoothing filter to an image</descr>
-        <doc>
-            <name>Smoothing</name>
-            <longdescr>This application applies smoothing filter to an image. Either gaussian, mean, or anisotropic diffusion are available.</longdescr>
-            <authors>OTB-Team</authors>
-            <limitations>None</limitations>
-            <seealso> </seealso>
-            <tags>
-                <tag>Image Filtering</tag>
-            </tags>
-        </doc>
-        <parameter mandatory="true">
-            <key>in</key>
-            <type>InputImage</type>
-            <name>Input Image</name>
-            <value>/home/rashad/repos/orfeo/OTB-Data/Input/poupees.tif</value>
-        </parameter>
-        <parameter mandatory="true">
-            <key>out</key>
-            <type>OutputImage</type>
-            <name>Output Image</name>
-            <value>/home/rashad/repos/orfeo/build/OTB_/test-build/Testing/Temporary/apTvUtSmoothingTest_OutXML.tif</value>
-        </parameter>
-        <parameter mandatory="true">
-            <key>type</key>
-            <type>Choice</type>
-            <name>Smoothing Type</name>
-            <value>mean</value>
-        </parameter>
-    </application>
-</OTB>
diff --git a/Modules/Applications/AppFiltering/app/otbFastNLMeans.cxx b/Modules/Applications/AppFiltering/app/otbFastNLMeans.cxx
index 3ed27ed028bfe43d0e1c27e626c9ab6d155125a3..c6e12f241bdadc42a6f1852289d111f78c37a4cb 100644
--- a/Modules/Applications/AppFiltering/app/otbFastNLMeans.cxx
+++ b/Modules/Applications/AppFiltering/app/otbFastNLMeans.cxx
@@ -59,7 +59,7 @@ private:
         "This filter relies on integral images. Overflow may happen though the risk is limited "
         " by OTB mechanism which process data by chunks.");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+    SetDocSeeAlso("Smoothing");
     AddDocTag(Tags::Filter);
 
     // Parameter declarations
@@ -110,25 +110,25 @@ private:
 
   void DoExecute() override
   {
-    // Get the input image
-    ImageType::Pointer         imIn           = this->GetParameterFloatImage("in");
-    float                      sigma          = this->GetParameterFloat("sig");
-    float                      cutoffDistance = this->GetParameterFloat("thresh");
-    int                        halfPatchSize  = this->GetParameterInt("patchradius");
-    int                        halfSearchSize = this->GetParameterInt("searchradius");
-    NLMeansFilterType::Pointer nlMeansFilter  = NLMeansFilterType::New();
+    // Get the input parameters
+    const auto imIn = this->GetParameterFloatImage("in");
+    const auto sigma = this->GetParameterFloat("sig");
+    const auto cutoffDistance = this->GetParameterFloat("thresh");
+    const auto halfPatchSize  = this->GetParameterInt("patchradius");
+    const auto halfSearchSize = this->GetParameterInt("searchradius");
+    
+    auto nlMeansFilter = NLMeansFilterType::New();
+    
     nlMeansFilter->SetInput(imIn);
     nlMeansFilter->SetSigma(sigma);
     nlMeansFilter->SetHalfWindowSize(halfPatchSize);
     nlMeansFilter->SetHalfSearchSize(halfSearchSize);
     nlMeansFilter->SetCutOffDistance(cutoffDistance);
 
-    m_FilterRef = nlMeansFilter;
     SetParameterOutputImage("out", nlMeansFilter->GetOutput());
     RegisterPipeline();
   }
 
-  itk::LightObject::Pointer m_FilterRef;
 }; // end class
 
 } // namespace Wrapper
diff --git a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
index f465172b66a2ad441e7c12888d917409785a1d89..4803bc7e934cfe09e825ea39c82f1d571284b718 100644
--- a/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
+++ b/Modules/Applications/AppFiltering/app/otbSmoothing.cxx
@@ -62,11 +62,21 @@ private:
 
     SetDocLongDescription(
         "This application applies a smoothing filter to an "
-        "image. Three methods can be used: a gaussian filter , a mean filter "
-        ", or an anisotropic diffusion using the Perona-Malik algorithm.");
+        "image. Three methods can be used: a mean filter, a gaussian filter based on [1]"
+        ", or an anisotropic diffusion using the Perona-Malik algorithm [2].");
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
-    SetDocSeeAlso(" ");
+    SetDocSeeAlso("FastNLMeans \n"
+                   "[1] Tony Lindeberg Discrete "
+                   "Scale-Space Theory and the Scale-Space Primal Sketch.  Dissertation. Royal "
+                   "Institute of Technology, Stockholm, Sweden. May 1991 \n"
+                   "[2] Pietro Perona and Jitendra Malik, "
+                   "Scale-space and edge detection using anisotropic diffusion, "
+                   "IEEE Transactions on Pattern Analysis Machine Intelligence, vol. 12, pp. 629-639, 1990. \n"
+                   "itk::MeanImageFilter (mean mode)\n"
+                   "itk::DiscreteGaussianImageFilter (gaussian mode)\n"
+                   "itk::GradientAnisotropicDiffusionImageFilter (anidif mode)."
+                   );
 
     AddDocTag(Tags::Filter);
 
@@ -86,13 +96,21 @@ private:
 
     AddChoice("type.gaussian", "Gaussian");
 
-    AddParameter(ParameterType_Float, "type.gaussian.radius", "Radius");
-    SetParameterDescription("type.gaussian.radius", "Standard deviation of the gaussian kernel used to filter the image");
-    SetDefaultParameterFloat("type.gaussian.radius", 2.0);
-    // TODO rename this parameter
+    AddParameter(ParameterType_Float, "type.gaussian.stdev", "Standard deviation");
+    SetParameterDescription("type.gaussian.stdev", "Standard deviation of the gaussian kernel used to filter the image");
+    SetDefaultParameterFloat("type.gaussian.stdev", 2.0);
 
-    AddChoice("type.anidif", "Anisotropic Diffusion");
+    AddParameter(ParameterType_Float, "type.gaussian.maxerror", "Maximum error");
+    SetParameterDescription("type.gaussian.maxerror", "The algorithm will size the discrete kernel so that the error "
+                            "resulting from truncation of the kernel is no greater than maxerror.");
+    SetDefaultParameterFloat("type.gaussian.maxerror", 0.01);
+
+    AddParameter(ParameterType_Int, "type.gaussian.maxwidth", "Maximum kernel width");
+    SetParameterDescription("type.gaussian.maxwidth", "Set the kernel to be no wider than maxwidth pixels, "
+                             "even if type.gaussian.maxerror demands it.");
+    SetDefaultParameterInt("type.gaussian.maxwidth", 32);
 
+    AddChoice("type.anidif", "Anisotropic Diffusion");
 
     AddParameter(ParameterType_Float, "type.anidif.timestep", "Time Step");
     SetParameterDescription("type.anidif.timestep", "Time step that will be used to discretize the diffusion equation");
@@ -139,79 +157,79 @@ private:
 
   void DoExecute() override
   {
-    GetLogger()->Debug("Entering DoExecute\n");
-
-
-    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
+    const auto inImage = GetParameterImage("in");
 
     switch (GetParameterInt("type"))
     {
     case Smoothing_Mean:
     {
-      GetLogger()->Debug("Using mean");
+      otbAppLogINFO("Using mean smoothing");
 
       typedef itk::MeanImageFilter<ImageType, ImageType> MeanFilterType;
       typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, MeanFilterType> PerBandMeanFilterType;
 
-      PerBandMeanFilterType::Pointer perBand = PerBandMeanFilterType::New();
+      auto perBand = PerBandMeanFilterType::New();
       perBand->SetInput(inImage);
 
       MeanFilterType::InputSizeType radius;
       radius.Fill(GetParameterInt("type.mean.radius"));
       perBand->GetFilter()->SetRadius(radius);
-      perBand->UpdateOutputInformation();
-      m_FilterRef = perBand;
+
       SetParameterOutputImage("out", perBand->GetOutput());
+      
+      RegisterPipeline();
     }
     break;
     case Smoothing_Gaussian:
     {
-      GetLogger()->Debug("Using gaussian");
+      otbAppLogINFO("Using gaussian smoothing");
 
       typedef itk::DiscreteGaussianImageFilter<ImageType, ImageType> DiscreteGaussianFilterType;
       typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, DiscreteGaussianFilterType> PerBandDiscreteGaussianFilterType;
 
-      PerBandDiscreteGaussianFilterType::Pointer perBand = PerBandDiscreteGaussianFilterType::New();
+      auto perBand = PerBandDiscreteGaussianFilterType::New();
       perBand->SetInput(inImage);
 
-      double radius   = GetParameterFloat("type.gaussian.radius");
-      double variance = radius * radius;
+      const auto stdev = GetParameterFloat("type.gaussian.stdev");
+      const auto variance = stdev * stdev;
+      
       perBand->GetFilter()->SetVariance(variance);
       perBand->GetFilter()->SetUseImageSpacing(false);
-      perBand->UpdateOutputInformation();
-      m_FilterRef = perBand;
+      perBand->GetFilter()->SetMaximumError(GetParameterFloat("type.gaussian.maxerror"));
+      perBand->GetFilter()->SetMaximumKernelWidth(GetParameterInt("type.gaussian.maxwidth"));
+      
       SetParameterOutputImage("out", perBand->GetOutput());
+      
+      RegisterPipeline();
     }
     break;
     case Smoothing_Anisotropic:
     {
-      GetLogger()->Debug("Using anisotropic diffusion");
+      otbAppLogINFO("Using anisotropic diffusion smoothing");
 
       typedef itk::GradientAnisotropicDiffusionImageFilter<ImageType, ImageType> GradientAnisotropicDiffusionFilterType;
       typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, GradientAnisotropicDiffusionFilterType>
           PerBandGradientAnisotropicDiffusionFilterType;
 
-      PerBandGradientAnisotropicDiffusionFilterType::Pointer perBand = PerBandGradientAnisotropicDiffusionFilterType::New();
+      auto perBand = PerBandGradientAnisotropicDiffusionFilterType::New();
       perBand->SetInput(inImage);
 
-      const int aniDifNbIter = GetParameterInt("type.anidif.nbiter");
+      const auto aniDifNbIter = GetParameterInt("type.anidif.nbiter");
       perBand->GetFilter()->SetNumberOfIterations(static_cast<unsigned int>(aniDifNbIter));
 
-      const float aniDifTimeStep = GetParameterFloat("type.anidif.timestep");
+      const auto aniDifTimeStep = GetParameterFloat("type.anidif.timestep");
       perBand->GetFilter()->SetTimeStep(static_cast<double>(aniDifTimeStep));
 
       perBand->GetFilter()->SetConductanceParameter(GetParameterFloat("type.anidif.conductance"));
       perBand->GetFilter()->SetUseImageSpacing(false);
-      perBand->UpdateOutputInformation();
 
-      m_FilterRef = perBand;
       SetParameterOutputImage("out", perBand->GetOutput());
+      
+      RegisterPipeline();
     }
     break;
     }
   }
-
-  itk::LightObject::Pointer m_FilterRef;
 };
 }
 }
diff --git a/Modules/Applications/AppFiltering/test/CMakeLists.txt b/Modules/Applications/AppFiltering/test/CMakeLists.txt
index 84ce8527671b5e9ecf1540dd0d80216297cfa707..73fad582ae6d2870150d37b95da902c6761882ed 100644
--- a/Modules/Applications/AppFiltering/test/CMakeLists.txt
+++ b/Modules/Applications/AppFiltering/test/CMakeLists.txt
@@ -20,9 +20,20 @@
 
 otb_module_test()
 #----------- Smoothing TESTS ----------------
+
+otb_test_application(NAME  apTvUtSmoothingTest_OutXML
+                     APP  Smoothing
+                     OPTIONS -in ${INPUTDATA}/poupees.tif
+               	             -out ${TEMP}/apTvUtSmoothingTest_OutXML.tif
+                             -type mean
+                             -outxml ${TEMP}/apTvUtSmoothingTest_OutXML.xml
+                     VALID   --compare-image ${NOTOL}
+                             ${BASELINE}/apTvUtSmoothingTest.tif
+                             ${TEMP}/apTvUtSmoothingTest_OutXML.tif)
+
 otb_test_application(NAME  apTvUtSmoothingTest_InXML
                      APP  Smoothing
-                     OPTIONS -inxml ${INPUTDATA}/apTvUtSmoothingTest_OutXML.xml
+                     OPTIONS -inxml ${TEMP}/apTvUtSmoothingTest_OutXML.xml
                	             -in ${INPUTDATA}/poupees.tif
                	             -out ${TEMP}/apTvUtSmoothingTest_InXML.tif
                              -type mean
@@ -30,24 +41,32 @@ otb_test_application(NAME  apTvUtSmoothingTest_InXML
                              ${BASELINE}/apTvUtSmoothingTest.tif
                              ${TEMP}/apTvUtSmoothingTest_InXML.tif)
 
-otb_test_application(NAME  apTvUtSmoothingTest
+set_tests_properties( apTvUtSmoothingTest_InXML
+    PROPERTIES DEPENDS apTvUtSmoothingTest_OutXML)
+
+otb_test_application(NAME  apTvUtSmoothingTestGaussian
                      APP  Smoothing
                      OPTIONS -in ${INPUTDATA}/poupees.tif
-               	             -out ${TEMP}/apTvUtSmoothingTest.tif
-                             -type mean
+               	             -out ${TEMP}/apTvUtSmoothingTestGaussian.tif
+                             -type gaussian
+                             -type.gaussian.stdev 2.0
+                             -type.gaussian.maxerror 0.1
+                             -type.gaussian.maxwidth 64
                      VALID   --compare-image ${NOTOL}
-                             ${BASELINE}/apTvUtSmoothingTest.tif
-                             ${TEMP}/apTvUtSmoothingTest.tif)
+                             ${BASELINE}/apTvUtSmoothingTestGaussian.tif
+                             ${TEMP}/apTvUtSmoothingTestGaussian.tif)
 
-otb_test_application(NAME  apTvUtSmoothingTest_OutXML
+otb_test_application(NAME  apTvUtSmoothingTestAnisotropic
                      APP  Smoothing
                      OPTIONS -in ${INPUTDATA}/poupees.tif
-               	             -out ${TEMP}/apTvUtSmoothingTest_OutXML.tif
-                             -type mean
-                             -outxml ${TEMP}/apTvUtSmoothingTest_OutXML.xml
-                     VALID   --compare-image ${NOTOL}
-                             ${BASELINE}/apTvUtSmoothingTest.tif
-                             ${TEMP}/apTvUtSmoothingTest_OutXML.tif)
+               	             -out ${TEMP}/apTvUtSmoothingTestAnisotropic.tif
+                             -type anidif
+                             -type.anidif.timestep 0.125
+                             -type.anidif.nbiter 10
+                             -type.anidif.conductance 1.
+                     VALID   --compare-image ${EPSILON_6}
+                             ${BASELINE}/apTvUtSmoothingTestAnisotropic.tif
+                             ${TEMP}/apTvUtSmoothingTestAnisotropic.tif)
 
 #----------- Contrast TESTS ----------------
 
@@ -115,7 +134,3 @@ otb_test_application(NAME  nlMeansTest_base
                              ${BASELINE}/GomaAvant_NLMeans.tif
                              ${TEMP}/GomaAvant_NLMeans.tif)
 
-
-                             
-                             
-