diff --git a/Modules/Adapters/OSSIMAdapters/test/otbDEMHandlerTest.cxx b/Modules/Adapters/OSSIMAdapters/test/otbDEMHandlerTest.cxx
index 7388ca058ccfd4ea48dd233945c4f4bc20282d2d..4d38777a01a7d85397065c2c2c872085146bd72c 100644
--- a/Modules/Adapters/OSSIMAdapters/test/otbDEMHandlerTest.cxx
+++ b/Modules/Adapters/OSSIMAdapters/test/otbDEMHandlerTest.cxx
@@ -40,8 +40,8 @@ int otbDEMHandlerTest(int argc, char* argv[])
   double      target        = atof(argv[7]);
   double      tolerance     = atof(argv[8]);
 
-  otb::DEMHandler::Pointer demHandler = otb::DEMHandler::Instance();
-  demHandler->SetDefaultHeightAboveEllipsoid(defaultHeight);
+  auto& demHandler = otb::DEMHandler::GetInstance();
+  demHandler.SetDefaultHeightAboveEllipsoid(defaultHeight);
 
   bool fail = false;
 
@@ -50,21 +50,21 @@ int otbDEMHandlerTest(int argc, char* argv[])
 
   if (demdir != "no")
   {
-    if (!demHandler->IsValidDEMDirectory(demdir.c_str()))
+    if (!demHandler.IsValidDEMDirectory(demdir.c_str()))
     {
       std::cerr << "IsValidDEMDirectory(" << demdir << ") = false" << std::endl;
       fail = true;
     }
 
-    demHandler->OpenDEMDirectory(demdir);
-    std::cout << "GetDEMDirectory() = " << demHandler->GetDEMDirectory() << std::endl;
+    demHandler.OpenDEMDirectory(demdir);
+    std::cout << "GetDEMDirectory() = " << demHandler.GetDEMDirectory() << std::endl;
   }
 
   if (geoid != "no")
   {
     try
     {
-      demHandler->OpenGeoidFile(geoid);
+      demHandler.OpenGeoidFile(geoid);
     }
     catch (const std::exception& exception)
     {
@@ -73,11 +73,9 @@ int otbDEMHandlerTest(int argc, char* argv[])
       fail = true;
     }
 
-    std::cout << "GetGeoidFile() = " << demHandler->GetGeoidFile() << std::endl;
+    std::cout << "GetGeoidFile() = " << demHandler.GetGeoidFile() << std::endl;
   }
 
-  std::cout << "PrintSelf: " << demHandler << std::endl;
-
   otb::DEMHandler::PointType point;
   point[0] = longitude;
   point[1] = latitude;
@@ -86,13 +84,13 @@ int otbDEMHandlerTest(int argc, char* argv[])
 
   if (aboveMSL)
   {
-    height = demHandler->GetHeightAboveMSL(point);
+    height = demHandler.GetHeightAboveMSL(point);
 
     std::cout << "height above MSL (" << longitude << ", " << latitude << ") = " << height << " meters" << std::endl;
   }
   else
   {
-    height = demHandler->GetHeightAboveEllipsoid(point);
+    height = demHandler.GetHeightAboveEllipsoid(point);
     std::cout << "height above ellipsoid (" << longitude << ", " << latitude << ") = " << height << " meters" << std::endl;
   }
 
diff --git a/Modules/Adapters/OSSIMAdapters/test/otbRPCSolverAdapterTest.cxx b/Modules/Adapters/OSSIMAdapters/test/otbRPCSolverAdapterTest.cxx
index fc9251e1d42ba178c8dd7572417a1e56d04d650b..e617e32bc2bbb0cda4a5a4faa1cd305e4f3582e2 100644
--- a/Modules/Adapters/OSSIMAdapters/test/otbRPCSolverAdapterTest.cxx
+++ b/Modules/Adapters/OSSIMAdapters/test/otbRPCSolverAdapterTest.cxx
@@ -63,12 +63,12 @@ int otbRPCSolverAdapterTest(int argc, char* argv[])
   std::cout << "GeoTol: " << geoTol << " meters" << std::endl;
   std::cout << "ImgTol: " << imgTol << " pixels" << std::endl;
 
-  otb::DEMHandler::Pointer demHandler = otb::DEMHandler::Instance();
-  demHandler->SetDefaultHeightAboveEllipsoid(0);
+  auto& demHandler = otb::DEMHandler::GetInstance();
+  demHandler.SetDefaultHeightAboveEllipsoid(0);
   if (demdir != "no")
-    demHandler->OpenDEMDirectory(demdir);
+    demHandler.OpenDEMDirectory(demdir);
   if (geoid != "no")
-    demHandler->OpenGeoidFile(geoid);
+    demHandler.OpenGeoidFile(geoid);
 
   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileName(infname);
@@ -99,7 +99,7 @@ int otbRPCSolverAdapterTest(int argc, char* argv[])
 
       currentWgs84Point = fwd2dTransform->TransformPoint(currentPoint);
 
-      double height = otb::DEMHandler::Instance()->GetHeightAboveEllipsoid(currentWgs84Point);
+      double height = demHandler.GetHeightAboveEllipsoid(currentWgs84Point);
 
       Point3DType current3DWgs84Point;
       current3DWgs84Point[0] = currentWgs84Point[0];
