diff --git a/DDCore/src/plugins/DetectorCheck.cpp b/DDCore/src/plugins/DetectorCheck.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f8283b05e4ad7b63ddf7faae86e1f2d99870f9e
--- /dev/null
+++ b/DDCore/src/plugins/DetectorCheck.cpp
@@ -0,0 +1,680 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "DD4hep/Detector.h"
+#include "DD4hep/Printout.h"
+#include "DD4hep/Factories.h"
+#include "DD4hep/IDDescriptor.h"
+#include "DD4hep/VolumeManager.h"
+#include "DD4hep/DetectorTools.h"
+#include "DD4hep/MatrixHelpers.h"
+#include "DD4hep/AlignmentsNominalMap.h"
+#include "DD4hep/detail/VolumeManagerInterna.h"
+
+// C/C++ include files
+#include <stdexcept>
+#include <algorithm>
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::detail;
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep { namespace detail { namespace tools  {
+      /// Assemble the path of the PlacedVolume selection
+      std::string elementPath(const PlacementPath& nodes, bool reverse= false);
+    } } }
+
+namespace  {
+
+  /// Tool to check the consistency of a detector setup or individual subdetectors
+  /** Tool to check the consistency of a detector setup or individual subdetectors
+   *
+   *  Test the detector setup:
+   *
+   *   - Scan the detectore structure and check DetElements and its placements
+   *
+   *   - Scan the geomeytrical hierarchy and check the volumes and placement
+   *     + optionally the sensitive setup
+   *
+   *   - Scan the volume hierarchy and test the volume manager by scanning 
+   *     the sensitive volumes and checking the correct setup of the
+   *     PhysVolIDs of the placements against the volume manager
+   *
+   *  Other ideas for implementing a proper detector check tool are welcome!
+   *
+   *  @author  M.Frank
+   *  @version 2.0
+   */
+  struct DetectorCheck  {
+    using StructureElements = std::map<DetElement, size_t>;
+    using Chain = detail::tools::PlacementPath;
+    using VolIDs = PlacedVolume::VolIDs;
+
+    /// Helper to scan volume ids
+    struct FND {
+      const string& test;
+      FND(const string& c) : test(c) {}
+      bool operator()(const VolIDs::value_type& c) const { return c.first == test; }
+    };
+
+    Detector&            description;
+    AlignmentsNominalMap m_mapping;
+    DetElement           m_current_detector;
+    SensitiveDetector    m_current_sensitive;
+    IDDescriptor         m_current_iddesc;
+    VolumeManager        m_volMgr;
+    DetElement           m_det;
+    std::string          m_name { "GeometryCheck" };
+
+    size_t               m_placement_errors = 0;
+    size_t               m_placement_elements = 0;
+
+    size_t               m_sensitive_errors = 0;
+    size_t               m_sensitive_elements = 0;
+
+    size_t               m_geometry_elements = 0;
+    size_t               m_geometry_errors = 0;
+
+    size_t               m_structure_errors = 0;
+    StructureElements    m_structure_elements;
+
+    bool check_structure  { false };
+    bool check_geometry   { false };
+    bool check_placements { false };
+    bool check_volmgr     { false };
+    bool check_sensitive  { false };
+
+    SensitiveDetector get_current_sensitive_detector();
+
+    /// Initializing constructor
+    DetectorCheck(Detector& description);
+    /// Default destructor
+    virtual ~DetectorCheck();
+
+    /// Check single volume integrity
+    void checkManagerSingleVolume(DetElement e, PlacedVolume pv, const VolIDs& child_ids, const Chain& chain);
+    /// Walk through tree of volume placements
+    void checkManagerVolumeTree(DetElement e, PlacedVolume pv, VolIDs ids, const Chain& chain, size_t depth, size_t mx_depth);
+
+    /// Check single volume integrity
+    void checkSingleVolume(DetElement e, PlacedVolume pv);
+    /// Walk through tree of volume placements
+    void checkVolumeTree(DetElement e, PlacedVolume pv);
+
+    /// Check DetElement integrity
+    bool checkDetElement(const std::string& path, DetElement detector, PlacedVolume pv);
+    /// Check DetElement tree for integrity
+    bool checkDetElementTree(const std::string& path, DetElement detector, PlacedVolume pv);
+
+    void execute(DetElement sdet, size_t depth);
+
+    /// Action routine to execute the test
+    static long run(Detector& description,int argc,char** argv);
+    static void help(int argc,char** argv);
+  };
+  const char* tag_fail(size_t errs)   {
+    return errs==0 ? "PASSED" : "FAILED";
+  }
+}
+
+
+/// Initializing constructor
+DetectorCheck::DetectorCheck(Detector& desc)
+  : description(desc), m_mapping(desc.world())
+{
+}
+
+SensitiveDetector DetectorCheck::get_current_sensitive_detector()  {
+  DetElement de = m_current_detector;
+  m_current_sensitive = description.sensitiveDetector(de.name());
+  m_current_iddesc = IDDescriptor();
+  if ( m_current_sensitive.isValid() )   {
+    m_current_iddesc = m_current_sensitive.readout().idSpec();
+  }
+  return m_current_sensitive;
+}
+
+void DetectorCheck::execute(DetElement sdet, size_t depth)   {
+  if ( !sdet.isValid() )   {
+    ++m_placement_errors;
+    except("VolumeMgrTest", "The detector element is not known to the geometry.");
+    return;
+  }
+
+  m_det = sdet;
+  m_current_detector = m_det;
+
+  /// Enable sensitive volume checks
+  if ( check_sensitive || check_volmgr )   {
+    if ( m_det == m_det.world() )  {
+      m_current_sensitive = SensitiveDetector();
+      m_current_iddesc = IDDescriptor();
+    }
+    else   {
+      m_current_sensitive = description.sensitiveDetector(m_det.name());
+      if ( !m_current_sensitive.isValid() )   {
+	printout(ERROR, m_name,
+		 "The sensitive detector of subdetector %s "
+		 "is not known to the geometry.", m_det.name());
+	return;
+      }
+      m_current_iddesc = m_current_sensitive.readout().idSpec();
+    }
+  }
+  size_t total_elements = 0;
+  size_t total_errors = 0;
+  /// Execute actions:
+  if ( check_structure )   {
+    PlacedVolume pv  = m_det.placement();
+    checkDetElementTree(m_det.path(), m_det, pv);
+    printout(m_structure_errors > 0 ? ERROR : ALWAYS, 
+	     m_name, "+++ %s: Checked %10ld structure elements.   Num.Errors:%ld (structure test)",
+	     tag_fail(m_structure_errors), m_structure_elements.size(), m_structure_errors);
+    total_elements += m_structure_elements.size();
+    total_errors += m_structure_errors;
+    m_structure_elements.clear();
+    m_structure_errors = 0;
+  }
+
+  if ( check_geometry )   {
+    PlacedVolume pv  = m_det.placement();
+    checkVolumeTree(m_det, pv);
+    if ( check_sensitive )  {
+      printout(m_sensitive_errors > 0 ? ERROR : ALWAYS,
+	       m_name, "+++ %s: Checked %10ld sensitive elements.   Num.Errors:%ld (geometry test)",
+	       tag_fail(m_sensitive_errors), m_sensitive_elements, m_sensitive_errors);
+    }
+    printout(m_geometry_errors > 0 ? ERROR : ALWAYS,
+	     m_name, "+++ %s: Checked %10ld placements.           Num.Errors:%ld (geometry test)",
+	     tag_fail(m_geometry_errors), m_geometry_elements, m_geometry_errors);
+    total_elements += m_sensitive_elements + m_geometry_elements;
+    total_errors += m_sensitive_errors + m_geometry_errors;
+    m_sensitive_errors   = 0;
+    m_sensitive_elements = 0;
+    m_geometry_errors    = 0;
+    m_geometry_elements  = 0;
+  }
+
+  if ( check_volmgr )   {
+    Chain chain;
+    PlacedVolume pv  = m_det.placement();
+    VolIDs       ids = pv.volIDs();
+    chain.emplace_back(pv);
+    m_volMgr = description.volumeManager();
+    if ( !m_volMgr.isValid() )    {
+      printout(ERROR, m_name, "Volume manager is not instantiated. Required for test!");
+      return;
+    }
+    m_sensitive_errors = 0;
+    m_sensitive_elements = 0;
+    checkManagerVolumeTree(m_det, pv, ids, chain, 1, depth);
+    if ( check_sensitive )  {
+      printout(m_sensitive_errors > 0 ? ERROR : ALWAYS,
+	       m_name, "+++ %s: Checked %10ld sensitive elements.   Num.Errors:%ld (phys.VolID test)",
+	       tag_fail(m_sensitive_errors), m_sensitive_elements, m_sensitive_errors);
+    }
+    printout(m_placement_errors > 0 ? ERROR : ALWAYS,
+	     m_name, "+++ %s: Checked %10ld sensitive placements. Num.Errors:%ld (phys.VolID test)",
+	     tag_fail(m_placement_errors), m_sensitive_elements, m_placement_errors);
+    total_elements += m_sensitive_elements + m_placement_elements;
+    total_errors += m_sensitive_errors + m_placement_errors;
+  }
+  total_elements += m_sensitive_elements + m_placement_elements;
+  total_errors += m_sensitive_errors + m_placement_errors;
+  printout(ALWAYS, m_name, "+++ %s: Checked a total of %10ld elements. Num.Errors:%ld (Some elements checked twice)",
+	   tag_fail(total_errors), total_elements, total_errors);
+}
+
+/// Default destructor
+DetectorCheck::~DetectorCheck()   {
+}
+
+/// Check DetElement integrity
+bool DetectorCheck::checkDetElement(const std::string& path, DetElement detector, PlacedVolume pv)   {
+  bool det_valid = true;
+  bool parent_valid = true;
+  bool place_valid = true;
+  bool det_place_valid = true;
+  bool vol_valid = true;
+  auto nerrs = m_structure_errors;
+  const char* de_path = detector.path().c_str();
+
+  if ( !pv.isValid() )   {
+    printout(ERROR, m_name, "Invalid DetElement placement: %s", de_path);
+    ++m_structure_errors;
+    place_valid = false;
+  }
+  if ( detector.path() != path )    {
+    printout(ERROR, m_name, "Invalid DetElement [path mismatch]: %s <> %s",
+	     de_path, path.c_str());
+    ++m_structure_errors;
+  }
+  if ( !detector.parent().isValid() && detector.world() != detector )   {
+    printout(ERROR, m_name, "Invalid DetElement [No parent]:     %s", de_path);
+    ++m_structure_errors;
+    parent_valid = false;
+  }
+  if ( !detector.placement().isValid() )   {
+    printout(ERROR, m_name, "Invalid DetElement [No placement]:  %s", de_path);
+    ++m_structure_errors;
+    det_place_valid = false;
+  }
+  else if ( !detector.volume().isValid() )   {
+    printout(ERROR, m_name, "Invalid DetElement [No volume]:     %s", de_path);
+    ++m_structure_errors;
+    vol_valid = false;
+  }
+  if ( detector.placement().isValid() && detector.placement() != pv )   {
+    printout(ERROR, m_name, "Invalid DetElement [Mismatched placement]:  %s", de_path);
+    ++m_structure_errors;
+    det_place_valid = false;
+  }
+  auto count = ++m_structure_elements[detector];
+  if ( count > 1 )   {
+    DetElement par = detector.parent();
+    printout(ERROR, m_name, "DetElement %s parent: %s is placed %ld times! Only single placement allowed.", 
+	     de_path, par.isValid() ? par.path().c_str() : "", m_structure_elements[detector]);
+    ++m_structure_errors;
+  }
+  Alignment ideal = detector.nominal();
+  if ( !ideal.isValid() )    {
+    printout(ERROR, m_name, "Invalid DetElement [No ideal alignment]: %s", de_path);
+    ++m_structure_errors;
+  }
+  Alignment survey = detector.survey();
+  if ( !survey.isValid() )    {
+    printout(ERROR, m_name, "Invalid DetElement [No survey alignment]: %s", de_path);
+    ++m_structure_errors;
+  }
+  if ( ideal.isValid() )    {
+    const TGeoHMatrix& m = ideal.worldTransformation();
+    if ( m.IsIdentity() )  {
+    }
+  }
+  printout(nerrs != m_structure_errors ? ERROR : INFO, m_name, 
+	   "DetElement %s [%s] parent: %s placement: %s [%s] volume: %s",
+	   path.c_str(), yes_no(det_valid), yes_no(parent_valid), yes_no(det_place_valid),
+	   yes_no(place_valid), yes_no(vol_valid));
+  return nerrs == m_structure_errors;
+}
+
+/// Check DetElement tree for integrity
+bool DetectorCheck::checkDetElementTree(const std::string& path, DetElement detector, PlacedVolume pv)   {
+  auto nerrs = m_structure_errors;
+  if ( !detector.isValid() )   {
+    printout(ERROR, m_name, "Invalid DetElement seen: %s", path.c_str());
+    ++m_structure_errors;
+    return false;
+  }
+  bool is_world = detector == detector.world();
+  /// Check single DetElement object
+  checkDetElement(path, detector, pv);
+  /// Recurse the tree
+  for ( const auto& c : detector.children() )   {
+    DetElement de = c.second;
+    if ( is_world )   {
+      m_current_sensitive = SensitiveDetector();
+      m_current_iddesc = IDDescriptor();
+      m_current_detector = de;
+    }
+    if ( de.parent().isValid() && de.parent() != detector )    {
+      printout(ERROR, m_name, "Invalid DetElement [Parent mismatch]:    %s", de.path().c_str());
+      printout(ERROR, m_name, "        apparent parent: %s  structural parent: %s",
+	       de.parent().path().c_str(), detector.path().c_str());
+      ++m_structure_errors;
+    }
+    /// Invalid daughter elements will be detectoed in there:
+    checkDetElementTree(path + "/" + c.first, de, de.placement());
+  }
+  return nerrs == m_structure_errors;
+}
+
+/// Check single volume integrity
+void DetectorCheck::checkSingleVolume(DetElement e, PlacedVolume pv)   {
+
+  ++m_geometry_elements;
+  /// Check DetElement validity
+  if ( !e.isValid() )   {
+    printout(ERROR, m_name, "Invalid DetElement [Invalid handle]");
+    ++m_geometry_errors;
+  }
+  /// Check placement validity
+  if ( !pv.isValid() )   {
+    printout(ERROR, m_name, "Invalid PlacedVolume [Invalid handle] DetElement: %s", e.path().c_str());
+    ++m_geometry_errors;
+  }
+  Volume vol = pv.volume();
+  /// Check volume validity
+  if ( !vol.isValid() )   {
+    printout(ERROR, m_name, "Invalid Volume [Invalid handle] DetElement: %s", e.path().c_str());
+    ++m_geometry_errors;
+    return;
+  }
+  /// Check sensitive settings for sensitive volumes
+  if ( check_sensitive && vol.isSensitive() )    {
+    SensitiveDetector sdv = vol.sensitiveDetector();
+    ++m_sensitive_elements;
+    if ( !sdv.isValid() )   {
+      printout(ERROR, m_name, "Invalid SensitiveDetector DetElement: %s", e.path().c_str());
+      ++m_sensitive_errors;
+    } 
+    SensitiveDetector sdd = get_current_sensitive_detector();
+    if ( sdd != sdv )   {
+      printout(ERROR, m_name, "Inconsistent sensitive detectors for DetElement: %s", e.path().c_str());
+      ++m_sensitive_errors;
+    }
+  }
+}
+
+/// Walk through tree of volume placements
+void DetectorCheck::checkVolumeTree(DetElement e, PlacedVolume pv)   {
+  const TGeoNode* current  = pv.ptr();
+  TObjArray*  nodes        = current->GetNodes();
+  int         num_children = nodes ? nodes->GetEntriesFast() : 0;
+  
+  /// Check single volume object
+  checkSingleVolume(e, pv);
+  /// Recurse the tree
+  for(int i=0; i<num_children; ++i)   {
+    TGeoNode* node = (TGeoNode*)nodes->At(i);
+    PlacedVolume place(node);
+    DetElement de = e;
+    /// Check if there is a new parent at the next level:
+    for ( const auto& c : e.children() )   {
+      if ( c.second.placement() == place )   {
+	de = c.second;
+	break;
+      }
+    }
+    checkVolumeTree(de, place);
+  }
+}
+
+/// Check volume integrity
+void DetectorCheck::checkManagerSingleVolume(DetElement detector, PlacedVolume pv, const VolIDs& child_ids, const Chain& chain)   {
+  stringstream err, log;
+  VolumeID     det_vol_id = detector.volumeID();
+  VolumeID     vid        = det_vol_id;
+  DetElement   top_sdet, det_elem;
+  VolumeManagerContext* mgr_ctxt = 0;
+  
+  ++m_placement_elements;
+
+  try {
+    vid       = m_current_iddesc.encode(child_ids);
+    top_sdet  = m_volMgr.lookupDetector(vid);
+    det_elem  = m_volMgr.lookupDetElement(vid);
+    mgr_ctxt  = m_volMgr.lookupContext(vid);
+
+    if ( pv.volume().isSensitive() )  {
+      PlacedVolume det_place = m_volMgr.lookupDetElementPlacement(vid);
+      ++m_sensitive_elements;
+      if ( pv.ptr() != det_place.ptr() )   {
+        err << "VolumeMgrTest: Wrong placement "
+            << " got "        << det_place.name() << " (" << (void*)det_place.ptr() << ")"
+            << " instead of " << pv.name()        << " (" << (void*)pv.ptr()        << ") "
+            << " vid:" << volumeID(vid);
+        ++m_placement_errors;
+      }
+      else if ( top_sdet.ptr() != detector.ptr() )   {
+        top_sdet  = m_volMgr.lookupDetector(vid);
+        err << "VolumeMgrTest: Wrong associated sub-detector element vid="  << volumeID(vid)
+            << " got "        << top_sdet.path() << " (" << (void*)top_sdet.ptr() << ") "
+            << " instead of " << detector.path() << " (" << (void*)detector.ptr() << ")"
+            << " vid:" << volumeID(vid);
+        ++m_placement_errors;
+      }
+      else if ( !detail::tools::isParentElement(detector,det_elem) )   {
+      // This is sort of a bit wischi-waschi.... 
+        err << "VolumeMgrTest: Wrong associated detector element vid="  << volumeID(vid)
+            << " got "        << det_elem.path() << " (" << (void*)det_elem.ptr() << ") "
+            << " instead of " << detector.path() << " (" << (void*)detector.ptr() << ")"
+            << " vid:" << volumeID(vid);
+        ++m_placement_errors;
+      }
+      else if ( top_sdet.ptr() != m_det.ptr() )   {
+        err << "VolumeMgrTest: Wrong associated detector "
+            << " vid:" << volumeID(vid);
+        ++m_placement_errors;
+      }
+    }
+  }
+  catch(const exception& ex) {
+    err << "Lookup " << pv.name() << " id:" << volumeID(vid)
+        << " path:" << detector.path() << " error:" << ex.what();
+    ++m_placement_errors;
+  }
+
+  if ( pv.volume().isSensitive() || (0 != det_vol_id) )  {
+    string id_desc;
+    log << "Volume:"  << setw(50) << left << pv.name();
+    if ( pv.volume().isSensitive() )  {
+      IDDescriptor dsc = SensitiveDetector(pv.volume().sensitiveDetector()).readout().idSpec();
+      log << " IDDesc:" << (char*)(dsc.ptr() == m_current_iddesc.ptr() ? "OK " : "BAD");
+      if ( dsc.ptr() != m_current_iddesc.ptr() ) ++m_placement_errors;
+    }
+    else  {
+      log << setw(11) << " ";
+    }
+    id_desc = m_current_iddesc.str(vid);
+    log << " [" << char(pv.volume().isSensitive() ? 'S' : 'N') << "] " << right
+        << " vid:" << volumeID(vid)
+        << " " << id_desc;
+    if ( !err.str().empty() )   {
+      printout(ERROR, m_det.name(),err.str()+" "+log.str());
+      //throw runtime_error(err.str());
+      return;
+    }
+    id_desc = m_current_iddesc.str(det_elem.volumeID());
+    printout(INFO, m_det.name(),log.str());
+    printout(INFO, m_det.name(), "  Elt:%-64s    vid:%s %s Parent-OK:%3s",
+             det_elem.path().c_str(),volumeID(det_elem.volumeID()).c_str(),
+             id_desc.c_str(),
+             yes_no(detail::tools::isParentElement(detector,det_elem)));
+
+    try  {
+      if ( pv.volume().isSensitive() )  {
+        TGeoHMatrix trafo;
+        for (size_t i = chain.size()-1; i > 0; --i)  {
+          //for (size_t i = 0; i<chain.size(); ++i )  {
+          const TGeoMatrix* mat = chain[i]->GetMatrix();
+          trafo.MultiplyLeft(mat);
+        }
+        for (size_t i = chain.size(); i > 0; --i)  {
+          const TGeoMatrix* mat = chain[i-1]->GetMatrix();
+          if ( printLevel() <= INFO )  {
+            ::printf("Placement [%d]  VolID:%s\t\t",int(i),chain[i-1].volIDs().str().c_str());
+            mat->Print();
+          }
+        }
+        det_elem  = m_volMgr.lookupDetElement(vid);
+        if ( printLevel() <= INFO )  {
+          ::printf("Computed Trafo (from placements):\t\t");
+          trafo.Print();
+          ::printf("DetElement Trafo: %s [%s]\t\t",
+                   det_elem.path().c_str(),volumeID(det_elem.volumeID()).c_str());
+          det_elem.nominal().worldTransformation().Print();
+          ::printf("VolumeMgr  Trafo: %s [%s]\t\t",det_elem.path().c_str(),volumeID(vid).c_str());
+          m_volMgr.worldTransformation(m_mapping,vid).Print();
+        }
+        
+        /// Check volume manager context
+        if ( 0 == mgr_ctxt )  {
+          printout(ERROR, m_det.name(), "VOLUME_MANAGER FAILED: Could not find entry for vid:%s.",
+                   volumeID(vid).c_str());
+          ++m_placement_errors;
+        }
+
+        /// Check nominal and DetElement trafos for pointer equality:
+        if ( &det_elem.nominal().worldTransformation() != &m_volMgr.worldTransformation(m_mapping,det_elem.volumeID()) )
+        {
+            printout(ERROR, m_det.name(), "DETELEMENT_PERSISTENCY FAILED: World transformation have DIFFERET pointer!");
+          ++m_placement_errors;
+        }
+        
+        if ( pv.ptr() == det_elem.placement().ptr() )   {
+          // The computed transformation 'trafo' MUST be equal to:
+          // m_volMgr.worldTransformation(vid) AND det_elem.nominal().worldTransformation()
+          int res1 = detail::matrix::_matrixEqual(trafo, det_elem.nominal().worldTransformation());
+          int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid));
+          if ( res1 != detail::matrix::MATRICES_EQUAL || res2 != detail::matrix::MATRICES_EQUAL )  {
+            printout(ERROR, m_det.name(), "DETELEMENT_PLACEMENT FAILED: World transformation DIFFER.");
+            ++m_placement_errors;
+          }
+          else  {
+            printout(INFO, m_det.name(), "DETELEMENT_PLACEMENT: PASSED. All matrices equal: %s",
+                     volumeID(vid).c_str());
+          }
+        }
+        else  {
+          // The computed transformation 'trafo' MUST be equal to:
+          // m_volMgr.worldTransformation(vid)
+          // The det_elem.nominal().worldTransformation() however is DIFFERENT!
+          int res2 = detail::matrix::_matrixEqual(trafo, m_volMgr.worldTransformation(m_mapping,vid));
+          if ( res2 != detail::matrix::MATRICES_EQUAL )  {
+            printout(ERROR, m_det.name(), "VOLUME_PLACEMENT FAILED: World transformation DIFFER.");
+            ++m_placement_errors;
+          }
+          else  {
+            printout(INFO, m_det.name(), "VOLUME_PLACEMENT: PASSED. All matrices equal: %s",
+                     volumeID(vid).c_str());
+          }
+        }
+      }
+    }
+    catch(const exception& ex) {
+      err << "Matrix " << pv.name() << " id:" << volumeID(vid)
+          << " path:" << detector.path() << " error:" << ex.what();
+      ++m_placement_errors;
+    }
+    
+  }
+}
+
+/// Walk through tree of detector elements
+void DetectorCheck::checkManagerVolumeTree(DetElement detector, PlacedVolume pv, VolIDs ids, const Chain& chain,
+                           size_t depth, size_t mx_depth)  
+{
+  if ( depth <= mx_depth )  {
+    const TGeoNode* current  = pv.ptr();
+    TObjArray*  nodes        = current->GetNodes();
+    int         num_children = nodes ? nodes->GetEntriesFast() : 0;
+
+    for(int i=0; i<num_children; ++i)   {
+      TGeoNode* node = (TGeoNode*)nodes->At(i);
+      PlacedVolume place(node);
+      VolIDs child_ids(ids);
+      Chain  child_chain(chain);
+
+      place.access(); // Test validity
+      child_chain.emplace_back(place);
+      child_ids.insert(child_ids.end(), place.volIDs().begin(), place.volIDs().end());
+      //bool is_sensitive = place.volume().isSensitive();
+      //if ( is_sensitive || !child_ids.empty() )  {
+      checkManagerSingleVolume(detector, place, child_ids, child_chain);
+      //}
+      checkManagerVolumeTree(detector, place, child_ids, child_chain, depth+1, mx_depth);
+    }
+  }
+}
+
+void DetectorCheck::help(int argc,char** argv)   {
+  std::cout
+    << 
+    "DD4hep_DetectorCheck -option [-option]                                         \n"
+    "  -name  <subdetector name>    Name of the subdetector to be checked           \n"
+    "                               \"ALL\" or \"all\": loop over known subdetectors\n"
+    "                               \"world\" start from the mother of all...       \n"
+    "  -structure                   Check structural tree consistency               \n"
+    "  -geometry                    Check geometry tree consistency                 \n"
+    "  -sensitve                    Check consistency between detector and volume   \n"
+    "                               settings of sensitive detectors.                \n"
+    "  -volmgr                      Check volume manager entries against volIDs of  \n"
+    "                               sensitive volume placements.                  \n\n"
+    "                               NOTE: Option requires proper PhysVolID setup    \n"
+    "                               of the sensitive volume placements !            \n"
+    "  -help                        Print this help message                         \n"
+    << std::endl;
+  std::cout << "Arguments: " << std::endl;
+  for(int iarg=0; iarg<argc;++iarg)  {
+    std::cout << "Argument[" << iarg << "]  = " << argv[iarg] << std::endl;
+  }
+  ::_exit(EINVAL);
+}
+
+/// Action routine to execute the test
+long DetectorCheck::run(Detector& description,int argc,char** argv)    {
+  string name;
+  bool volmgr = false;
+  bool geometry = false;
+  bool structure = false;
+  bool sensitive = false;
+  bool placements = false;
+  printout(ALWAYS, "DD4hepVolumeMgrTest", "++ Processing plugin...");
+  for(int iarg=0; iarg<argc;++iarg)  {
+    if ( argv[iarg] == 0 ) break;
+    if ( ::strncasecmp(argv[iarg], "-name",4) == 0 && (iarg+1) < argc )
+      name = argv[++iarg];
+    else if ( ::strncasecmp(argv[iarg], "-structure",4) == 0 )
+      structure = true;
+    else if ( ::strncasecmp(argv[iarg], "-placements",4) == 0 )
+      placements = true;
+    else if ( ::strncasecmp(argv[iarg], "-volmgr",4) == 0 )
+      volmgr = true;
+    else if ( ::strncasecmp(argv[iarg], "-geometry",4) == 0 )
+      geometry = true;
+    else if ( ::strncasecmp(argv[iarg], "-sensitive",4) == 0 )
+      sensitive = true;
+    else if ( ::strncasecmp(argv[iarg], "-help",4) == 0 )
+      help(argc, argv);
+    else
+      help(argc, argv);
+  }
+  if ( argc == 0 ) help(argc, argv);
+  if ( !name.empty() )   {
+    DetectorCheck test(description);
+    if ( name == "all" || name == "All" || name == "ALL" )  {
+      for (const auto& det : description.detectors() )  {
+        printout(INFO, "DD4hepVolumeMgrTest", "++ Processing subdetector: %s", det.second.name());
+	test.check_structure  = structure;
+	test.check_placements = placements;
+	test.check_volmgr     = volmgr;
+	test.check_geometry   = geometry;
+	test.check_sensitive  = sensitive;
+	test.execute(det.second, 9999);
+      }
+      return 1;
+    }
+    DetElement det = (::strcasecmp(name.c_str(), "world") == 0)
+      ? description.world() : description.detector(name);
+    printout(INFO, "DD4hepVolumeMgrTest", "++ Processing subdetector: %s",name.c_str());
+    test.check_structure  = structure;
+    test.check_placements = placements;
+    test.check_volmgr     = volmgr;
+    test.check_geometry   = geometry;
+    test.check_sensitive  = sensitive;
+    test.execute(det, 9999);
+  }
+  return 1;
+}
+
+DECLARE_APPLY(DD4hep_DetectorCheck,DetectorCheck::run)
+
+/// Action routine to execute the test for backwards compatibility
+long run_VolumeMgrTest(Detector& description,int argc, const char*const* argv)    {
+  const char* args[] = {"-name", argc > 0 ? argv[0] : "world", "-structure", "-geometry", "-volmgr", 0 };
+  return DetectorCheck::run(description, 6, (char**)args); 
+}
+DECLARE_APPLY(DD4hep_VolumeMgrTest,run_VolumeMgrTest)
diff --git a/DDCore/src/plugins/VolumeMgrTest.cpp b/DDCore/src/plugins/VolumeMgrTest.cpp
deleted file mode 100644
index 7cb265decab6d909df5df9755f6dfa61deb852b2..0000000000000000000000000000000000000000
--- a/DDCore/src/plugins/VolumeMgrTest.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-//==========================================================================
-//  AIDA Detector description implementation 
-//--------------------------------------------------------------------------
-// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
-// All rights reserved.
-//
-// For the licensing terms see $DD4hepINSTALL/LICENSE.
-// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
-//
-// Author     : M.Frank
-//
-//==========================================================================
-
-// Framework include files
-#include "DD4hep/Detector.h"
-#include "DD4hep/Printout.h"
-#include "DD4hep/Factories.h"
-#include "DD4hep/IDDescriptor.h"
-#include "DD4hep/VolumeManager.h"
-#include "DD4hep/DetectorTools.h"
-#include "DD4hep/MatrixHelpers.h"
-#include "DD4hep/AlignmentsNominalMap.h"
-#include "DD4hep/detail/VolumeManagerInterna.h"
-
-// C/C++ include files
-#include <stdexcept>
-#include <algorithm>
-
-using namespace std;
-using namespace dd4hep;
-using namespace dd4hep::detail;
-
-namespace  {
-  /** @class VolIDTest
-   *
-   *  Test the volume manager by scanning the sensitive
-   *  volumes of one or several subdetectors.
-   *
-   *  @author  M.Frank
-   *  @version 1.0
-   */
-  struct VolIDTest  {
-    typedef detail::tools::PlacementPath     Chain;
-    typedef PlacedVolume::VolIDs             VolIDs;
-
-    /// Helper to scan volume ids
-    struct FND {
-      const string& test;
-      FND(const string& c) : test(c) {}
-      bool operator()(const VolIDs::value_type& c) const { return c.first == test; }
-    };
-    AlignmentsNominalMap m_mapping;
-    IDDescriptor  m_iddesc;
-    VolumeManager m_mgr;
-    DetElement    m_det;
-    size_t        m_errors = 0;
-    size_t        m_elements = 0;
-    /// Initializing constructor
-    VolIDTest(Detector& description, DetElement sdet, size_t depth);
-    /// Default destructor
-    virtual ~VolIDTest();
-    /// Check volume integrity
-    void checkVolume(DetElement e, PlacedVolume pv, const VolIDs& child_ids, const Chain& chain);
-    /// Walk through tree of detector elements
-    //void walk(DetElement de, VolIDs ids, const Chain& chain, size_t depth, size_t mx_depth)  const;
-    /// Walk through tree of volume placements
-    void walkVolume(DetElement e, PlacedVolume pv, VolIDs ids, const Chain& chain, size_t depth, size_t mx_depth);
-
-    /// Action routine to execute the test
-    static long run(Detector& description,int argc,char** argv);
-  };
-}
-
-/// Initializing constructor
-VolIDTest::VolIDTest(Detector& description, DetElement sdet, size_t depth) : m_mapping(description.world()), m_det(sdet) {
-  m_mgr = description.volumeManager();
-  if ( !m_det.isValid() )   {
-    stringstream err;
-    ++m_errors;
-    err << "The subdetector " << m_det.name() << " is not known to the geometry.";
-    except("VolumeMgrTest",err.str().c_str());
-    throw runtime_error(err.str());
-  }
-  if ( !description.sensitiveDetector(m_det.name()).isValid() )   {
-    stringstream err;
-    ++m_errors;
-    err << "The sensitive detector of subdetector " << m_det.name()
-        << " is not known to the geometry.";
-    printout(ERROR,"VolumeMgrTest",err.str().c_str());
-    //throw runtime_error(err.str());
-    return;
-  }
-  m_iddesc = description.sensitiveDetector(m_det.name()).readout().idSpec();
-  //walk(m_det,VolIDs(),Chain(),0,depth);
-  PlacedVolume pv  = sdet.placement();
-  VolIDs       ids = pv.volIDs();
-  Chain        chain;
-  chain.emplace_back(pv);
-  checkVolume(sdet, pv, ids, chain);
-  walkVolume(sdet, pv, ids, chain, 1, depth);
-}
-
-/// Default destructor
-VolIDTest::~VolIDTest()   {
-  if ( m_errors == 0 )
-    printout(ALWAYS,"VolIDTest","+++ PASSED: Checked %ld objects. Num.Errors:%ld",
-             m_elements, m_errors);
-  else
-    printout(ALWAYS,"VolIDTest","+++ FAILED: Checked %ld objects. Num.Errors:%ld",
-             m_elements, m_errors);
-}
-
-/// Check volume integrity
-void VolIDTest::checkVolume(DetElement detector, PlacedVolume pv, const VolIDs& child_ids, const Chain& chain)   {
-  stringstream err, log;
-  VolumeID     det_vol_id = detector.volumeID();
-  VolumeID     vid = det_vol_id;
-  DetElement   top_sdet, det_elem;
-  VolumeManagerContext* mgr_ctxt = 0;
-  
-  ++m_elements;
-
-  try {
-    vid       = m_iddesc.encode(child_ids);
-    top_sdet  = m_mgr.lookupDetector(vid);
-    det_elem  = m_mgr.lookupDetElement(vid);
-    mgr_ctxt  = m_mgr.lookupContext(vid);
-
-    if ( pv.volume().isSensitive() )  {
-      PlacedVolume det_place = m_mgr.lookupDetElementPlacement(vid);
-      if ( pv.ptr() != det_place.ptr() )   {
-        err << "VolumeMgrTest: Wrong placement "
-            << " got "        << det_place.name() << " (" << (void*)det_place.ptr() << ")"
-            << " instead of " << pv.name()        << " (" << (void*)pv.ptr()        << ") "
-            << " vid:" << volumeID(vid);
-        ++m_errors;
-      }
-      else if ( top_sdet.ptr() != detector.ptr() )   {
-        top_sdet  = m_mgr.lookupDetector(vid);
-        err << "VolumeMgrTest: Wrong associated sub-detector element vid="  << volumeID(vid)
-            << " got "        << top_sdet.path() << " (" << (void*)top_sdet.ptr() << ") "
-            << " instead of " << detector.path() << " (" << (void*)detector.ptr() << ")"
-            << " vid:" << volumeID(vid);
-        ++m_errors;
-      }
-      else if ( !detail::tools::isParentElement(detector,det_elem) )   {
-      // This is sort of a bit wischi-waschi.... 
-        err << "VolumeMgrTest: Wrong associated detector element vid="  << volumeID(vid)
-            << " got "        << det_elem.path() << " (" << (void*)det_elem.ptr() << ") "
-            << " instead of " << detector.path() << " (" << (void*)detector.ptr() << ")"
-            << " vid:" << volumeID(vid);
-        ++m_errors;
-      }
-      else if ( top_sdet.ptr() != m_det.ptr() )   {
-        err << "VolumeMgrTest: Wrong associated detector "
-            << " vid:" << volumeID(vid);
-        ++m_errors;
-      }
-    }
-  }
-  catch(const exception& ex) {
-    err << "Lookup " << pv.name() << " id:" << volumeID(vid)
-        << " path:" << detector.path() << " error:" << ex.what();
-    ++m_errors;
-  }
-
-  if ( pv.volume().isSensitive() || (0 != det_vol_id) )  {
-    string id_desc;
-    log << "Volume:"  << setw(50) << left << pv.name();
-    if ( pv.volume().isSensitive() )  {
-      IDDescriptor dsc = SensitiveDetector(pv.volume().sensitiveDetector()).readout().idSpec();
-      log << " IDDesc:" << (char*)(dsc.ptr() == m_iddesc.ptr() ? "OK " : "BAD");
-      if ( dsc.ptr() != m_iddesc.ptr() ) ++m_errors;
-    }
-    else  {
-      log << setw(11) << " ";
-    }
-    id_desc = m_iddesc.str(vid);
-    log << " [" << char(pv.volume().isSensitive() ? 'S' : 'N') << "] " << right
-        << " vid:" << volumeID(vid)
-        << " " << id_desc;
-    if ( !err.str().empty() )   {
-      printout(ERROR,m_det.name(),err.str()+" "+log.str());
-      //throw runtime_error(err.str());
-      return;
-    }
-    id_desc = m_iddesc.str(det_elem.volumeID());
-    printout(INFO,m_det.name(),log.str());
-    printout(INFO,m_det.name(),"  Elt:%-64s    vid:%s %s Parent-OK:%3s",
-             det_elem.path().c_str(),volumeID(det_elem.volumeID()).c_str(),
-             id_desc.c_str(),
-             yes_no(detail::tools::isParentElement(detector,det_elem)));
-
-    try  {
-      if ( pv.volume().isSensitive() )  {
-        TGeoHMatrix trafo;
-        for (size_t i = chain.size()-1; i > 0; --i)  {
-          //for (size_t i = 0; i<chain.size(); ++i )  {
-          const TGeoMatrix* mat = chain[i]->GetMatrix();
-          trafo.MultiplyLeft(mat);
-        }
-        for (size_t i = chain.size(); i > 0; --i)  {
-          const TGeoMatrix* mat = chain[i-1]->GetMatrix();
-          if ( printLevel() <= INFO )  {
-            ::printf("Placement [%d]  VolID:%s\t\t",int(i),chain[i-1].volIDs().str().c_str());
-            mat->Print();
-          }
-        }
-        det_elem  = m_mgr.lookupDetElement(vid);
-        if ( printLevel() <= INFO )  {
-          ::printf("Computed Trafo (from placements):\t\t");
-          trafo.Print();
-          ::printf("DetElement Trafo: %s [%s]\t\t",
-                   det_elem.path().c_str(),volumeID(det_elem.volumeID()).c_str());
-          det_elem.nominal().worldTransformation().Print();
-          ::printf("VolumeMgr  Trafo: %s [%s]\t\t",det_elem.path().c_str(),volumeID(vid).c_str());
-          m_mgr.worldTransformation(m_mapping,vid).Print();
-        }
-        
-        /// Check volume manager context
-        if ( 0 == mgr_ctxt )  {
-          printout(ERROR,m_det.name(),"VOLUME_MANAGER FAILED: Could not find entry for vid:%s.",
-                   volumeID(vid).c_str());
-          ++m_errors;
-        }
-
-        /// Check nominal and DetElement trafos for pointer equality:
-        if ( &det_elem.nominal().worldTransformation() != &m_mgr.worldTransformation(m_mapping,det_elem.volumeID()) )
-        {
-            printout(ERROR,m_det.name(),"DETELEMENT_PERSISTENCY FAILED: World transformation have DIFFERET pointer!");
-          ++m_errors;
-        }
-        
-        if ( pv.ptr() == det_elem.placement().ptr() )   {
-          // The computed transformation 'trafo' MUST be equal to:
-          // m_mgr.worldTransformation(vid) AND det_elem.nominal().worldTransformation()
-          int res1 = detail::matrix::_matrixEqual(trafo, det_elem.nominal().worldTransformation());
-          int res2 = detail::matrix::_matrixEqual(trafo, m_mgr.worldTransformation(m_mapping,vid));
-          if ( res1 != detail::matrix::MATRICES_EQUAL || res2 != detail::matrix::MATRICES_EQUAL )  {
-            printout(ERROR,m_det.name(),"DETELEMENT_PLACEMENT FAILED: World transformation DIFFER.");
-            ++m_errors;
-          }
-          else  {
-            printout(INFO,m_det.name(),"DETELEMENT_PLACEMENT: PASSED. All matrices equal: %s",
-                     volumeID(vid).c_str());
-          }
-        }
-        else  {
-          // The computed transformation 'trafo' MUST be equal to:
-          // m_mgr.worldTransformation(vid)
-          // The det_elem.nominal().worldTransformation() however is DIFFERENT!
-          int res2 = detail::matrix::_matrixEqual(trafo, m_mgr.worldTransformation(m_mapping,vid));
-          if ( res2 != detail::matrix::MATRICES_EQUAL )  {
-            printout(ERROR,m_det.name(),"VOLUME_PLACEMENT FAILED: World transformation DIFFER.");
-            ++m_errors;
-          }
-          else  {
-            printout(INFO,m_det.name(),"VOLUME_PLACEMENT: PASSED. All matrices equal: %s",
-                     volumeID(vid).c_str());
-          }
-        }
-      }
-    }
-    catch(const exception& ex) {
-      err << "Matrix " << pv.name() << " id:" << volumeID(vid)
-          << " path:" << detector.path() << " error:" << ex.what();
-      ++m_errors;
-    }
-    
-  }
-}
-
-/// Walk through tree of detector elements
-void VolIDTest::walkVolume(DetElement detector, PlacedVolume pv, VolIDs ids, const Chain& chain,
-                           size_t depth, size_t mx_depth)  
-{
-  if ( depth <= mx_depth )  {
-    const TGeoNode* current  = pv.ptr();
-    TObjArray*  nodes        = current->GetNodes();
-    int         num_children = nodes ? nodes->GetEntriesFast() : 0;
-
-    for(int i=0; i<num_children; ++i)   {
-      TGeoNode* node = (TGeoNode*)nodes->At(i);
-      PlacedVolume place(node);
-      VolIDs child_ids(ids);
-      Chain  child_chain(chain);
-
-      place.access(); // Test validity
-      child_chain.emplace_back(place);
-      child_ids.insert(child_ids.end(), place.volIDs().begin(), place.volIDs().end());
-      //bool is_sensitive = place.volume().isSensitive();
-      //if ( is_sensitive || !child_ids.empty() )  {
-      checkVolume(detector, place, child_ids, child_chain);
-      //}
-      walkVolume(detector, place, child_ids, child_chain, depth+1, mx_depth);
-    }
-  }
-}
-
-/// Action routine to execute the test
-long VolIDTest::run(Detector& description,int argc,char** argv)    {
-  printout(ALWAYS,"DD4hepVolumeMgrTest","++ Processing plugin...");
-  for(int iarg=0; iarg<argc;++iarg)  {
-    if ( argv[iarg] == 0 ) break;
-    string name = argv[iarg];
-    if ( name == "all" || name == "All" || name == "ALL" )  {
-      const DetElement::Children& children = description.world().children();
-      for (DetElement::Children::const_iterator i=children.begin(); i!=children.end(); ++i)  {
-        DetElement sdet = (*i).second;
-        printout(INFO,"DD4hepVolumeMgrTest","++ Processing subdetector: %s",sdet.name());
-        VolIDTest test(description,sdet,99);
-      }
-      return 1;
-    }
-    DetElement sdet = description.detector(name);
-    if ( !sdet.isValid() )   {
-      except("VolumeMgrTest","++ Unknwon top level subdetector: %s",name.c_str());
-    }
-    printout(INFO,"DD4hepVolumeMgrTest","++ Processing subdetector: %s",name.c_str());
-    VolIDTest test(description,sdet,99);
-  }
-  return 1;
-}
-
-DECLARE_APPLY(DD4hep_VolumeMgrTest,VolIDTest::run)
diff --git a/examples/ClientTests/CMakeLists.txt b/examples/ClientTests/CMakeLists.txt
index eeaddde26fcc760fea73dc6f347c406cecc12865..742c2d75e4c98d62eed412467f253bae2aa09e8d 100644
--- a/examples/ClientTests/CMakeLists.txt
+++ b/examples/ClientTests/CMakeLists.txt
@@ -146,7 +146,7 @@ dd4hep_add_test_reg( ClientTests_MultiPlace
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
   EXEC_ARGS  geoPluginRun
   -input file:${ClientTestsEx_INSTALL}/compact/SiBarrelMultiSensitiveLongVolID.xml -volmgr -destroy
-  -plugin DD4hep_VolumeMgrTest SiTrackerBarrel
+  -plugin DD4hep_DetectorCheck -name SiTrackerBarrel -geometry -structure -volmgr -sensitive
 
   REGEX_PASS "Volume:component1_1                                       IDDesc:OK  \\[S\\]  vid:00200668000000ff system:00ff barrel:0000 layer:0001 module:0033 sensor:0001"
   REGEX_FAIL "FAILED: World transformation DIFFER"
@@ -157,7 +157,7 @@ dd4hep_add_test_reg( ClientTests_Bitfield64_LongVoldID
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
   EXEC_ARGS  geoPluginRun
   -input file:${ClientTestsEx_INSTALL}/compact/SiBarrelMultiSensitiveLongVolID.xml -volmgr -destroy
-  -plugin DD4hep_VolumeMgrTest SiTrackerBarrel
+  -plugin DD4hep_DetectorCheck -name SiTrackerBarrel -geometry -structure -volmgr -sensitive
 
   REGEX_PASS "Volume:component1_1                                       IDDesc:OK  \\[S\\]  vid:00200668000000ff system:00ff barrel:0000 layer:0001 module:0033 sensor:0001"
   REGEX_FAIL "FAILED: World transformation DIFFER"
@@ -170,7 +170,7 @@ dd4hep_add_test_reg( ClientTests_Bitfield64_BarrelSides
   -input file:${ClientTestsEx_INSTALL}/compact/Bitfield_SidesTest.xml -volmgr -destroy
   -plugin DD4hep_DetectorVolumeDump
   -plugin DD4hep_VolumeDump volids
-  -plugin DD4hep_VolumeMgrTest all
+  -plugin DD4hep_DetectorCheck -name all -geometry -structure -volmgr -sensitive
   REGEX_PASS "Volume:Shell_2                                            IDDesc:OK  \\[S\\]  vid:0000000000000102 system:0002 barrel:0001")
 #
 #  Test readout strings of the form: <id>system:16,barrel:16:-5</id>
@@ -180,7 +180,7 @@ dd4hep_add_test_reg( ClientTests_Bitfield64_BarrelSides2
   -input file:${ClientTestsEx_INSTALL}/compact/Bitfield_SidesTest2.xml -volmgr -destroy
   -plugin DD4hep_DetectorVolumeDump
   -plugin DD4hep_VolumeDump volids
-  -plugin DD4hep_VolumeMgrTest all
+  -plugin DD4hep_DetectorCheck -name all -geometry -structure -volmgr -sensitive
   REGEX_PASS "Volume:Shell_2                                            IDDesc:OK  \\[S\\]  vid:0000000000010002 system:0002 barrel:0001")
 #
 #  Test handle casting procedures.
diff --git a/examples/DDCMS/CMakeLists.txt b/examples/DDCMS/CMakeLists.txt
index 873f493bd823e96e1749b101cc546b00c5730379..2f9a42b751f8d59eb55694d2abc9159095dae4ba 100644
--- a/examples/DDCMS/CMakeLists.txt
+++ b/examples/DDCMS/CMakeLists.txt
@@ -143,8 +143,8 @@ dd4hep_add_test_reg( DDCMS_VolumeMgrTest_PixelBarrel
   EXEC_ARGS  geoPluginRun
   -input file:${CMAKE_CURRENT_SOURCE_DIR}/data/dd4hep-config.xml
   -destroy -print WARNING
-  -plugin DD4hep_VolumeMgrTest PixelBarrel_1
-  REGEX_PASS "PASSED: Checked 10981 objects. Num.Errors:0"
+  -plugin    DD4hep_DetectorCheck -name PixelBarrel_1 -geometry -structure -volmgr -sensitive
+  REGEX_PASS "\\+\\+\\+ PASSED: Checked a total of      46193 elements. Num.Errors:0"
   REGEX_FAIL "Exception"
   REGEX_FAIL "FAILED"
   )
@@ -155,8 +155,8 @@ dd4hep_add_test_reg( DDCMS_VolumeMgrTest_TIB
   EXEC_ARGS  geoPluginRun
   -input file:${CMAKE_CURRENT_SOURCE_DIR}/data/dd4hep-config.xml
   -destroy -print WARNING
-  -plugin DD4hep_VolumeMgrTest TIB_1
-  REGEX_PASS "PASSED: Checked 47964 objects. Num.Errors:0"
+  -plugin    DD4hep_DetectorCheck -name TIB_1 -geometry -structure -volmgr -sensitive
+  REGEX_PASS "\\+\\+\\+ PASSED: Checked a total of     168629 elements. Num.Errors:0"
   REGEX_FAIL "Exception"
   REGEX_FAIL "FAILED"
   )
@@ -167,8 +167,8 @@ dd4hep_add_test_reg( DDCMS_VolumeMgrTest_TOB
   EXEC_ARGS  geoPluginRun
   -input file:${CMAKE_CURRENT_SOURCE_DIR}/data/dd4hep-config.xml
   -destroy -print WARNING
-  -plugin DD4hep_VolumeMgrTest TOB_1
-  REGEX_PASS "PASSED: Checked 150699 objects. Num.Errors:0"
+  -plugin DD4hep_DetectorCheck -name TOB_1 -geometry -structure -volmgr -sensitive
+  REGEX_PASS "\\+\\+\\+ PASSED: Checked a total of     520446 elements. Num.Errors:0"
   REGEX_FAIL "Exception"
   REGEX_FAIL "FAILED"
   )
@@ -203,7 +203,7 @@ dd4hep_add_test_reg( DDCMS_Persist_Restore_LONGTEST
   )
 #
 #  Test restoring geometry from ROOT file: Volume Manager loading+nominals
-dd4hep_add_test_reg( DDCMS_Persist_Restore_VolMgr1_LONGTEST
+dd4hep_add_test_reg( DDCMS_Persist_Restore_DetTest1_LONGTEST
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDCMS.sh"
   EXEC_ARGS  geoPluginRun -print WARNING
   -plugin    DD4hep_RootLoader DDCMS_geometry.root
@@ -214,13 +214,13 @@ dd4hep_add_test_reg( DDCMS_Persist_Restore_VolMgr1_LONGTEST
   )
 #
 #  Test restoring geometry from ROOT file: Test Volume Manager results
-dd4hep_add_test_reg( DDCMS_Persist_Restore_VolMgr2_LONGTEST
+dd4hep_add_test_reg( DDCMS_Persist_Restore_DetTest2_LONGTEST
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDCMS.sh"
   EXEC_ARGS  geoPluginRun -print WARNING
   -plugin    DD4hep_RootLoader DDCMS_geometry.root
-  -plugin    DD4hep_VolumeMgrTest PixelBarrel_1
+  -plugin    DD4hep_DetectorCheck -name PixelBarrel_1 -geometry -structure -volmgr -sensitive
   DEPENDS    DDCMS_Persist_Save_LONGTEST
-  REGEX_PASS "\\+\\+\\+ PASSED: Checked 10981 objects. Num.Errors:0"
+  REGEX_PASS "\\+\\+\\+ PASSED: Checked a total of      46193 elements. Num.Errors:0 "
   REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED;TStreamerInfo"
   )
 #
diff --git a/examples/Persistency/CMakeLists.txt b/examples/Persistency/CMakeLists.txt
index c86fcdf759cbed23787edae3d4f809aba9a6f99c..0f844cd70873a587078f3ae072a739c817dd7bc2 100644
--- a/examples/Persistency/CMakeLists.txt
+++ b/examples/Persistency/CMakeLists.txt
@@ -163,9 +163,9 @@ dd4hep_add_test_reg( Persist_CLICSiD_Restore_VolMgr2_LONGTEST
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Persistency.sh"
   EXEC_ARGS  geoPluginRun -print WARNING
   -plugin    DD4hep_RootLoader CLICSiD_geometry.root
-  -plugin    DD4hep_VolumeMgrTest SiTrackerBarrel
+  -plugin    DD4hep_DetectorCheck -name SiTrackerBarrel -geometry -structure -volmgr -sensitive
   DEPENDS    Persist_CLICSiD_Save_LONGTEST
-  REGEX_PASS "\\+\\+\\+ PASSED: Checked 81306 objects. Num.Errors:0"
+  REGEX_PASS "\\+\\+\\+ PASSED: Checked a total of     284572 elements. Num.Errors:0"
   REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED;TStreamerInfo"
   )
 #