diff --git a/Modules/Applications/AppProjection/app/otbGenerateRPCSensorModel.cxx b/Modules/Applications/AppProjection/app/otbGenerateRPCSensorModel.cxx
index 7442f33305c6b92e10132cc7e6cc98fa5d2f1d21..d8dfa50b3c8605d55428ab2fdc6888ab8cf805b5 100644
--- a/Modules/Applications/AppProjection/app/otbGenerateRPCSensorModel.cxx
+++ b/Modules/Applications/AppProjection/app/otbGenerateRPCSensorModel.cxx
@@ -143,7 +143,7 @@ private:
       {
         std::istringstream iss(line);
         iss >> x >> y >> lon >> lat;
-        z = otb::DEMHandler::Instance()->GetHeightAboveEllipsoid(lon, lat);
+        z = otb::DEMHandler::GetInstance().GetHeightAboveEllipsoid(lon, lat);
 
         otbAppLogDEBUG("Adding tie point x=" << x << ", y=" << y << ", z=" << z << ", lon=" << lon << ", lat=" << lat);
 
diff --git a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
index ae1916ca7e991fa5970392bd8d79e89792e1383a..244e43fea80185fc146ac472301233dd5bf4cab6 100644
--- a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
+++ b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx
@@ -255,7 +255,7 @@ private:
     {
 
       // Clear and reset the DEM Handler
-      otb::DEMHandler::Instance()->ClearDEMs();
+      otb::DEMHandler::GetInstance().ClearDEMs();
       otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this, "elev");
 
       // input image
diff --git a/Modules/Applications/AppProjection/app/otbRefineSensorModel.cxx b/Modules/Applications/AppProjection/app/otbRefineSensorModel.cxx
index 7b79e0fb509ec16649264bbd62606f2faa47625e..9dcedb3e2e42b67a14ca554eede60908a11d2226 100644
--- a/Modules/Applications/AppProjection/app/otbRefineSensorModel.cxx
+++ b/Modules/Applications/AppProjection/app/otbRefineSensorModel.cxx
@@ -165,7 +165,7 @@ private:
         nextpos                        = line.find_first_of("\t", pos);
         lat                            = atof(line.substr(pos, nextpos).c_str());
 
-        z = otb::DEMHandler::Instance()->GetHeightAboveEllipsoid(lon, lat);
+        z = otb::DEMHandler::GetInstance().GetHeightAboveEllipsoid(lon, lat);
 
         otbAppLogDEBUG("Adding tie point x=" << x << ", y=" << y << ", z=" << z << ", lon=" << lon << ", lat=" << lat);
 
diff --git a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
index a2e2d3f33eb4f9bc30d96efef296d277bad39a7c..6a995450dff580101d7c13864a93eb6865d5aa3f 100644
--- a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
+++ b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx
@@ -311,7 +311,7 @@ private:
       AddProcess(m_StatisticsFilter->GetStreamer(), "Computing DEM statistics ...");
       m_StatisticsFilter->Update();
 
-      otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(m_StatisticsFilter->GetMean());
+      otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(m_StatisticsFilter->GetMean());
 
       EnableParameter("epi.elevation.avgdem.value");
       SetParameterFloat("epi.elevation.avgdem.value", m_StatisticsFilter->GetMean());
diff --git a/Modules/Core/Transform/include/otbSensorModelAdapter.h b/Modules/Core/Transform/include/otbSensorModelAdapter.h
index 7ab640a45e57ee375c037b9892935840cdcd3c83..759f99bc78c0a5ff971bb32259fa68fe69b88915 100644
--- a/Modules/Core/Transform/include/otbSensorModelAdapter.h
+++ b/Modules/Core/Transform/include/otbSensorModelAdapter.h
@@ -116,9 +116,6 @@ private:
   InternalMapProjectionPointer m_SensorModel;
 
   InternalTiePointsContainerPointer m_TiePoints;
-
-  /** Object that read and use DEM */
-  DEMHandler::Pointer m_DEMHandler;
 };
 
 } // namespace otb
diff --git a/Modules/Core/Transform/src/otbSensorModelAdapter.cxx b/Modules/Core/Transform/src/otbSensorModelAdapter.cxx
index 629cf6e6ffdc0910acab7a2aab502bbfc54996df..6f297b2cfdf847fad2c66e6d035a15ef31624ca0 100644
--- a/Modules/Core/Transform/src/otbSensorModelAdapter.cxx
+++ b/Modules/Core/Transform/src/otbSensorModelAdapter.cxx
@@ -63,7 +63,6 @@ namespace otb
 
 SensorModelAdapter::SensorModelAdapter() : m_SensorModel(nullptr), m_TiePoints(nullptr) // FIXME keeping the original value but...
 {
-  m_DEMHandler = DEMHandler::Instance();
   m_TiePoints  = new ossimTieGptSet();
 }
 
@@ -154,7 +153,7 @@ void SensorModelAdapter::InverseTransformPoint(double lon, double lat, double& x
   }
 
   // Get elevation from DEMHandler
-  double h = m_DEMHandler->GetHeightAboveEllipsoid(lon, lat);
+  double h = DEMHandler::GetInstance().GetHeightAboveEllipsoid(lon, lat);
 
   // Initialize with value from the function parameters
   ossimGpt ossimGPoint(lat, lon, h);
@@ -183,7 +182,7 @@ void SensorModelAdapter::AddTiePoint(double x, double y, double lon, double lat)
   ossimDpt imagePoint(internal::ConvertToOSSIMFrame(x), internal::ConvertToOSSIMFrame(y));
 
   // Get elevation from DEMHandler
-  double z = m_DEMHandler->GetHeightAboveEllipsoid(lon, lat);
+  double z = DEMHandler::GetInstance().GetHeightAboveEllipsoid(lon, lat);
 
   ossimGpt ossimGPoint(lat, lon, z);
 
diff --git a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h
index 695e25f14e6983bd15353f70bfa6590e0affa172..13dd735287242805ef0aca58087f764362a0bf27 100644
--- a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h
+++ b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h
@@ -185,7 +185,6 @@ protected:
   void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) override;
   void GenerateOutputInformation() override;
 
-  DEMHandlerType::Pointer m_DEMHandler;
   PointType               m_OutputOrigin;
   SpacingType             m_OutputSpacing;
   SizeType                m_OutputSize;
diff --git a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx
index bd9c303488070a0fc8f9d93bbb22c1c152d156f6..24b3dac2bae628c0791208520e679d7881f1068a 100644
--- a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx
+++ b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx
@@ -31,7 +31,6 @@ namespace otb
 template <class TDEMImage>
 DEMToImageGenerator<TDEMImage>::DEMToImageGenerator()
 {
-  m_DEMHandler          = DEMHandlerType::Instance();
   m_OutputSpacing[0]    = 0.0001;
   m_OutputSpacing[1]    = -0.0001;
   m_OutputSize[0]       = 1;
@@ -125,12 +124,12 @@ void DEMToImageGenerator<TDEMImage>::ThreadedGenerateData(const OutputImageRegio
       geoPoint = m_Transform->TransformPoint(phyPoint);
       if (m_AboveEllipsoid)
       {
-        height = m_DEMHandler->GetHeightAboveEllipsoid(geoPoint); // Altitude
+        height = DEMHandler::GetInstance().GetHeightAboveEllipsoid(geoPoint); // Altitude
                                                                   // calculation
       }
       else
       {
-        height = m_DEMHandler->GetHeightAboveMSL(geoPoint); // Altitude
+        height = DEMHandler::GetInstance().GetHeightAboveMSL(geoPoint); // Altitude
                                                             // calculation
       }
     }
@@ -138,12 +137,12 @@ void DEMToImageGenerator<TDEMImage>::ThreadedGenerateData(const OutputImageRegio
     {
       if (m_AboveEllipsoid)
       {
-        height = m_DEMHandler->GetHeightAboveEllipsoid(phyPoint); // Altitude
+        height = DEMHandler::GetInstance().GetHeightAboveEllipsoid(phyPoint); // Altitude
                                                                   // calculation
       }
       else
       {
-        height = m_DEMHandler->GetHeightAboveMSL(phyPoint); // Altitude
+        height = DEMHandler::GetInstance().GetHeightAboveMSL(phyPoint); // Altitude
                                                             // calculation
       }
     }
diff --git a/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx b/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx
index aef94cd6453c8f39b73694ff6367a0d5d2983f61..2d86d9743e8652770fba980e7488c04a189310dd 100644
--- a/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx
+++ b/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx
@@ -72,7 +72,7 @@ int otbDEMToImageGeneratorFromImageTest(int argc, char* argv[])
   WriterType::Pointer writer1 = WriterType::New();
   WriterType::Pointer writer2 = WriterType::New();
 
-  otb::DEMHandler::Instance()->OpenDEMDirectory(folderPath);
+  otb::DEMHandler::GetInstance().OpenDEMDirectory(folderPath);
 
   // Read input image
   reader->SetFileName(inputName);
diff --git a/Modules/Filtering/DEM/test/otbDEMToImageGeneratorTest.cxx b/Modules/Filtering/DEM/test/otbDEMToImageGeneratorTest.cxx
index dd5027ba0452f4e269c2e7f127cef031c1951a66..6d01eed72ecf328c7df472ffc715e2134d4f4392 100644
--- a/Modules/Filtering/DEM/test/otbDEMToImageGeneratorTest.cxx
+++ b/Modules/Filtering/DEM/test/otbDEMToImageGeneratorTest.cxx
@@ -47,8 +47,8 @@ int otbDEMToImageGeneratorTest(int argc, char* argv[])
   typedef otb::ImageFileWriter<ImageType>      WriterType;
 
   // Instantiating object
-  DEMToImageGeneratorType::Pointer object = DEMToImageGeneratorType::New();
-  WriterType::Pointer              writer = WriterType::New();
+  auto object = DEMToImageGeneratorType::New();
+  auto              writer = WriterType::New();
 
   PointType origin;
   origin[0] = ::atof(argv[3]);
@@ -62,7 +62,7 @@ int otbDEMToImageGeneratorTest(int argc, char* argv[])
   spacing[0] = ::atof(argv[7]);
   spacing[1] = ::atof(argv[8]);
 
-  otb::DEMHandler::Instance()->OpenDEMDirectory(folderPath);
+  otb::DEMHandler::GetInstance().OpenDEMDirectory(folderPath);
 
   object->SetOutputOrigin(origin);
   object->SetOutputSize(size);
diff --git a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h
index 9b5f3fccce69ced430c573438cb89ae9e85a31b8..eb167b2fa46b3ae22e88c0c5b86da44e3dff7e6a 100644
--- a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h
+++ b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h
@@ -98,7 +98,6 @@ public:
 
   /** DEM typedef */
   typedef otb::DEMHandler                  DEMHandlerType;
-  typedef typename DEMHandlerType::Pointer DEMHandlerPointerType;
 
   /** Method for creation through the object factory. */
   itkNewMacro(Self);
@@ -125,10 +124,6 @@ public:
   itkSetMacro(MeanElevation, double);
   itkGetConstReferenceMacro(MeanElevation, double);
 
-  /** Set/Get the DEMHandler */
-  itkSetObjectMacro(DEMHandler, DEMHandlerType);
-  itkGetObjectMacro(DEMHandler, DEMHandlerType);
-
   /** Get the residual ground error */
   itkGetConstReferenceMacro(RMSGroundError, double);
 
@@ -207,9 +202,6 @@ private:
    * over the image is used instead */
   double m_MeanElevation;
 
-  /** The DEMHandler */
-  DEMHandlerPointerType m_DEMHandler;
-
   /** Container of GCPs */
   GCPsContainerType m_GCPsContainer;
 
diff --git a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx
index c13ebc85e51fe7982e37970548f990d6afef56ba..a3df285e01aa01b83f4029c7b1a3690c9abb9204 100644
--- a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx
+++ b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx
@@ -40,7 +40,6 @@ GCPsToRPCSensorModelImageFilter<TImage>::GCPsToRPCSensorModelImageFilter()
     m_MeanError(0.),
     m_UseDEM(false),
     m_MeanElevation(0.),
-    m_DEMHandler(),
     m_GCPsContainer(),
     m_ModelUpToDate(false)
 {
@@ -51,9 +50,6 @@ GCPsToRPCSensorModelImageFilter<TImage>::GCPsToRPCSensorModelImageFilter()
 
   // Clear the GCPs container
   this->ClearGCPs();
-
-  /** Create the DEM handler */
-  m_DEMHandler = DEMHandler::Instance();
 }
 
 template <class TImage>
@@ -122,7 +118,7 @@ void GCPsToRPCSensorModelImageFilter<TImage>::AddGCP(const Point2DType& sensorPo
   if (m_UseDEM)
   {
     // If so, use it to get the elevation
-    double height = m_DEMHandler->GetHeightAboveEllipsoid(groundPoint);
+    double height = DEMHandler::GetInstance().GetHeightAboveEllipsoid(groundPoint);
     // To avoid nan value
     if (height != height)
       height                    = 0;
diff --git a/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx b/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx
index f9eec4089a28b97b08b3a9188b7db8c8a63ac86c..0370201ff9b03d23497679bc119d902a4c63e39a 100644
--- a/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx
+++ b/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx
@@ -96,7 +96,7 @@ int otbGCPsToRPCSensorModelImageFilterCheckRpcModel(int argc, char* argv[])
 
   // Set the DEM Directory
   if (std::string(argv[2]).compare("no_output") != 0)
-    otb::DEMHandler::Instance()->OpenDEMDirectory(argv[2]);
+    otb::DEMHandler::GetInstance().OpenDEMDirectory(argv[2]);
 
   grsTrasnform->InstantiateTransform();
 
diff --git a/Modules/Filtering/Projection/test/otbGenericRSResampleImageFilter.cxx b/Modules/Filtering/Projection/test/otbGenericRSResampleImageFilter.cxx
index d8132f061897412e4840221eeff59246c66447cf..6af25669be8f9ef4653b0307d7a1be3250ab373b 100644
--- a/Modules/Filtering/Projection/test/otbGenericRSResampleImageFilter.cxx
+++ b/Modules/Filtering/Projection/test/otbGenericRSResampleImageFilter.cxx
@@ -128,11 +128,11 @@ int otbGenericRSResampleImageFilter(int argc, char* argv[])
   // manage demHandler
   if (atoi(argv[12]) == 1) // mode = no DEM
   {
-    otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(135.8);
+    otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(135.8);
   }
   else if ((atoi(argv[12]) == 2) || (atoi(argv[12]) == 3)) // mode = DEM SRTM || DEM GTIFF
   {
-    otb::DEMHandler::Instance()->OpenDEMDirectory(argv[13]);
+    otb::DEMHandler::GetInstance().OpenDEMDirectory(argv[13]);
   }
 
   writer->SetInput(orthoRectifFilter->GetOutput());
diff --git a/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx b/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx
index 4a8af39b5bae329823500f5e48f3025341664b7f..1410fceaf98001ca50b7768e91896a1fef7dd49d 100644
--- a/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx
+++ b/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx
@@ -117,10 +117,10 @@ int otbGenericRSTransformImageAndMNTToWGS84ConversionChecking(int itkNotUsed(arg
   GeoDistanceType::Pointer   geoDistance   = GeoDistanceType::New();
   GeoDistance3DType::Pointer geoDistance3d = GeoDistance3DType::New();
 
-  otb::DEMHandler::Pointer demHandler = otb::DEMHandler::Instance();
-  demHandler->OpenDEMDirectory(argv[2]);
-  demHandler->OpenGeoidFile(argv[3]);
-  double heightAboveEllipsoid = demHandler->GetHeightAboveEllipsoid(refGeoPt);
+  auto & demHandler = otb::DEMHandler::GetInstance();
+  demHandler.OpenDEMDirectory(argv[2]);
+  demHandler.OpenGeoidFile(argv[3]);
+  double heightAboveEllipsoid = demHandler.GetHeightAboveEllipsoid(refGeoPt);
 
   // Instantiate WGS->Image transform
   TransformType::Pointer wgs2img = TransformType::New();
diff --git a/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx b/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx
index 1f57dd1c2825112bf18e4959ceeab46bf43e8942..cbc42748a502c25d1465a6c312e0f332ce146379 100644
--- a/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx
+++ b/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx
@@ -151,7 +151,7 @@ int otbGenericRSTransformGenericTest(int argc, char* argv[])
     }
 
     double averageElevation = atof(argv[14]);
-    otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(averageElevation);
+    otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(averageElevation);
 
     std::cout << "Average elevation " << averageElevation << " used." << std::endl;
   }
@@ -163,7 +163,7 @@ int otbGenericRSTransformGenericTest(int argc, char* argv[])
       return EXIT_FAILURE;
     }
 
-    otb::DEMHandler::Instance()->OpenDEMDirectory(argv[14]);
+    otb::DEMHandler::GetInstance().OpenDEMDirectory(argv[14]);
 
     std::cout << "Elevation from DEM " << argv[14] << " used." << std::endl;
   }
diff --git a/Modules/Filtering/Projection/test/otbSensorModel.cxx b/Modules/Filtering/Projection/test/otbSensorModel.cxx
index 208d57357442d061c1094d9fde818a64e04c9f76..baf10d54e862cb4cee6ef2de01dc942562c9ac0f 100644
--- a/Modules/Filtering/Projection/test/otbSensorModel.cxx
+++ b/Modules/Filtering/Projection/test/otbSensorModel.cxx
@@ -72,7 +72,7 @@ int produceGCP(char* outputgcpfilename, const otb::ImageKeywordlist& kwlist, boo
     return EXIT_FAILURE;
   }
 
-  otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(z);
+  otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(z);
 
   // ossim classes
   ossimKeywordlist ossimKwlist;
@@ -347,7 +347,7 @@ int otbSensorModel(int argc, char* argv[])
     geo3dPoint = *geo3dPointsIt;
 
     double z = geo3dPoint[2];
-    otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(z);
+    otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(z);
 
     // otbForwardSensorModel and otbInverseSensorModel
     geoPoint           = forwardSensorModel->TransformPoint(imagePoint);
diff --git a/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx b/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx
index 98ee1deee06ceec423e575484b83c78bece2d8b1..c91665f6a4f784925b2c419c1d032fd5af168cf8 100644
--- a/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx
+++ b/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx
@@ -50,7 +50,7 @@ int otbTileImageFilterRSTransformTest(int argc, char* argv[])
   TileImageFilterType::Pointer tileFilter = TileImageFilterType::New();
   tileFilter->SetLayout(layout);
 
-  otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(0);
+  otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(0);
 
   for (unsigned int i = 0; i < numberOfImages; ++i)
   {
diff --git a/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx b/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx
index dd1aec17c81ca56118ca4652bf8fc07a22f93681..36a3335abfa0a62920c2b7035a47a9658de33c49 100644
--- a/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx
+++ b/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx
@@ -131,7 +131,7 @@ int otbVectorDataIntoImageProjectionFilterCompareImplTest(int itkNotUsed(argc),
 
   if (!demDirectory.empty())
   {
-    otb::DEMHandler::Instance()->OpenDEMDirectory(demDirectory);
+    otb::DEMHandler::GetInstance().OpenDEMDirectory(demDirectory);
   }
 
   // Read the image
diff --git a/Modules/IO/IOGDAL/include/otbDEMHandler.h b/Modules/IO/IOGDAL/include/otbDEMHandler.h
index 4c3370395b1b3e5e63a1094a8aba6df7733ec318..830a5a90d009dbd0a38bad8118bb63c3270b758e 100644
--- a/Modules/IO/IOGDAL/include/otbDEMHandler.h
+++ b/Modules/IO/IOGDAL/include/otbDEMHandler.h
@@ -67,40 +67,29 @@ namespace otb
  *
  * \ingroup OTBIOGDAL
  */
-class DEMHandler: public itk::Object
+class DEMHandler
 {
 public:
-  /** @name Standard class typedefs
-  * @{
-  */
   using Self =          DEMHandler;
-  using Superclass =    itk::Object;
-  using Pointer =       itk::SmartPointer<Self>;
-  using ConstPointer =  itk::SmartPointer<const Self>;
-  /** @} */
-
   using PointType =     itk::Point<double, 2>;
 
   /** Retrieve the singleton instance */
-  static Pointer Instance();
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(DEMHandler, Object);
+  static DEMHandler & GetInstance();
 
   /** Try to open the DEM directory. 
   * \param path input path
   */
   void OpenDEMFile(const std::string & path);
 
-  /** Try to open the DEM directory. 
+  /** Open all raster in the directory. 
   * \param DEMDirectory input directory
   */
   void OpenDEMDirectory(const std::string& DEMDirectory);
 
-  /** return true if the directory contain raster 
+  /** Tells whether the directory contains a raster
   * \param DEMDirectory input directory
   */
-  bool IsValidDEMDirectory(const std::string& DEMDirectory);
+  bool IsValidDEMDirectory(const std::string& DEMDirectory) const;
 
   /** Try to open a geoid file 
   * \param geoidFile input geoid path
@@ -116,9 +105,9 @@ public:
    * \param lat input latitude
    * \return height above ellipsoid
   */
-  double GetHeightAboveEllipsoid(double lon, double lat);
+  double GetHeightAboveEllipsoid(double lon, double lat) const;
 
-  double GetHeightAboveEllipsoid(const PointType& geoPoint);
+  double GetHeightAboveEllipsoid(const PointType& geoPoint) const;
  
   /** Return the height above the mean sea level :
    * - SRTM and geoid both available: srtm_value
@@ -129,15 +118,15 @@ public:
    * \param lat input latitude
    * \return height above mean sea level
   */
-  double GetHeightAboveMSL(double lon, double lat);
+  double GetHeightAboveMSL(double lon, double lat) const;
 
-  double GetHeightAboveMSL(const PointType& geoPoint);
+  double GetHeightAboveMSL(const PointType& geoPoint) const;
 
   /** Return the number of DEM opened */
   unsigned int GetDEMCount() const;
   
-  itkGetMacro(DefaultHeightAboveEllipsoid, double);
-  
+  double GetDefaultHeightAboveEllipsoid() const;
+
   void SetDefaultHeightAboveEllipsoid(double height);
 
   /** Get DEM directory 
@@ -161,7 +150,6 @@ protected:
 private:
   DEMHandler(const Self&) = delete;
   void operator=(const Self&) = delete;
-
   /** List of RAII capsules on all opened DEM datasets for memory management */
   std::vector<otb::GDALDatasetWrapper::Pointer> m_DatasetList;
   
@@ -171,8 +159,6 @@ private:
   /** Pointer to the geoid dataset */
   GDALDataset* m_GeoidDS;
   
-  static Pointer m_Singleton;
-
   /** Default height above elliposid, used when no DEM or geoid height is available. */
   double m_DefaultHeightAboveEllipsoid;
 
diff --git a/Modules/IO/IOGDAL/src/otbDEMHandler.cxx b/Modules/IO/IOGDAL/src/otbDEMHandler.cxx
index c789c8d5adf02bce3cf444e440714826ee5ec400..d91621e2263bf00ba7e3df56a6e7b6acc66d30c8 100644
--- a/Modules/IO/IOGDAL/src/otbDEMHandler.cxx
+++ b/Modules/IO/IOGDAL/src/otbDEMHandler.cxx
@@ -21,6 +21,7 @@
 #include "otbDEMHandler.h"
 #include "otbGDALDriverManagerWrapper.h"
 #include "boost/filesystem.hpp"
+#include <boost/range/iterator_range.hpp>
 #include "gdal_utils.h"
 
 //TODO C++ 17 : use std::optional instead
@@ -48,32 +49,33 @@ std::vector<std::string> GetFilesInDirectory(const std::string & directoryPath)
     return fileList;
   }
   
-  boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
-  for ( boost::filesystem::directory_iterator itr( directoryPath ); itr != end_itr; ++itr )
+  // End iterator : default construction yields past-the-end
+  for ( const auto & item : boost::make_iterator_range(boost::filesystem::directory_iterator(directoryPath), {}) )
   {
-    if ( boost::filesystem::is_directory(itr->status()) )
+    if ( boost::filesystem::is_directory(item.status()) )
     {
-      auto subDirList = GetFilesInDirectory(itr->path().string());
+      auto subDirList = GetFilesInDirectory(item.path().string());
       fileList.insert(fileList.end(), subDirList.begin(), subDirList.end());
     }
     else
     {
-      fileList.push_back(itr->path().string());
+      fileList.push_back(item.path().string());
     }
   }
+
   return fileList;
 }
 
-boost::optional<double> GetDEMValue(double lon, double lat, GDALDataset* ds)
+boost::optional<double> GetDEMValue(double lon, double lat, GDALDataset& ds)
 {
   double geoTransform[6];
   
-  ds->GetGeoTransform(geoTransform);
+  ds.GetGeoTransform(geoTransform);
 
   auto x = (lon - geoTransform[0]) / geoTransform[1] - 0.5;
   auto y = (lat - geoTransform[3]) / geoTransform[5] - 0.5;
 
-  if (x < 0 || y < 0 || x > ds->GetRasterXSize() || y > ds->GetRasterYSize())
+  if (x < 0 || y < 0 || x > ds.GetRasterXSize() || y > ds.GetRasterYSize())
   {
     return boost::none;
   }
@@ -84,7 +86,7 @@ boost::optional<double> GetDEMValue(double lon, double lat, GDALDataset* ds)
   auto deltaX = x - x_int;
   auto deltaY = y - y_int;
 
-  if (x < 0 || y < 0 || x+1 > ds->GetRasterXSize() || y+1 > ds->GetRasterYSize())
+  if (x < 0 || y < 0 || x+1 > ds.GetRasterXSize() || y+1 > ds.GetRasterYSize())
   {
     return boost::none;
   }
@@ -92,7 +94,7 @@ boost::optional<double> GetDEMValue(double lon, double lat, GDALDataset* ds)
   // Bilinear interpolation.
   double elevData[4];
   
-  auto err = ds->GetRasterBand(1)->RasterIO( GF_Read, x_int, y_int, 2, 2,
+  auto err = ds.GetRasterBand(1)->RasterIO( GF_Read, x_int, y_int, 2, 2,
               elevData, 2, 2, GDT_Float64,
               0, 0, nullptr);
 
@@ -105,7 +107,7 @@ boost::optional<double> GetDEMValue(double lon, double lat, GDALDataset* ds)
   // of the interpolation is no data.
   for (int i =0; i<4; i++)
   {
-    if (elevData[i] == ds->GetRasterBand(1)->GetNoDataValue())
+    if (elevData[i] == ds.GetRasterBand(1)->GetNoDataValue())
     {
       return boost::none;
     }
@@ -120,26 +122,13 @@ boost::optional<double> GetDEMValue(double lon, double lat, GDALDataset* ds)
 
 }  // namespace DEMDetails
 
-/** Initialize the singleton */
-DEMHandler::Pointer DEMHandler::m_Singleton = nullptr;
-
-DEMHandler::Pointer DEMHandler::Instance()
+// Meyer singleton design pattern
+DEMHandler & DEMHandler::GetInstance() 
 {
-  if (m_Singleton.GetPointer() == nullptr)
-  {
-    m_Singleton = itk::ObjectFactory<Self>::Create();
-
-    if (m_Singleton.GetPointer() == nullptr)
-    {
-      m_Singleton = new DEMHandler;
-    }
-    m_Singleton->UnRegister();
-  }
-
-  return m_Singleton;
+  static DEMHandler s_instance;
+  return s_instance;
 }
 
-
 DEMHandler::DEMHandler() : m_Dataset(nullptr),
                            m_GeoidDS(nullptr),
                            m_DefaultHeightAboveEllipsoid(0.0)
@@ -170,7 +159,7 @@ void DEMHandler::OpenDEMDirectory(const std::string& DEMDirectory)
   {
     auto ds = otb::GDALDriverManagerWrapper::GetInstance().Open(file);
     if (ds)
-    {  
+    {
       m_DatasetList.push_back(ds );
     }
   }
@@ -197,10 +186,8 @@ void DEMHandler::OpenDEMDirectory(const std::string& DEMDirectory)
         vrtDatasetList[i] = m_DatasetList[i]->GetDataSet();
       }
 
-      int error = 0;
-
       m_Dataset = (GDALDataset *) GDALBuildVRT(nullptr, vrtSize, vrtDatasetList, 
-                                                nullptr, nullptr, &error);
+                                                nullptr, nullptr, nullptr);
       m_DEMDirectories.push_back(DEMDirectory);
       delete[] vrtDatasetList;
     }
@@ -226,7 +213,7 @@ bool DEMHandler::OpenGeoidFile(const std::string& geoidFile)
   return pbError;
 }
 
-double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat)
+double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat) const
 {
   double result = 0.;
   boost::optional<double> DEMresult;
@@ -234,7 +221,7 @@ double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat)
 
   if (m_Dataset)
   {
-    DEMresult = DEMDetails::GetDEMValue(lon, lat, m_Dataset);
+    DEMresult = DEMDetails::GetDEMValue(lon, lat, *m_Dataset);
     if (DEMresult)
     {
       result += *DEMresult;
@@ -244,7 +231,7 @@ double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat)
 
   if (m_GeoidDS)
   {
-    geoidResult = DEMDetails::GetDEMValue(lon, lat, m_GeoidDS);
+    geoidResult = DEMDetails::GetDEMValue(lon, lat, *m_GeoidDS);
     if (geoidResult)
     {
       result += *geoidResult;
@@ -257,16 +244,16 @@ double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat)
     return m_DefaultHeightAboveEllipsoid;
 }
 
-double DEMHandler::GetHeightAboveEllipsoid(const PointType& geoPoint)
+double DEMHandler::GetHeightAboveEllipsoid(const PointType& geoPoint) const
 {
   return GetHeightAboveEllipsoid(geoPoint[0], geoPoint[1]);
 }
 
-double DEMHandler::GetHeightAboveMSL(double lon, double lat)
+double DEMHandler::GetHeightAboveMSL(double lon, double lat) const
 {
   if (m_Dataset)
   { 
-    auto result = DEMDetails::GetDEMValue(lon, lat, m_Dataset);
+    auto result = DEMDetails::GetDEMValue(lon, lat, *m_Dataset);
     
     if (result)
     {
@@ -277,7 +264,7 @@ double DEMHandler::GetHeightAboveMSL(double lon, double lat)
   return 0;
 }
 
-double DEMHandler::GetHeightAboveMSL(const PointType& geoPoint)
+double DEMHandler::GetHeightAboveMSL(const PointType& geoPoint) const
 {
   return GetHeightAboveMSL(geoPoint[0], geoPoint[1]);
 }
@@ -287,7 +274,7 @@ unsigned int DEMHandler::GetDEMCount() const
   return m_DatasetList.size();
 }
 
-bool DEMHandler::IsValidDEMDirectory(const std::string& DEMDirectory)
+bool DEMHandler::IsValidDEMDirectory(const std::string& DEMDirectory) const
 {
   for (const auto & filename : DEMDetails::GetFilesInDirectory(DEMDirectory))
   {
@@ -338,4 +325,9 @@ void DEMHandler::SetDefaultHeightAboveEllipsoid(double height)
   m_DefaultHeightAboveEllipsoid = height;
 }
 
+double DEMHandler::GetDefaultHeightAboveEllipsoid() const
+{
+  return m_DefaultHeightAboveEllipsoid;
+}
+
 } // namespace otb
diff --git a/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx b/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx
index e9ec0b208b591419f54e313d4dc7acbbc92f1048..31cea8f936eb4198f89ffce5a223febc650beff3 100644
--- a/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx
+++ b/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx
@@ -85,7 +85,7 @@ int otbDisparityMapToDEMFilter(int argc, char* argv[])
   filter->SetElevationMax(atof(argv[8]));
   filter->SetDEMGridStep(atof(argv[10]));
 
-  otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(atof(argv[9]));
+  otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(atof(argv[9]));
 
   MaskReaderType::Pointer maskReader;
   if (argc == 12)
diff --git a/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx b/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx
index 4222bc55dcb46177a08aa23b5d49dbaf9878ba57..f60c12cfeebbf5d654aecbefe806e1cc5a587f1e 100644
--- a/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx
+++ b/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx
@@ -259,7 +259,7 @@ void StereoSensorModelToElevationFilter<TInputImage, TOutputHeight>::BeforeThrea
   this->GetCorrelationOutput()->FillBuffer(0.);
 
   // Initialize with average elevation
-  this->GetOutput()->FillBuffer(otb::DEMHandler::Instance()->GetDefaultHeightAboveEllipsoid());
+  this->GetOutput()->FillBuffer(otb::DEMHandler::GetInstance().GetDefaultHeightAboveEllipsoid());
 
   // Initialize with DEM elevation (not threadable because of some
   // mutex in ossim)
@@ -280,7 +280,7 @@ void StereoSensorModelToElevationFilter<TInputImage, TOutputHeight>::BeforeThrea
 
     // Transform to geo point
     geoPoint = rsTransform->TransformPoint(outputPoint);
-    outputIt.Set(otb::DEMHandler::Instance()->GetHeightAboveEllipsoid(geoPoint));
+    outputIt.Set(otb::DEMHandler::GetInstance().GetHeightAboveEllipsoid(geoPoint));
   }
 
   const InputImageType* masterPtr = this->GetMasterInput();
diff --git a/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx b/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx
index d31a09a94f261e97b81428560cea30adfca17d95..b6f001219adc201df5c1f38a7e962a51355e5a8a 100644
--- a/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx
+++ b/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx
@@ -119,7 +119,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
   m_RightImage->UpdateOutputInformation();
 
   // Setup the DEM handler if needed
-  typename DEMHandler::Pointer demHandler = DEMHandler::Instance();
+  auto & demHandler = DEMHandler::GetInstance();
 
   // Set-up a transform to use the DEMHandler
   typedef otb::GenericRSTransform<> RSTransform2DType;
@@ -156,12 +156,12 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
   outputSpacing[1] *= mean_spacing;
 
   // Then, we retrieve the origin of the left input image
-  double localElevation = otb::DEMHandler::Instance()->GetDefaultHeightAboveEllipsoid();
+  double localElevation = demHandler.GetDefaultHeightAboveEllipsoid();
 
   if (m_UseDEM)
   {
     RSTransform2DType::InputPointType tmpPoint;
-    localElevation = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(m_LeftImage->GetOrigin()));
+    localElevation = demHandler.GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(m_LeftImage->GetOrigin()));
   }
 
   TDPointType leftInputOrigin;
@@ -295,7 +295,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
   this->AllocateOutputs();
 
   // Setup the DEM handler if needed
-  typename DEMHandler::Pointer demHandler = DEMHandler::Instance();
+  auto & demHandler = DEMHandler::GetInstance();
 
   // Set-up a transform to use the DEMHandler
   typedef otb::GenericRSTransform<> RSTransform2DType;
@@ -313,7 +313,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
   TDPointType currentPoint1, currentPoint2, nextLineStart1, nextLineStart2, startLine1, endLine1, startLine2, endLine2, epiPoint1, epiPoint2;
 
   // Then, we retrieve the origin of the left input image
-  double localElevation = otb::DEMHandler::Instance()->GetDefaultHeightAboveEllipsoid();
+  double localElevation = demHandler.GetDefaultHeightAboveEllipsoid();
 
   // Use the mean spacing as before
   double mean_spacing = 0.5 * (std::abs(m_LeftImage->GetSignedSpacing()[0]) + std::abs(m_LeftImage->GetSignedSpacing()[1]));
@@ -325,7 +325,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
     RSTransform2DType::InputPointType tmpPoint;
     tmpPoint[0]    = currentPoint1[0];
     tmpPoint[1]    = currentPoint1[1];
-    localElevation = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
+    localElevation = demHandler.GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
   }
   currentPoint1[2] = localElevation;
   currentPoint2    = m_LeftToRightTransform->TransformPoint(currentPoint1);
@@ -463,7 +463,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
       RSTransform2DType::InputPointType tmpPoint;
       tmpPoint[0]    = currentPoint1[0];
       tmpPoint[1]    = currentPoint1[1];
-      localElevation = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
+      localElevation = demHandler.GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
     }
     currentPoint1[2] = localElevation;
 
@@ -489,7 +489,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
         RSTransform2DType::InputPointType tmpPoint;
         tmpPoint[0]       = nextLineStart1[0];
         tmpPoint[1]       = nextLineStart1[1];
-        nextLineStart1[2] = demHandler->GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
+        nextLineStart1[2] = demHandler.GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
       }
 
 
diff --git a/Modules/Registration/Stereo/test/otbStereoSensorModelToElevationMapFilter.cxx b/Modules/Registration/Stereo/test/otbStereoSensorModelToElevationMapFilter.cxx
index caf1ea271540720ccbc6bade977348a15ed709ad..d3081f75782c1a3a6b23349fcdb9356fb172a49b 100644
--- a/Modules/Registration/Stereo/test/otbStereoSensorModelToElevationMapFilter.cxx
+++ b/Modules/Registration/Stereo/test/otbStereoSensorModelToElevationMapFilter.cxx
@@ -66,8 +66,8 @@ int otbStereoSensorModelToElevationMapFilter(int itkNotUsed(argc), char* argv[])
   gaussian2->SetInput(slaveReader->GetOutput());
   gaussian2->SetVariance(sigma);
 
-  otb::DEMHandler::Instance()->OpenDEMDirectory(argv[4]);
-  otb::DEMHandler::Instance()->OpenGeoidFile(argv[5]);
+  otb::DEMHandler::GetInstance().OpenDEMDirectory(argv[4]);
+  otb::DEMHandler::GetInstance().OpenGeoidFile(argv[5]);
 
   StereoFilterType::Pointer stereoFilter = StereoFilterType::New();
   stereoFilter->SetMasterInput(gaussian1->GetOutput());
diff --git a/Modules/Registration/Stereo/test/otbStereorectificationDisplacementFieldSource.cxx b/Modules/Registration/Stereo/test/otbStereorectificationDisplacementFieldSource.cxx
index e6624576cf60baf00a10a3f3f921d7ba295a130e..d3a73e06d6917d6778615adb800effd01af9e7cf 100644
--- a/Modules/Registration/Stereo/test/otbStereorectificationDisplacementFieldSource.cxx
+++ b/Modules/Registration/Stereo/test/otbStereorectificationDisplacementFieldSource.cxx
@@ -55,7 +55,7 @@ int otbStereorectificationDisplacementFieldSource(int itkNotUsed(argc), char* ar
   dfSource->SetGridStep(gridStep);
   dfSource->SetScale(scale);
 
-  otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(avgElev);
+  otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(avgElev);
 
   WriterType::Pointer writer1 = WriterType::New();
   writer1->SetInput(dfSource->GetLeftDisplacementFieldOutput());
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
index 648de002fcf0b95429aab06274acbe11562d2e2a..33072efb089c4ec94c3e015b7806023ca8f66b48 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx
@@ -99,8 +99,10 @@ void ElevationParametersHandler::AddElevationParameters(Application::Pointer app
 
 void ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(const Application::Pointer app, const std::string& key)
 {
+  auto & demHandler = otb::DEMHandler::GetInstance();
+
   // Set default elevation
-  otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(GetDefaultElevation(app, key));
+  demHandler.SetDefaultHeightAboveEllipsoid(GetDefaultElevation(app, key));
 
 
   std::ostringstream oss;
@@ -113,7 +115,7 @@ void ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(const Ap
   {
     oss.str("");
     oss << "Elevation management: using geoid file (" << GetGeoidFile(app, key) << ")" << std::endl;
-    otb::DEMHandler::Instance()->OpenGeoidFile(GetGeoidFile(app, key));
+    demHandler.OpenGeoidFile(GetGeoidFile(app, key));
     
     app->GetLogger()->Info(oss.str());
   }
@@ -122,11 +124,11 @@ void ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(const Ap
   if (IsDEMUsed(app, key))
   {
     std::string demDirectory = GetDEMDirectory(app, key);
-    if (otb::DEMHandler::Instance()->IsValidDEMDirectory(demDirectory.c_str()))
+    if (demHandler.IsValidDEMDirectory(demDirectory.c_str()))
     {
       oss.str("");
       oss << "Elevation management: using DEM directory (" << demDirectory << ")" << std::endl;
-      otb::DEMHandler::Instance()->OpenDEMDirectory(demDirectory);
+      demHandler.OpenDEMDirectory(demDirectory);
       app->GetLogger()->Info(oss.str());
     }
     else