diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h
index b34ca918ca7c8021e7e8dee68b84ab96eb708fea..904797a43e79b5ae7252714e803ef53c20ea0a83 100644
--- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h
+++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h
@@ -78,7 +78,7 @@ class GeoDeDuplicator {
         GeoLogVolPtr cacheVolume(GeoLogVolPtr vol) const;
         GeoShapePtr cacheShape(GeoShapePtr shape) const;
 
-        void setShapeDeduplication(bool enable);
+        void setShapeDeDuplication(bool enable);
         void setLogVolDeDuplication(bool enable);
         void setTransformDeDuplication(bool enable);
         void setPhysVolDeDuplication(bool enable);
diff --git a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx
index d0ffee65ce746f6e9705de993a468c41b72ef913..45a9ec90541751d8ef95d2f2aa03e4d88828818e 100644
--- a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx
+++ b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx
@@ -9,7 +9,7 @@ GeoDeDuplicator::TrfSet GeoDeDuplicator::s_trfStore{};
 GeoDeDuplicator::ShapeSet GeoDeDuplicator::s_shapeStore{};
 
 
-void GeoDeDuplicator::setShapeDeduplication(bool enable){
+void GeoDeDuplicator::setShapeDeDuplication(bool enable){
     m_deDuplicateShape = enable;
 }
 void GeoDeDuplicator::setLogVolDeDuplication(bool enable) {
diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h
index b3c042e3f0db15e3805bbfb5dead72d8acab9c9f..8c82309e9635a1f65e794cbd33be1c9e7d9e487d 100644
--- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h
+++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h
@@ -14,7 +14,7 @@ template<typename GeoType>
 class GeoIntrusivePtr{
     public:
         template <typename GeoTypeGrp> friend class GeoIntrusivePtr;
-
+        /// Default constructor
         GeoIntrusivePtr() noexcept = default;
         // Standard constructor taking a bare pointer
         GeoIntrusivePtr(GeoType* obj) noexcept:
@@ -116,9 +116,26 @@ class GeoIntrusivePtr{
         /// Odering operator
         bool operator<(const GeoIntrusivePtr& other) const {
             return m_ptr < other.m_ptr;
-        }
+        }       
     private:
         GeoType* m_ptr{nullptr};
 };
 
+/// Function to perform an easy pointer cast from one GeoIntrusivePtr type to another
+template <class ToCast, class FromCast>
+    GeoIntrusivePtr<ToCast> dynamic_pointer_cast(const GeoIntrusivePtr<FromCast>& from) {
+        ToCast* raw_ptr = dynamic_cast<ToCast*>(from.get());
+        return GeoIntrusivePtr<ToCast>(raw_ptr);
+    }
+/// Function to perform an easy pointer const_cast from one GeoIntrusivePtr type to another
+template <class CastType>
+    GeoIntrusivePtr<CastType> const_pointer_cast(const GeoIntrusivePtr<const CastType>& from) {
+        CastType* raw_ptr = const_cast<CastType*>(from.get());
+        return GeoIntrusivePtr<CastType>(raw_ptr);
+    }
+/// Create a GeoModel object and pipe it directly into the GeoIntrusivePtr
+template <class GeoObjType, class... Args> 
+    GeoIntrusivePtr<GeoObjType> make_intrusive(Args... args) {
+    return GeoIntrusivePtr<GeoObjType>{new GeoObjType(args...)};
+}
 #endif
\ No newline at end of file
diff --git a/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx b/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx
index 9aea247992b7f0cd26815e0634e0b31d8324e316..2c4e93db39a8611dec8bb7dd3ffd8230e03b848b 100644
--- a/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx
+++ b/GeoModelTools/GeoModelXML/GMXPlugin/src/GMXPlugin.cxx
@@ -1,19 +1,18 @@
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
-
 #include "GeoModelKernel/GeoVGeometryPlugin.h"
 
-
+#include "GeoModelHelpers/StringUtils.h"
+#include "GeoModelHelpers/FileUtils.h"
+#include "GeoModelHelpers/throwExcept.h"
 #include "GeoModelKernel/GeoPhysVol.h"
-#include "GeoModelKernel/GeoNameTag.h"
-#include "GeoModelKernel/Units.h"
-#define SYSTEM_OF_UNITS GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm'
 
 #include "GeoModelXml/GmxInterface.h"
 #include "GeoModelXml/Gmx2Geo.h"
 
+
 #include <iostream>
 #include <fstream>
 #include <sstream>
@@ -23,13 +22,13 @@ class GMXPlugin : public GeoVGeometryPlugin  {
  public:
 
   // Constructor:
-  GMXPlugin();
+  GMXPlugin() = default;
 
   // Constructor with name to provide to publisher  
   GMXPlugin(std::string name):GeoVGeometryPlugin(name){}
 
   // Destructor:
-  ~GMXPlugin();
+  ~GMXPlugin() = default;
 
   // Creation of geometry:
   virtual void create(GeoVPhysVol *world, bool publish) override;
@@ -40,92 +39,60 @@ class GMXPlugin : public GeoVGeometryPlugin  {
   const GMXPlugin & operator=(const GMXPlugin &right)=delete;
   GMXPlugin(const GMXPlugin &right) = delete;
 
-  bool exists (const std::string& name)
-  {
-    std::ifstream f(name.c_str());
-    return f.good();
-  }
-
-  std::vector<std::string> parseFiles(const std::string s, std::string delimiter=";")
-  {
-    size_t pos_start = 0, pos_end, delim_len = delimiter.length();
-    std::string token;
-    std::vector<std::string> res;
-
-    while ((pos_end = s.find (delimiter, pos_start)) != std::string::npos) {
-        token = s.substr (pos_start, pos_end - pos_start);
-        pos_start = pos_end + delim_len;
-        res.push_back (token);
-    }
-
-    res.push_back (s.substr (pos_start));
-    return res;
-  }
-
 };
 
 
 
 
-
-GMXPlugin::GMXPlugin()
-{
-}
-
-
-GMXPlugin::~GMXPlugin()
-{
-}
-
-
 //## Other Operations (implementation)
-void GMXPlugin::create(GeoVPhysVol *world, bool publish)
-{  
+void GMXPlugin::create(GeoVPhysVol *world, bool publish) {  
   std::cout<< "This is GMXPlugin: creating a GeoModelXml detector "<<std::endl;
-  std::vector<std::string> filesToParse;
-  char* fPath=getenv("GMX_FILES");
-  std::string fileName;
-  if (fPath!=NULL) {
-    std::cout<<" Environment variable GMX_FILES set to "<<fPath<<std::endl;
-    fileName=std::string(fPath);
-    filesToParse=parseFiles(fileName,":");
-  }
-  else {
-  	fileName="gmx.xml";
-	filesToParse.push_back(fileName);
+  std::vector<std::string> filesToParse = GeoStrUtils::tokenize(GeoStrUtils::resolveEnviromentVariables("${GMX_FILES}"), ":");
+  
+  if (filesToParse.empty()) {
+    filesToParse.push_back("gmx.xml");
   }
-
-  char* matManager=getenv("GMX_USE_MATMANAGER");
-  bool matman=0;
-  if (matManager!=nullptr)
-  {
+  
+  
+  bool matman{false};  
+  const std::string matManager = GeoStrUtils::resolveEnviromentVariables("${GMX_USE_MATMANAGER}");
+  /// Flags to perform the deduplication
+  const bool deDuplicateShapes = GeoStrUtils::atoi(GeoStrUtils::resolveEnviromentVariables("${GMX_USE_SHAPEDEDUPL}"));
+  const bool deDuplicateLogVol = GeoStrUtils::atoi(GeoStrUtils::resolveEnviromentVariables("${GMX_USE_LOGVOLDEDUPL}"));
+  const bool deDuplicatePhysVol = GeoStrUtils::atoi(GeoStrUtils::resolveEnviromentVariables("${GMX_USE_PHYSVOLDEDUPL}"));
+  const bool deDuplicateTrfVol = GeoStrUtils::atoi(GeoStrUtils::resolveEnviromentVariables("${GMX_USE_TRANSFDEDUPL}"));
+  
+  
+  
+  if (matManager.size()){
   	std::cout<<" Environment variable GMX_USE_MATMANAGER set to "<<matManager<<std::endl;
-	std::istringstream ss(matManager);
-	ss>>matman;
-	std::cout<<"matman set to "<<matman<<std::endl;
+    matman = GeoStrUtils::atoi(matManager);
+    std::cout<<"matman set to "<<matman<<std::endl;
   }
 
-  char* levelmaps=getenv("GMX_DUMP_LEVEL_MAPS");
+  std::string levelMaps= GeoStrUtils::resolveEnviromentVariables("${GMX_DUMP_LEVEL_MAPS}");
 
-  for (auto f: filesToParse)
-  {
-    if (!exists(f)) {
-    	std::cout <<"GDMLtoGeo: input file "<<f<<
-      	" does not exist. quitting and returning nicely! "<<std::endl;
-   	return;
+  for (auto f: filesToParse) {
+    if (!GeoFileUtils::doesFileExist(f)) {
+    	THROW_EXCEPTION("GDMLtoGeo: input file "<<f<<" does not exist.");   	  
     }
+    
     GmxInterface gmxInterface;
+    gmxInterface.enableMaterialManager(matman);
+    gmxInterface.enableShapeDeDuplication(deDuplicateShapes);
+    gmxInterface.enableLogVolDeDuplication(deDuplicateLogVol);
+    gmxInterface.enablePhysVolDeDuplication(deDuplicatePhysVol);
+    gmxInterface.enableTransformDeDuplication(deDuplicateTrfVol);
     //If we want to write the SQLite, pass a publisher through to fill Aux tables
     //(needed for ReadoutGeometry)
     if(publish) gmxInterface.setPublisher(getPublisher());
 
-    if (levelmaps!=nullptr){
+    if (levelMaps.size()){
         std::string mapname = f.substr(0, f.length() - 4);
         mapname+="_levelMap.txt";
         std::cout<<"Dumping Copy Number Level Map to "<<mapname<<std::endl;
-        Gmx2Geo gmx2Geo(f, world, gmxInterface, 0 , matman, mapname);
-    }
-    else Gmx2Geo gmx2Geo(f, world, gmxInterface, 0 , matman);
+        Gmx2Geo gmx2Geo(f, world, gmxInterface, 0 , mapname);
+    } else Gmx2Geo gmx2Geo(f, world, gmxInterface, 0);
   }
 
   if (matman) MaterialManager::getManager()->printAll();
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/AssemblyProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/AssemblyProcessor.h
index 523204ece15ed2195eab0a9167d2b7e6a33a7247..9ca57c7634504c3178681fdf1a8578a773cdb38b 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/AssemblyProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/AssemblyProcessor.h
@@ -17,11 +17,11 @@ class GeoNameTag;
 
 class AssemblyProcessor: public ElementProcessor {
 public:
-    typedef struct {
-        GeoNameTag *name;
-        int id;
-        bool alignable;
-    } AssemblyStore; 
+    struct AssemblyStore {
+        GeoIntrusivePtr<GeoNameTag> name{};
+        int id{0};
+        bool alignable{false};
+    }; 
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
     void zeroId(const xercesc::DOMElement *element);
 private:
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h
index 9ae11193d2d41053279358d2af64a05e5c90fee5..e4dde0f1fa7b6e9f98666414aebf520429e74a3e 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h
@@ -31,9 +31,9 @@ class Element2GeoItem: public GeoDeDuplicator {
 
 public:
     Element2GeoItem() = default;
-    virtual ~Element2GeoItem() = default;;
-    RCBase * process(const xercesc::DOMElement *element, GmxUtil &gmxUtil);
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const;
+    virtual ~Element2GeoItem() = default;
+    GeoIntrusivePtr<RCBase> process(const xercesc::DOMElement *element, GmxUtil &gmxUtil);
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const;
 protected:
     using EntryMap = std::map<std::string, GeoIntrusivePtr<RCBase>>;
     EntryMap m_map{};  
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItemRegistry.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItemRegistry.h
index 1cea419f137ba852556826ec5991fa494b63a00c..969faee8c4ee4925a8295366c8dccbba05cfc890 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItemRegistry.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItemRegistry.h
@@ -13,20 +13,35 @@
 #include <string>
 #include <map>
 
-class Element2GeoItem;
+#include "GeoModelXml/Element2GeoItem.h"
 
 class Element2GeoItemRegistry {
 public:
-    Element2GeoItemRegistry();
-    ~Element2GeoItemRegistry();
-    Element2GeoItemRegistry(const Element2GeoItemRegistry&) = delete;
-    Element2GeoItemRegistry& operator=(const Element2GeoItemRegistry&) = delete;
+    Element2GeoItemRegistry() = default;
+    ~Element2GeoItemRegistry() = default;
     void enregister(const std::string& tagName,  Element2GeoItem *processor); // register = keyword
     Element2GeoItem *find(const std::string& tagName);
 
+    /** Switches whether the log vol shall be shared across multiple physVols. 
+     *  Propagates the flag to all registered Element2GeoItem objects */
+    void enableLogVolDeDuplication(bool enable);
+    /** Switches whether the shapes shall be shared across the Geometry
+     *  Propagates the flag to all regsitered Element2GeoItem objects */
+    void enableShapeDeDuplication(bool enable);
+    /** Switches whether the non-alignable transform nodes shall be shared across the Geometry tree
+     *  Propagtes the flag to all registered Element2GeoItem objects */
+    void enableTransformDeDuplication(bool enable);
+    /** Switches whether the equivalent ordinary phyiscal volumes shall be shared across the Geometry tree
+     *  Propagtes the flag to all registered Element2GeoItem objects */
+    void enablePhysVolDeDuplication(bool enable);
 private:
-    Element2GeoItem *m_defaultProcessor;
-    std::map<std::string,  Element2GeoItem *> m_processor;
+    std::unique_ptr<Element2GeoItem> m_defaultProcessor{std::make_unique<Element2GeoItem>()};
+    std::map<std::string, Element2GeoItem *> m_processor{};
+
+    bool m_deDuplicateLogVols{false};
+    bool m_deDuplicateShapes{false};
+    bool m_deDuplicateTransforms{false};
+    bool m_deDuplicatePhysVols{false};
 };
 
 #endif // ELEMENT2GEO_ITEM_REGISTRY_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2ShapeItem.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2ShapeItem.h
deleted file mode 100644
index 0d80503f6c92a065b8019643fe0e38800dab01d4..0000000000000000000000000000000000000000
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2ShapeItem.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
-*/
-#ifndef GEO_MODEL_XML_ELEMENT_2_SHAPEITEM_H
-#define GEO_MODEL_XML_ELEMENT_2_SHAPEITEM_H
-#include "GeoModelXml/Element2GeoItem.h"
-
-#include <set>
-class Element2ShapeItem: public Element2GeoItem {
-    public:
-        Element2ShapeItem();
-        
-        virtual ~Element2ShapeItem();
-
-        static void deduplicateShapes(const bool enable);
-
-    private:
-        static std::set<Element2ShapeItem*> s_instances;
-        static bool s_applyDepluication;
-};
-
-
-#endif
\ No newline at end of file
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ElementProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ElementProcessor.h
index 231236a9274e95d6b2496a4e2e5a269b6face6fa..e295b4c7c244101821cffc386cb7b0c58a053d7a 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ElementProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ElementProcessor.h
@@ -21,7 +21,7 @@ class GmxUtil;
 class ElementProcessor: public GeoDeDuplicator {
 
 public:
-    ElementProcessor();
+    ElementProcessor() = default;
     virtual void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, 
                          GeoNodeList &toBeAdded);
 };
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GeoNodeList.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GeoNodeList.h
index 22287c7fdf32ac9f3042bc48947970f8dbc55c7e..b3451430565bb30963d2abe2959815ade31b47b6 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GeoNodeList.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GeoNodeList.h
@@ -1,9 +1,9 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <vector>
 #include "GeoModelKernel/GeoGraphNode.h"
-
-typedef std::vector<GeoGraphNode *> GeoNodeList;
+#include "GeoModelKernel/GeoIntrusivePtr.h"
+using GeoNodeList = std::vector<GeoIntrusivePtr<GeoGraphNode>>;
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Gmx2Geo.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Gmx2Geo.h
index 9ad3f0f38f7e140fe7fdaae51e0b6b9cd4a13bed..715a93746b8031bade4fd227fc0e7229f8377150 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Gmx2Geo.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Gmx2Geo.h
@@ -58,9 +58,13 @@ using processorList = std::map<std::string,ElementProcessor*>;
 
 class Gmx2Geo {
 public:
-    Gmx2Geo(const std::string& gmxFile, GeoVPhysVol *addHere, GmxInterface &gmxInterface, unsigned int flags = 0, bool useMatManager = 0, std::string levelMapName = "", const processorList& procs=processorList());
+    Gmx2Geo(const std::string& gmxFile, 
+            GeoVPhysVol *addHere, 
+            GmxInterface &gmxInterface, 
+            unsigned int flags = 0, 
+            std::string levelMapName = "", const processorList& procs=processorList());
 private:
-// Disallow copying
+    // Disallow copying
     Gmx2Geo(const Gmx2Geo &right) = delete;
     Gmx2Geo & operator=(const Gmx2Geo &right) = delete;
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxInterface.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxInterface.h
index 609280b0a0f626b8e384fa16c138ebe3ac25be23..c14562e5a153ba24134759e110fad815e428a4f4 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxInterface.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxInterface.h
@@ -21,6 +21,7 @@
 #include <variant>
 #include "GeoModelKernel/GeoVFullPhysVol.h"
 #include "GeoModelKernel/GeoAlignableTransform.h"
+#include "GeoModelHelpers/throwExcept.h"
 
 class GeoPublisher;
 
@@ -32,9 +33,9 @@ public:
   virtual void addSensor(const std::string& name, std::map<std::string, int> &index, int id, GeoVFullPhysVol *fpv);
   virtual void addSplitSensor(const std::string& name, std::map<std::string, int> &index, std::pair<std::string, int> &extraIndex, int id, GeoVFullPhysVol *fpv,int splitLevel=0);
   virtual void addAlignable(int level, std::map<std::string, int> &index,
-			    GeoVFullPhysVol *fpv, GeoAlignableTransform *transform);
+                GeoVFullPhysVol *fpv, GeoAlignableTransform *transform);
   virtual void addSplitAlignable(int level, std::map<std::string, int> &index, std::pair<std::string, int> &extraIndex,
-			    GeoVFullPhysVol *fpv, GeoAlignableTransform *transform);
+                GeoVFullPhysVol *fpv, GeoAlignableTransform *transform);
   //allow a publisher to be passed through from GMXPlugin, to write necessary AuxTables to SQLite
   void setPublisher(GeoPublisher * publisher);
   void publish(std::string& tableName, std::vector<std::string>& colNames, std::vector<std::string>& colTypes, std::vector<std::vector<std::variant<int,long,float,double,std::string>>>& tableData);
@@ -42,9 +43,9 @@ public:
   // helpers
   template <typename T>
   bool checkParameter(const std::string /* &typeName */,
-		      const std::map<std::string, std::string> &parameters,
-		      const std::string &name,
-		      T &value)
+                      const std::map<std::string, std::string> &parameters,
+                      const std::string &name,
+                      T &value)
   {
     // Needs some kind of versioning to stop this being abused...
     auto it = parameters.find(name);
@@ -57,24 +58,22 @@ public:
 
   template <typename T>
   void getParameter(const std::string &typeName,
-		    const std::map<std::string, std::string> &parameters,
-		    const std::string &name,
-		    T &value) const
-  {
+            const std::map<std::string, std::string> &parameters,
+            const std::string &name,
+            T &value) const {
     auto it = parameters.find(name);
     if (it != parameters.end()) {
       std::istringstream(it->second) >> value;
     } else {
-      std::string err("GmxInterface Error: missing parameter " + name + " for " + typeName);
-      throw std::runtime_error(err);
+      THROW_EXCEPTION("GmxInterface Error: missing parameter " << name << " for " << typeName);
     }
   }
 
   template <typename T, typename A>
   void getParameters(const std::string &typeName,
-		     const std::map<std::string, std::string> &parameters,
-		     const std::string &name,
-		     std::vector<T, A> &vec) const
+                    const std::map<std::string, std::string> &parameters,
+                    const std::string &name,
+                    std::vector<T, A> &vec) const
   {
     auto it = parameters.find(name);
     if (it != parameters.end()) {
@@ -83,17 +82,45 @@ public:
       strVal.erase(strVal.find_last_not_of(" \t\n\r\f\v") + 1); // trailing white space or you get an extra 0
       std::istringstream inString(strVal);
       do {
-	inString >> value;
-	vec.push_back(value);
+          inString >> value;
+          vec.push_back(value);
       } while (inString.good());
     } else {
-      std::string err("GmxInterface Error: missing parameters " + name + " for " + typeName);
-      throw std::runtime_error(err);
+      THROW_EXCEPTION("GmxInterface Error: missing parameters "<< name << " for "<< typeName);
     }
   }
 
+  /** Switches whether the log vol shall be shared across multiple physVols. 
+   *  Propagates the flag to all registered Element2GeoItem objects */
+  void enableLogVolDeDuplication(bool enable);
+  /** Switches whether the shapes shall be shared across the Geometry
+   *  Propagates the flag to all regsitered Element2GeoItem objects */
+  void enableShapeDeDuplication(bool enable);
+  /** Switches whether the non-alignable transform nodes shall be shared across the Geometry tree
+   *  Propagtes the flag to all registered Element2GeoItem objects */
+  void enableTransformDeDuplication(bool enable);
+  /** Switches whether the equivalent ordinary phyiscal volumes shall be shared across the Geometry tree
+   *  Propagtes the flag to all registered Element2GeoItem objects */
+  void enablePhysVolDeDuplication(bool enable);
+
+  
+  void enableMaterialManager(bool enable);
+
+   bool doPhysVolDeDpulication () const;
+   bool doLogVolDeDuplication() const;
+   bool doShapeDeDuplication() const;
+   bool doTransformDeDuplication() const;
+
+   bool useMaterialManager() const;
 private:
-GeoPublisher * m_publisher = nullptr;
+    GeoPublisher* m_publisher{nullptr};
+    /// @brief  Flags to steer whether the deduplication shall take place
+    bool m_deDuplicateLogVols{false};
+    bool m_deDuplicateShapes{false};
+    bool m_deDuplicateTransforms{false};
+    bool m_deDuplicatePhysVols{false};
+    /// @brief 
+    bool m_useMatManger{false};
 
 };
 #endif // GMX_INTERFACE_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h
index 0a1912e85dfb2a788c556fc1d2be1c119dc88a7d..e149501c677c4f71a229f77a360f80f347a525c8 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h
@@ -62,21 +62,22 @@
 class GmxUtil {
 public:
     GmxUtil(GmxInterface &gmxInterface);
-    ~GmxUtil();
-    GmxInterface *gmxInterface();
+    virtual ~GmxUtil() = default;
+    GmxInterface& gmxInterface();
     double evaluate(char const *expression);
     std::string debracket(std::string expression);
     GeoModelTools::Evaluator eval;
     PositionIndex positionIndex;
-    MaterialManager* matManager=0;
+    MaterialManager* matManager{nullptr};
     ProcessorRegistry processorRegistry;
     Element2GeoItemRegistry geoItemRegistry;
     GeoLogVol * getAssemblyLV() {return m_assemblyLV;};
+    
+    
     struct TagHandler {
-//
-//    Things creating a vector of nodes to be added to the tree
-//
-	std::map<std::string, ElementProcessor&, std::less<std::string> > processor;
+        //
+        //    Things creating a vector of nodes to be added to the tree
+        //
         AddbranchProcessor addbranch;
         LogvolProcessor logvol;
         LogvolrefProcessor logvolref;
@@ -84,11 +85,11 @@ public:
         AssemblyrefProcessor assemblyref;
         TransformProcessor transform;
         MulticopyProcessor multicopy;
-	ReplicaXProcessor replicaX;
-	ReplicaYProcessor replicaY;
-	ReplicaZProcessor replicaZ;
-	ReplicaRPhiProcessor replicaRPhi;
-	ReplicaXYarraysProcessor replicaXYArrays;
+        ReplicaXProcessor replicaX;
+        ReplicaYProcessor replicaY;
+        ReplicaZProcessor replicaZ;
+        ReplicaRPhiProcessor replicaRPhi;
+        ReplicaXYarraysProcessor replicaXYArrays;
         IndexProcessor index;
 //
 //    Things creating an RCBase *
@@ -127,10 +128,11 @@ public:
     } tagHandler;
 //    SensitiveId sensitiveId;
 private:
-    GeoLogVol *makeAssemblyLV();
-    GeoLogVol *m_assemblyLV; // Special logvol to be turned into an assembly-physical-volume. 
+    GeoIntrusivePtr<GeoLogVol> makeAssemblyLV();
+    GeoIntrusivePtr<GeoLogVol> m_assemblyLV{}; // Special logvol to be turned into an assembly-physical-volume. 
                              // Achieved by filling it with special::ether material.
-    GmxInterface *m_gmxInterface; 
+    GmxInterface& m_gmxInterface; 
+
 };
 
 #endif // GMXUTIL_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h
index 51a83dfd9c194f7fc1f7267d7f06d25831f9fd0f..09c4e3d41888c99aba475af6526e9921bf73472d 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h
@@ -26,7 +26,7 @@ public:
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
     void zeroId(const xercesc::DOMElement *element);
 
-    LogvolProcessor();
+    LogvolProcessor() = default;
 private:
     std::map<std::string, LogVolStore> m_map; 
 };
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeElement.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeElement.h
index ac31a7bb064bd77e4fec714b718d96777379f447..e43b9df7cbbac5435dd6085f429c552a49cf704b 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeElement.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeElement.h
@@ -14,7 +14,7 @@
 class MakeElement: public Element2GeoItem {
 public:
     MakeElement();
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // MAKE_ELEMENT_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeMaterial.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeMaterial.h
index e2219f27fd6c2840d0427efc92c02b92326ed760..e2b9f86dd489a61a49f6decbdfbf1ab775172330 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeMaterial.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeMaterial.h
@@ -14,7 +14,7 @@
 class MakeMaterial: public Element2GeoItem {
 public:
     MakeMaterial();
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // MAKE_MATERIAL_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformation.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformation.h
index 0cf6b79f001cba0b68c3551672f259316bf7f9b1..baff4746e6bcf5ad62635cbc2310519a90253a93 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformation.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformation.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -13,8 +13,8 @@
 
 class MakeTransformation: public Element2GeoItem {
 public:
-    MakeTransformation();
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    MakeTransformation() = default;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // MAKE_TRANSFORMATION_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformationref.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformationref.h
index caca40cb2cbb84193852d5b54f3a0871ea9b6417..45cb423a15e47ab0b9045e9e2f5e384ee61bcf75 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformationref.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTransformationref.h
@@ -13,7 +13,7 @@
 
 class MakeTransformationref: public Element2GeoItem {
 public:
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // MAKE_TRANSFORMATIONREF_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTranslation.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTranslation.h
index 3464308f791059a16548cd7fa36d0f89e52d299f..b6783c2ede7cf223a4dcd954b8dc086ae62a11e6 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTranslation.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MakeTranslation.h
@@ -18,7 +18,7 @@ class GmxUtil;
 
 class MakeTranslation {
 public:
-    MakeTranslation();
+    MakeTranslation() = default;
     GeoTrf::Translate3D getTransform(const xercesc::DOMElement *rotation, GmxUtil &gmxUtil);
 };
 #endif // MAKE_TRANSLATION_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MulticopyProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MulticopyProcessor.h
index 2bd5d1db8f54d12031973cf7558a743208c31da7..788118acb064a2e54927561c09f1eac26ef3228b 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MulticopyProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MulticopyProcessor.h
@@ -16,7 +16,7 @@ class GmxUtil;
 
 class MulticopyProcessor: public ElementProcessor {
 public:
-    MulticopyProcessor();
+    MulticopyProcessor() = default;
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
 private:
     std::map <std::string, GeoNodeList> m_map; 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ProcessorRegistry.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ProcessorRegistry.h
index 97c2e8b403d60ad7b65cfe1bc9f2c2d134af1129..fdfb0f1135c132cdcfcfa21a40f50fab05fc2d61 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ProcessorRegistry.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ProcessorRegistry.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -11,22 +11,40 @@
 #ifndef GEO_MODEL_XML_PROCESSOR_REGISTRY_H
 #define GEO_MODEL_XML_PROCESSOR_REGISTRY_H
 
+
+#include "GeoModelXml/ElementProcessor.h"
 #include <string>
 #include <map>
 
-class ElementProcessor;
 
 class ProcessorRegistry {
 public:
-    ProcessorRegistry();
-    ProcessorRegistry(const ProcessorRegistry&) = delete;
-    ProcessorRegistry& operator=(const ProcessorRegistry&) = delete;
+    ProcessorRegistry() = default;
+    
     void enregister(const std::string& tagName, ElementProcessor *processor);
     ElementProcessor *find(const std::string& name);
 
+    /** Switches whether the log vol shall be shared across multiple physVols. 
+     *  Propagates the flag to all registered ElementProcessors */
+    void enableLogVolDeDuplication(bool enable);
+    /** Switches whether the shapes shall be shared across the Geometry
+     *  Propagates the flag to all regsitered ElementProcessors */
+    void enableShapeDeDuplication(bool enable);
+    /** Switches whether the non-alignable transform nodes shall be shared across the Geometry tree
+     *  Propagtes the flag to all registered ElementProcessors */
+    void enableTransformDeDuplication(bool enable);
+    /** Switches whether the equivalent ordinary phyiscal volumes shall be shared across the Geometry tree
+     *  Propagtes the flag to all registered ElementProcessors */
+    void enablePhysVolDeDuplication(bool enable);
+
 private:
-    ElementProcessor *m_defaultProcessor;
+    bool m_deDuplicateLogVols{false};
+    bool m_deDuplicateShapes{false};
+    bool m_deDuplicateTransforms{false};
+    bool m_deDuplicatePhysVols{false};
+    std::unique_ptr<ElementProcessor> m_defaultProcessor{std::make_unique<ElementProcessor>()};
     std::map<std::string, ElementProcessor *> m_processor;
+
 };
 
 #endif // PROCESSOR_REGISTRY_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaRPhiProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaRPhiProcessor.h
index 189dd9eaba982daa3e5a5eb7cc91f31b0e9becbc..8fb9fb209cc7d5ce24f048b43f47c920a2879d46 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaRPhiProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaRPhiProcessor.h
@@ -16,7 +16,7 @@ class GmxUtil;
 
 class ReplicaRPhiProcessor: public ElementProcessor {
 public:
-    ReplicaRPhiProcessor();
+    ReplicaRPhiProcessor() = default;
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
 private:
     std::map <std::string, GeoNodeList> m_map{}; 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXProcessor.h
index d1698e52a1e871d4a8afc937e58a5fb1d8f3fce7..198dcd1bef27ebb6eb114f8b4bd3eed5712b5f0f 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXProcessor.h
@@ -16,7 +16,7 @@ class GmxUtil;
 
 class ReplicaXProcessor: public ElementProcessor {
 public:
-    ReplicaXProcessor();
+    ReplicaXProcessor() = default;
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
 private:
     std::map <std::string, GeoNodeList> m_map; 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXYArraysProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXYArraysProcessor.h
index e57ef6945cc0a0fa77f54c3dc8ff90c3272f3c44..4d8d16fb873e718e0af97872c50b257bea21b569 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXYArraysProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaXYArraysProcessor.h
@@ -16,7 +16,7 @@ class GmxUtil;
 
 class ReplicaXYarraysProcessor: public ElementProcessor {
 public:
-    ReplicaXYarraysProcessor();
+    ReplicaXYarraysProcessor() = default;
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
 private:
     std::map <std::string, GeoNodeList> m_map; 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaYProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaYProcessor.h
index 3bb68619c1107d059cd91a701f1bf04b69dfedee..6631f0a72b2e8bfd4e97c5ef3d2f78b06f3137a5 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaYProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaYProcessor.h
@@ -16,7 +16,7 @@ class GmxUtil;
 
 class ReplicaYProcessor: public ElementProcessor {
 public:
-    ReplicaYProcessor();
+    ReplicaYProcessor() = default;
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
 private:
     std::map <std::string, GeoNodeList> m_map; 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaZProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaZProcessor.h
index 02b8ca8b9aa48544e6685480398795dec64ad26c..cb585a4f4624db11a14e019a073e296dbef954dc 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaZProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/ReplicaZProcessor.h
@@ -16,7 +16,7 @@ class GmxUtil;
 
 class ReplicaZProcessor: public ElementProcessor {
 public:
-    ReplicaZProcessor();
+    ReplicaZProcessor() = default;
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
 private:
     std::map <std::string, GeoNodeList> m_map; 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/TransformProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/TransformProcessor.h
index 7167379dd05e3b2f2cd38044090161d57a1574a3..a9d3ba3b2866c0eac8825f28a711cdb9568dcf8a 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/TransformProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/TransformProcessor.h
@@ -14,6 +14,7 @@ class GmxUtil;
 
 class TransformProcessor: public ElementProcessor {
 public:
+    TransformProcessor() = default;
     void process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd);
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeBox.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeBox.h
index e89272085bae0878322df423660479e9e94a72b5..d38e471d7b254e646eab0a66c612a03e9a295584 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeBox.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeBox.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_BOX_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 #include "GeoModelKernel/GeoBox.h"
-class MakeBox: public Element2ShapeItem {
+class MakeBox: public Element2GeoItem {
 public:
     MakeBox() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeCons.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeCons.h
index b02df79df024fe1f5605203180fcacd23c12979a..df820ef8a16debe2653b264f5156add4e1a8af6a 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeCons.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeCons.h
@@ -10,12 +10,12 @@
 #define GEO_MODEL_XML_MAKE_CONS_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakeCons: public Element2ShapeItem {
+class MakeCons: public Element2GeoItem {
   public:
       MakeCons() = default;
-      virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+      virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeEllipticalTube.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeEllipticalTube.h
index 1cb4c1cd2ee7ed40f42ff3d98f711073e1a86a9f..3681df4c5893c43df21d13ad8b466ba169185448 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeEllipticalTube.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeEllipticalTube.h
@@ -6,12 +6,12 @@
 #define GEO_MODEL_XML_MAKE_ELLIPTICAL_TUBE_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakeEllipticalTube: public Element2ShapeItem {
+class MakeEllipticalTube: public Element2GeoItem {
 public:
     MakeEllipticalTube() = default;;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeGenericTrap.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeGenericTrap.h
index abf19c9d33885d3aa74a265628ca0aeb1c734d90..8161b759593f787b385c0b396cc7a475653db472 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeGenericTrap.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeGenericTrap.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_GENERICTRAP_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakeGenericTrap: public Element2ShapeItem {
+class MakeGenericTrap: public Element2GeoItem {
 public:
     MakeGenericTrap() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // GEO_MODEL_XML_MAKE_GENERICTRAP_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeIntersection.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeIntersection.h
index c3bacc088d63cdf68c350fb147d94bcea0b56078..f840903c9dc05fe02f514503d6b336c51f8b0c13 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeIntersection.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeIntersection.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_INTERSECTION_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakeIntersection: public Element2ShapeItem {
+class MakeIntersection: public Element2GeoItem {
 public:
     MakeIntersection() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePara.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePara.h
index 05f9436b2a538669b13d2cb170dfa2761934a445..47a3bb8c54118a7d7d6d2418b1ba6ff9e79f269f 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePara.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePara.h
@@ -10,12 +10,12 @@
 #define GEO_MODEL_XML_MAKE_PARA_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakePara: public Element2ShapeItem {
+class MakePara: public Element2GeoItem {
   public:
     MakePara() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
    
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePcon.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePcon.h
index 844f5161a8d82ee8d24f5a7e2f9fd455d29d8370..1e5af9b93ec78f3e7464b955033ee6f37a84d725 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePcon.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePcon.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_PCON_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakePcon: public Element2ShapeItem {
+class MakePcon: public Element2GeoItem {
 public:
     MakePcon() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePgon.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePgon.h
index ee8bee8747f74882cce825f240a8afadbbd93700..0a2d62a7181e7b194c6c3e60148cdb2cfa02a22a 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePgon.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakePgon.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_PGON_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakePgon: public Element2ShapeItem {
+class MakePgon: public Element2GeoItem {
   public:
       MakePgon() = default;
-      virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+      virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeShaperef.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeShaperef.h
index 7c5ee33db55b78777c584278568d5ecaf794877f..b30c840c6cfae8c35d576ede2aca05925c60a083 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeShaperef.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeShaperef.h
@@ -10,11 +10,11 @@
 #define GEO_MODEL_XML_MAKE_SHAPEREF_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakeShaperef: public Element2ShapeItem {
+class MakeShaperef: public Element2GeoItem {
 public:
-  RCBase * process(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const;
+  GeoIntrusivePtr<RCBase>process(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const;
 };
 
 #endif // GEO_MODEL_XML_MAKE_SHAPEREF_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSimplePolygonBrep.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSimplePolygonBrep.h
index 81fad3a8d16b31bce32c40ff63246e29c6c78cbc..7184411acc05313c3704652dce891eb23fe946f1 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSimplePolygonBrep.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSimplePolygonBrep.h
@@ -9,12 +9,12 @@
 #define GEO_MODEL_XML_MAKE_SIMPLEPOLYGONBREP_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakeSimplePolygonBrep: public Element2ShapeItem {
+class MakeSimplePolygonBrep: public Element2GeoItem {
 public:
     MakeSimplePolygonBrep() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // GEO_MODEL_XML_MAKE_SIMPLEPOLYGONBREP_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSubtraction.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSubtraction.h
index 0f185db1e3bac0a150bc850c09fe251cea4e47a0..298938545e6f7c8467b56a8503c1119987ea8c89 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSubtraction.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeSubtraction.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_SUBTRACTION_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakeSubtraction: public Element2ShapeItem {
+class MakeSubtraction: public Element2GeoItem {
 public:
     MakeSubtraction() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTorus.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTorus.h
index d78175d9f993eccbcbded980a359f881cb35a10d..e8878eb3544ea8c6efd698598b52e3b5e9dda857 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTorus.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTorus.h
@@ -7,13 +7,13 @@
 #define GEO_MODEL_XML_MAKE_TORUS_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakeTorus: public Element2ShapeItem {
+class MakeTorus: public Element2GeoItem {
 public:
     MakeTorus() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrap.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrap.h
index d307e96e25b39e336eea32e4856aab5b83584616..32fc9fa0305df296d250a443e6a870322506e941 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrap.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrap.h
@@ -10,12 +10,12 @@
 #define GEO_MODEL_XML_MAKE_TRAP_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakeTrap: public Element2ShapeItem {
+class MakeTrap: public Element2GeoItem {
 public:
     MakeTrap() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // GEO_MODEL_XML_MAKE_TRAP_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrd.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrd.h
index 1ae5b139070a2d56bcc067d99da529c942a0aff3..13accc8a467a16d717ecd9e05bdcb99abc035fa6 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrd.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTrd.h
@@ -10,12 +10,12 @@
 #define GEO_MODEL_XML_MAKE_TRD_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakeTrd: public Element2ShapeItem {
+class MakeTrd: public Element2GeoItem {
 public:
     MakeTrd() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // GEO_MODEL_XML_MAKE_TRD_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTube.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTube.h
index fe347e9f854ffe8ba0c4bec37b8083b1fb5f63e7..fd6a63152efe43d0a0afdcd0abdd86de89249da3 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTube.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTube.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_TUBE_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakeTube: public Element2ShapeItem {
+class MakeTube: public Element2GeoItem {
 public:
     MakeTube() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTubs.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTubs.h
index 595c45b08a4184a51487910be5e41aa5029451ce..a2b27a7a5f20c84f011698007592be8d05921500 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTubs.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTubs.h
@@ -10,13 +10,13 @@
 #define GEO_MODEL_XML_MAKE_TUBS_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakeTubs: public Element2ShapeItem {
+class MakeTubs: public Element2GeoItem {
 public:
     MakeTubs() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 };
 
 #endif // GEO_MODEL_XML_MAKE_TUBS_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTwistedTrap.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTwistedTrap.h
index 4193ba496b3b92c6b0d57bcea6f299cef6cd548d..271e3f6ebab59cbb1b469f827d9c918e9d8d4d16 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTwistedTrap.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeTwistedTrap.h
@@ -6,13 +6,13 @@
 #define GEO_MODEL_XML_MAKE_TWISTED_TRAP_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
 
-class MakeTwistedTrap: public Element2ShapeItem {
+class MakeTwistedTrap: public Element2GeoItem {
 public:
     MakeTwistedTrap() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeUnion.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeUnion.h
index 67fa1be6c88b0bbe21dc809731ebec15d73d86fd..6590c7cec654791125db252dfa7ce4a54c54e073 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeUnion.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/shape/MakeUnion.h
@@ -10,12 +10,12 @@
 #define GEO_MODEL_XML_MAKE_UNION_H
 #include <xercesc/util/XercesDefs.hpp>
 
-#include "GeoModelXml/Element2ShapeItem.h"
+#include "GeoModelXml/Element2GeoItem.h"
 
-class MakeUnion: public Element2ShapeItem {
+class MakeUnion: public Element2GeoItem {
 public:
     MakeUnion() = default;
-    virtual RCBase * make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
+    virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const override;
 
 };
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx
index d42f4124fa33b7d2e6a84f5dd07874ee4f309896..8c1b225d09f691265bd1e1f9e0535cc1f5da5c7c 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyProcessor.cxx
@@ -31,8 +31,8 @@ using namespace std;
 using namespace xercesc;
 
 void AssemblyProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-GeoLogVol *lv;
-GeoNameTag *physVolName;
+    GeoIntrusivePtr<GeoLogVol> lv{};
+    GeoIntrusivePtr<GeoNameTag> physVolName{};
 
     gmxUtil.positionIndex.incrementLevel();
 
@@ -47,22 +47,18 @@ GeoNameTag *physVolName;
 //
     map<string, AssemblyStore>::iterator entry;
     if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Name
-//
-        m_map[name] = AssemblyStore();
-        AssemblyStore *store = &m_map[name];
-        physVolName = new GeoNameTag(name); 
-        store->name = physVolName;
-        store->id = 0;
-    }
-    else { // Already in the registry; use it.
+        //
+        //    Name
+        AssemblyStore& store {m_map[name]};
+        physVolName = make_intrusive<GeoNameTag>(name); 
+        store.name = physVolName;
+    } else { // Already in the registry; use it.
         physVolName = entry->second.name;
     }
     lv = gmxUtil.getAssemblyLV();
     toAdd.push_back(physVolName);
     gmxUtil.positionIndex.setCopyNo(m_map[name].id);
-    toAdd.push_back(new GeoIdentifierTag(m_map[name].id++)); 
+    toAdd.push_back(make_intrusive<GeoIdentifierTag>(m_map[name].id++)); 
 //
 //    Process the assembly's children
 //
@@ -85,18 +81,18 @@ GeoNameTag *physVolName;
     XMLString::release(&toRelease);
     XMLString::release(&alignable_tmp);
     if (alignable.compare(string("true")) == 0) {
-        GeoFullPhysVol *pv = new GeoFullPhysVol(lv);
+        GeoIntrusivePtr<GeoFullPhysVol> pv = make_intrusive<GeoFullPhysVol>(cacheVolume(lv));
         for (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) {
             pv->add(*node);
         }
         toAdd.push_back(pv); // NB: the *PV is third item added, so reference as toAdd[2].
     }
     else {
-        GeoPhysVol *pv = new GeoPhysVol(lv);
+        GeoIntrusivePtr<GeoPhysVol> pv = make_intrusive<GeoPhysVol>(cacheVolume(lv));
         for (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) {
             pv->add(*node);
         }
-        toAdd.push_back(pv);
+        toAdd.push_back(cacheVolume(pv));
     }
 
     gmxUtil.positionIndex.decrementLevel();
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyrefProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyrefProcessor.cxx
index a0e63cf7f8333f8023a6651777ea3b70140ca2b5..455526fcd4eca5a6730a7552016e6163c757adeb 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyrefProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/AssemblyrefProcessor.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -7,7 +7,7 @@
 //
 #include "OutputDirector.h"
 #include "GeoModelXml/AssemblyrefProcessor.h"
-#include <string>
+#include "GeoModelHelpers/throwExcept.h"
 
 #include "xercesc/util/XercesDefs.hpp"
 #include <xercesc/dom/DOM.hpp>
@@ -36,9 +36,8 @@ char *toRelease;
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     if (nodeName != string("assembly") && nodeName != string("set")) {
-        msglog << MSG::FATAL << "Error in xml/gmx file: assemblyref " << XMLString::transcode(idref) << " referenced a " << 
-                              nodeName << " instead of an assembly.\n";
-	std::abort();
+        THROW_EXCEPTION("Error in xml/gmx file: assemblyref " << XMLString::transcode(idref) << " referenced a " << 
+                              nodeName << " instead of an assembly.\n");
     }
 //
 //    Process it
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx
index 580b20989303b4eab2e41dc4b470a96d875804ad..09c48a79f4c58ee1bd2b3c6fc25680311c4ac624 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx
@@ -18,7 +18,7 @@ using namespace std;
 using namespace xercesc;
 
 
-RCBase * Element2GeoItem::process(const xercesc::DOMElement *element, GmxUtil &gmxUtil) {
+GeoIntrusivePtr<RCBase> Element2GeoItem::process(const xercesc::DOMElement *element, GmxUtil &gmxUtil) {
 
     char *name2release;
     XMLCh * name_tmp = XMLString::transcode("name");
@@ -28,7 +28,7 @@ RCBase * Element2GeoItem::process(const xercesc::DOMElement *element, GmxUtil &g
     XMLString::release(&name2release);
     XMLString::release(&name_tmp);
 
-    RCBase *item{nullptr};
+    GeoIntrusivePtr<RCBase> item{nullptr};
     EntryMap::iterator entry;
     if (name.empty()) { // Unnamed item; cannot store in the map; make a new one 
         item = make(element, gmxUtil);
@@ -43,7 +43,7 @@ RCBase * Element2GeoItem::process(const xercesc::DOMElement *element, GmxUtil &g
     return item;
 }
 
-RCBase * Element2GeoItem::make(const xercesc::DOMElement *element, GmxUtil & /* gmxUtil */) const {
+GeoIntrusivePtr<RCBase> Element2GeoItem::make(const xercesc::DOMElement *element, GmxUtil & /* gmxUtil */) const {
     char *name2release = XMLString::transcode(element->getNodeName());
     std::string nodeName{name2release};
     XMLString::release(&name2release);
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItemRegistry.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItemRegistry.cxx
index 14c961e980c6d19e3cd9cf1173fbcee95806af65..d2c288b067b6625eca7b032ecd9b031b3e3fd8f7 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItemRegistry.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItemRegistry.cxx
@@ -1,24 +1,44 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GeoModelXml/Element2GeoItemRegistry.h"
 #include "GeoModelXml/Element2GeoItem.h"
 
-Element2GeoItemRegistry::Element2GeoItemRegistry() {
-    m_defaultProcessor = new Element2GeoItem; 
+void Element2GeoItemRegistry::enableLogVolDeDuplication(bool enable){
+    m_deDuplicateLogVols = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setLogVolDeDuplication(enable);
+    }
 }
-
-Element2GeoItemRegistry::~Element2GeoItemRegistry() {
-    delete m_defaultProcessor; 
+void Element2GeoItemRegistry::enableShapeDeDuplication(bool enable){
+    m_deDuplicateShapes = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setShapeDeDuplication(enable);
+    }
+}
+void Element2GeoItemRegistry::enableTransformDeDuplication(bool enable) {
+    m_deDuplicateTransforms = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setTransformDeDuplication(enable);
+    }
+}
+void Element2GeoItemRegistry::enablePhysVolDeDuplication(bool enable){
+    m_deDuplicatePhysVols = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setPhysVolDeDuplication(enable);
+    }
 }
 
 void Element2GeoItemRegistry::enregister(const std::string& tagName, Element2GeoItem *processor) {
     m_processor[tagName] = processor;
+    processor->setPhysVolDeDuplication(m_deDuplicatePhysVols);
+    processor->setTransformDeDuplication(m_deDuplicateTransforms);
+    processor->setShapeDeDuplication(m_deDuplicateShapes);
+    processor->setLogVolDeDuplication(m_deDuplicateLogVols);
 }
 
 Element2GeoItem * Element2GeoItemRegistry::find(const std::string& name) {
     std::map<std::string, Element2GeoItem *>::iterator it = m_processor.find(name);
-
-    return it == m_processor.end()? m_defaultProcessor: it->second;
+    return it == m_processor.end()? m_defaultProcessor.get(): it->second;
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2ShapeItem.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2ShapeItem.cxx
deleted file mode 100644
index 9c9dabde39b081ac3b41292ce96117c6311d5ebe..0000000000000000000000000000000000000000
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2ShapeItem.cxx
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
-*/
-#include "GeoModelXml/Element2ShapeItem.h"
-#include <mutex>
-
-namespace{
-    std::mutex s_mutex{};
-}
-
-bool Element2ShapeItem::s_applyDepluication = false;
-std::set<Element2ShapeItem*> Element2ShapeItem::s_instances{};
-
-Element2ShapeItem::Element2ShapeItem() {
-    std::lock_guard guard{s_mutex};
-    s_instances.insert(this);
-    setShapeDeduplication(s_applyDepluication);
-}
-Element2ShapeItem::~Element2ShapeItem() {
-    std::lock_guard guard{s_mutex};
-    s_instances.erase(this);
-}
-void Element2ShapeItem::deduplicateShapes(const bool enable) {
-    std::lock_guard guard{s_mutex};
-    s_applyDepluication = enable;
-    for (Element2ShapeItem* item : s_instances) {
-        item->setShapeDeduplication(enable);
-    }
-}
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/ElementProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/ElementProcessor.cxx
index 40fb3e1b4821ce3ff9fa7a2236389c2c7584e42d..ee6b2562984841f8a33aa519cef67aabaa96652c 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/ElementProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/ElementProcessor.cxx
@@ -28,7 +28,6 @@
 
 using namespace xercesc;
 
-ElementProcessor::ElementProcessor() {}
 
 void ElementProcessor::process(const DOMElement *element, GmxUtil & /* gmxUtil*/, GeoNodeList & /* toAdd */) {
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx
index 86f3e8811c358b7a46c983b69921d96daaef0513..faba526488e15cc10da6faf13f814a0f511d001b 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx
@@ -29,11 +29,17 @@
 #include "GeoModelXml/GmxInterface.h"
 #include "GeoModelXml/createdomdocument.h"
 #include "GeoModelHelpers/MaterialManager.h"
+#include "GeoModelHelpers/throwExcept.h"
 
 using namespace std;
 using namespace xercesc;
 
-Gmx2Geo::Gmx2Geo(const string& xmlFile, GeoVPhysVol *addHere, GmxInterface &gmxInterface, unsigned int flags, bool useMatManager, std::string levelMapName, const processorList& procs) {
+Gmx2Geo::Gmx2Geo(const string& xmlFile, 
+                 GeoVPhysVol *addHere, 
+                 GmxInterface &gmxInterface, 
+                 unsigned int flags,                  
+                 std::string levelMapName, 
+                 const processorList& procs) {
 //
 //    Create the xml tree (DOMDocument)
 //
@@ -45,23 +51,22 @@ Gmx2Geo::Gmx2Geo(const string& xmlFile, GeoVPhysVol *addHere, GmxInterface &gmxI
     DOMDocument *doc = createDOMDocument(xmlFile, parser, flags);
     if (!doc) {// Parsed badly
         XMLPlatformUtils::Terminate();
-        msglog << MSG::FATAL << "Error in xml file " << xmlFile << ". Exiting program." << endmsg;
-	std::abort();
+       THROW_EXCEPTION("Error in xml file " << xmlFile << ". Exiting program." );
     }
 
 //
 //    Set up the CLHEP evaluator and the xml-tag processors, and store the GmxInterface:
 //
     GmxUtil gmxUtil(gmxInterface); 
-    if (useMatManager) gmxUtil.matManager=MaterialManager::getManager();
+    if (gmxInterface.useMaterialManager()) gmxUtil.matManager=MaterialManager::getManager();
 
-// add any additional ElementProcessor
+    // add any additional ElementProcessor
     for (auto pr: procs)
         gmxUtil.processorRegistry.enregister(pr.first,pr.second);
 
-//
-//    Process the xml tree, creating all the GeoModel items and adding to the GeoModel tree.
-//
+    //
+    //    Process the xml tree, creating all the GeoModel items and adding to the GeoModel tree.
+    //
     const DOMElement *root = doc->getDocumentElement();
 //
 //    info message: name of detector
@@ -380,14 +385,14 @@ DOMNodeList *rgs = doc->getElementsByTagName(readoutgeometry_tmp);
 //    Call the user's call back routine to add this sensor type with its specific parameters
 //
                         tableData.push_back(data);
-                        gmxUtil.gmxInterface()->addSensorType(clas, name, stParams);
+                        gmxUtil.gmxInterface().addSensorType(clas, name, stParams);
 
                     //finished loop over first sensorType, so we now should have all the columns for this type
                     columsDefined = true;
                     }
 
                 }
-                gmxUtil.gmxInterface()->publish(clas,colNames,colTypes,tableData);
+                gmxUtil.gmxInterface().publish(clas,colNames,colTypes,tableData);
             }
         }
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxInterface.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxInterface.cxx
index 8c40d0cc32a087caae802615656f60602de34289..2b1a681c2245be2d2f99798861fef5ed9267548e 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxInterface.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxInterface.cxx
@@ -105,15 +105,18 @@ void GmxInterface::addAlignable(int level, map<std::string, int> &index, GeoVFul
     if (m_publisher) m_publisher->publishNode<GeoAlignableTransform *,std::string>(transform,idString.str());
 }
 
-void GmxInterface::addSplitAlignable(int level, map<std::string, int> &index, std::pair<std::string, int> &extraIndex, GeoVFullPhysVol *fpv, 
-                                GeoAlignableTransform * transform) {
+void GmxInterface::addSplitAlignable(int level, 
+                                     std::map<std::string, int> &index, 
+                                     std::pair<std::string, int> &extraIndex, 
+                                     GeoVFullPhysVol* fpv, 
+                                     GeoAlignableTransform* transform) {
    
     std::stringstream idString;
     // debug message
     msglog << MSG::DEBUG 
         << "GmxInterface::addSplitAlignable called for a physvol. Logvol name " 
         << fpv->getLogVol()->getName() << ". Level = " << level << ". Indices:   ";
-    for (map<string, int>::iterator i = index.begin(); i != index.end(); ++i) {
+    for ( map<string, int>::iterator i = index.begin(); i != index.end(); ++i) {
         msglog << i->second << "   ";
         if(i!=index.begin()) idString <<"_";
         idString << i->first <<"_"<<i->second;
@@ -125,6 +128,26 @@ void GmxInterface::addSplitAlignable(int level, map<std::string, int> &index, st
     //--------------
 
     //publish
-    if (m_publisher) m_publisher->publishNode<GeoAlignableTransform *,std::string>(transform,idString.str());
+    if (m_publisher) m_publisher->publishNode<GeoAlignableTransform *,std::string>(transform, idString.str());
 }
+bool GmxInterface::doPhysVolDeDpulication () const{ return m_deDuplicatePhysVols; }
+bool GmxInterface::doLogVolDeDuplication() const{ return m_deDuplicateLogVols; }
+bool GmxInterface::doShapeDeDuplication() const{ return m_deDuplicateShapes; }
+bool GmxInterface::doTransformDeDuplication() const{ return m_deDuplicateTransforms; }
+bool GmxInterface::useMaterialManager() const{ return m_useMatManger; }
 
+void GmxInterface::enableLogVolDeDuplication(bool enable){
+    m_deDuplicateLogVols = enable;
+}
+void GmxInterface::enableShapeDeDuplication(bool enable){
+    m_deDuplicateShapes = enable;
+}
+void GmxInterface::enableTransformDeDuplication(bool enable){
+    m_deDuplicateTransforms = enable;
+}
+void GmxInterface::enablePhysVolDeDuplication(bool enable){
+    m_deDuplicatePhysVols = enable;
+}
+void GmxInterface::enableMaterialManager(bool enable){
+    m_useMatManger = enable;
+}
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxUtil.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxUtil.cxx
index d1a7d70448b0572bb3f3a7aa87162c2670ec38d2..f9e5ff1d31d488c5b1b92d1d5126818fc935449d 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxUtil.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/GmxUtil.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GeoModelXml/GmxUtil.h"
@@ -11,6 +11,7 @@
 #include "GeoModelKernel/GeoBox.h"
 #include "GeoModelKernel/GeoLogVol.h"
 #include "GeoModelXml/GmxInterface.h"
+#include "GeoModelHelpers/throwExcept.h"
 
 #include <cstdlib>
 #include <sstream>
@@ -19,8 +20,21 @@
 
 using namespace std;
 
-GmxUtil::GmxUtil(GmxInterface &gmxInterface) {
-    m_gmxInterface = &gmxInterface;
+GmxUtil::GmxUtil(GmxInterface &gmxInterface):
+    m_gmxInterface{gmxInterface} {
+
+    geoItemRegistry.enableLogVolDeDuplication(gmxInterface.doLogVolDeDuplication());
+    processorRegistry.enableLogVolDeDuplication(gmxInterface.doLogVolDeDuplication());
+
+    geoItemRegistry.enableShapeDeDuplication(gmxInterface.doShapeDeDuplication());
+    processorRegistry.enableShapeDeDuplication(gmxInterface.doShapeDeDuplication());
+
+    geoItemRegistry.enableTransformDeDuplication(gmxInterface.doTransformDeDuplication());
+    processorRegistry.enableTransformDeDuplication(gmxInterface.doTransformDeDuplication());
+
+    geoItemRegistry.enablePhysVolDeDuplication(gmxInterface.doPhysVolDeDpulication());
+    processorRegistry.enablePhysVolDeDuplication(gmxInterface.doPhysVolDeDpulication());
+
 //
 //    Initialise the CLHEP::Evaluator
 //
@@ -47,38 +61,35 @@ GmxUtil::GmxUtil(GmxInterface &gmxInterface) {
     processorRegistry.enregister("replicaRPhi", &tagHandler.replicaRPhi);
     processorRegistry.enregister("replicaXYarrays", &tagHandler.replicaXYArrays);
     processorRegistry.enregister("index", &tagHandler.index);
-//
-//   Register tag handlers that produce GeoNodes. Only useful for those tags which
-//   can appear in a long list in any order. So certainly all shapes; maybe others.
-//
-    geoItemRegistry.enregister("simplepolygonbrep", (Element2GeoItem *) &tagHandler.simplepolygonbrep);
-    geoItemRegistry.enregister("twistedtrap", (Element2GeoItem *) &tagHandler.twistedtrap);
-    geoItemRegistry.enregister("ellipticaltube", (Element2GeoItem *) &tagHandler.ellipticaltube);
-    geoItemRegistry.enregister("torus", (Element2GeoItem *) &tagHandler.torus);
-    geoItemRegistry.enregister("box", (Element2GeoItem *) &tagHandler.box);
-    geoItemRegistry.enregister("cons", (Element2GeoItem *) &tagHandler.cons);
-    geoItemRegistry.enregister("generictrap", (Element2GeoItem *) &tagHandler.generictrap);
-    geoItemRegistry.enregister("para", (Element2GeoItem *) &tagHandler.para);
-    geoItemRegistry.enregister("pcon", (Element2GeoItem *) &tagHandler.pcon);
-    geoItemRegistry.enregister("pgon", (Element2GeoItem *) &tagHandler.pgon);
-    geoItemRegistry.enregister("trap", (Element2GeoItem *) &tagHandler.trap);
-    geoItemRegistry.enregister("trd", (Element2GeoItem *) &tagHandler.trd);
-    geoItemRegistry.enregister("tube", (Element2GeoItem *) &tagHandler.tube);
-    geoItemRegistry.enregister("tubs", (Element2GeoItem *) &tagHandler.tubs);
-    geoItemRegistry.enregister("intersection", (Element2GeoItem *) &tagHandler.intersection);
-    geoItemRegistry.enregister("union", (Element2GeoItem *) &tagHandler.onion); // union is reserved
-    geoItemRegistry.enregister("subtraction", (Element2GeoItem *) &tagHandler.subtraction);
-    geoItemRegistry.enregister("shaperef", (Element2GeoItem *) &tagHandler.shaperef);
-    geoItemRegistry.enregister("transformation", (Element2GeoItem *) &tagHandler.transformation);
-    geoItemRegistry.enregister("transformationref", (Element2GeoItem *) &tagHandler.transformationref);
+    ///
+    ///   Register tag handlers that produce GeoNodes. Only useful for those tags which
+    ///   can appear in a long list in any order. So certainly all shapes; maybe others.
+    ///
+    geoItemRegistry.enregister("simplepolygonbrep",  &tagHandler.simplepolygonbrep);
+    geoItemRegistry.enregister("twistedtrap",  &tagHandler.twistedtrap);
+    geoItemRegistry.enregister("ellipticaltube",  &tagHandler.ellipticaltube);
+    geoItemRegistry.enregister("torus",  &tagHandler.torus);
+    geoItemRegistry.enregister("box",  &tagHandler.box);
+    geoItemRegistry.enregister("cons",  &tagHandler.cons);
+    geoItemRegistry.enregister("generictrap",  &tagHandler.generictrap);
+    geoItemRegistry.enregister("para", &tagHandler.para);
+    geoItemRegistry.enregister("pcon", &tagHandler.pcon);
+    geoItemRegistry.enregister("pgon", &tagHandler.pgon);
+    geoItemRegistry.enregister("trap", &tagHandler.trap);
+    geoItemRegistry.enregister("trd",  &tagHandler.trd);
+    geoItemRegistry.enregister("tube", &tagHandler.tube);
+    geoItemRegistry.enregister("tubs", &tagHandler.tubs);
+    geoItemRegistry.enregister("intersection", &tagHandler.intersection);
+    geoItemRegistry.enregister("union",  &tagHandler.onion); // union is reserved
+    geoItemRegistry.enregister("subtraction",  &tagHandler.subtraction);
+    geoItemRegistry.enregister("shaperef",  &tagHandler.shaperef);
+    geoItemRegistry.enregister("transformation",  &tagHandler.transformation);
+    geoItemRegistry.enregister("transformationref",  &tagHandler.transformationref);
 
     tagHandler.addplane.gmxUtil=this;
 }
 
-GmxUtil::~GmxUtil() {
-}
-
-GmxInterface * GmxUtil::gmxInterface() {
+GmxInterface& GmxUtil::gmxInterface() {
     return m_gmxInterface;
 }
 
@@ -94,7 +105,7 @@ double GmxUtil::evaluate(char const *expression) {
         }
     }
     if (isWhiteSpace) { // Catch a common error early and give best message possible
-        throw runtime_error(string("evaluate: empty or white space expression. Last good expression was " + lastGoodExpression));
+       THROW_EXCEPTION("evaluate: empty or white space expression. Last good expression was " + lastGoodExpression);
 
     }
 //
@@ -108,7 +119,7 @@ double GmxUtil::evaluate(char const *expression) {
 //
     double result = eval.evaluate(noBrackets.c_str());
     if (eval.status() != GeoModelTools::Evaluator::OK) {
-        throw runtime_error(string("evaluate: invalid expression. Last good expression was <" + lastGoodExpression + ">"));
+        THROW_EXCEPTION("evaluate: invalid expression. Last good expression was <" + lastGoodExpression + ">");
     }
     lastGoodExpression = strExpression;
     return result;
@@ -140,26 +151,22 @@ std::string GmxUtil::debracket(std::string expression) {
 
     return debracket(newExpression);
 }
+GeoIntrusivePtr<GeoLogVol>  GmxUtil::makeAssemblyLV() {
 
-GeoLogVol * GmxUtil::makeAssemblyLV() {
-
-    const GeoMaterial *assembly_material =0;
+    GeoIntrusivePtr<const GeoMaterial> assembly_material{nullptr};
     
-    if (matManager)
-    {
-    	assembly_material = matManager->getMaterial("special::HyperUranium");
+    if (matManager) {
+        assembly_material = matManager->getMaterial("special::HyperUranium");
     }
-    else
-    {
-    	GeoMaterial* temp_material = new GeoMaterial("special::HyperUranium", 1.e-20);
-	GeoElement *vacuum = new GeoElement("vacuum", "Mt", 1, 1);
-    	temp_material->add(vacuum, 1.0);
-	temp_material->lock();
-	assembly_material=temp_material;
+    else {
+        GeoMaterial* temp_material = new GeoMaterial("special::HyperUranium", 1.e-20);
+        GeoElement *vacuum = new GeoElement("vacuum", "Mt", 1, 1);
+        temp_material->add(vacuum, 1.0);
+        temp_material->lock();
+        assembly_material=temp_material;
     }
 
     GeoBox *box = new GeoBox(1., 1., 1.); // Simplest shape; it is irrelevant
-    GeoLogVol *lv = new GeoLogVol(string("AssemblyLV"), box, assembly_material);
-    return lv;
-    
+    GeoIntrusivePtr<GeoLogVol> lv{new GeoLogVol(string("AssemblyLV"), box, assembly_material)};
+    return lv;    
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx
index 500d968056ebcd644f20051893ca994ab3e6762c..bd4850c4131f4f35eabb1ab4b2408b5ca7dc4f06 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx
@@ -60,15 +60,10 @@ std::string getNodeType(const GeoGraphNode* node) {
         return "GeoTransform";
     return "UnidentifiedNode";
 }
-LogvolProcessor::LogvolProcessor() {
-    setLogVolDeDuplication(false);
-    setPhysVolDeDuplication(false);
-      
-}
 void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
   GeoLogVolPtr lv{};
-  GeoNameTag *nameTag_physChildVolName;//USed for "sensitive" PhysVols 
-  GeoNameTag *nameTag_physVolName;//Actually the logVol name, which gets used for the PhysVols if they have "named" attribute (and aren't sensitive)
+  GeoIntrusivePtr<GeoNameTag> nameTag_physChildVolName{};//USed for "sensitive" PhysVols 
+  GeoIntrusivePtr<GeoNameTag> nameTag_physVolName{};//Actually the logVol name, which gets used for the PhysVols if they have "named" attribute (and aren't sensitive)
 
   gmxUtil.positionIndex.incrementLevel();
 
@@ -115,19 +110,17 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
 //
   map<string, LogVolStore>::iterator entry;
   if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Name
-//
-    m_map[name] = LogVolStore();
-    LogVolStore *store = &m_map[name];
+    //
+    //    Name
+    //   
+    LogVolStore* store{&m_map[name]};
     if(isNamed) {
-        nameTag_physVolName = new GeoNameTag(name);
+        nameTag_physVolName = make_intrusive<GeoNameTag>(name);
         store->name = nameTag_physVolName;
-    }
-    store->id = 0;
-//
-//    Get the shape.
-//
+    }   
+    //
+    //    Get the shape.
+    //
     DOMDocument *doc = element->getOwnerDocument();
     XMLCh * shape_tmp = XMLString::transcode("shape");
     const XMLCh *shape = element->getAttribute(shape_tmp);
@@ -136,24 +129,23 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     DOMNode *parent = refShape->getParentNode();
     if (XMLString::compareIString(parent->getNodeName(), XMLString::transcode("shapes")) != 0) {
         char* shape_s = XMLString::transcode (shape);
-        msglog << MSG::FATAL << "Processing logvol " << name <<
+        THROW_EXCEPTION("Processing logvol " << name <<
             ". Error in gmx file. An IDREF for a logvol shape did not refer to a shape.\n" <<
-            "Shape ref was " << shape_s << "; exiting" << endmsg;
+            "Shape ref was " << shape_s << "; exiting");
         XMLString::release (&shape_s);
-        std::abort();
     }
-//
-//    What sort of shape?
-//
+    //
+    //    What sort of shape?
+    //
     name2release = XMLString::transcode(refShape->getNodeName());
     string shapeType(name2release);
     XMLString::release(&name2release);
     XMLString::release(&shape_tmp);
 
-    const GeoShape *shGeo = static_cast<const GeoShape *>(gmxUtil.geoItemRegistry.find(shapeType)->process(refShape, gmxUtil));
-//
-//    Get the material
-//
+    GeoIntrusivePtr<const GeoShape> shGeo = dynamic_pointer_cast<const GeoShape>(gmxUtil.geoItemRegistry.find(shapeType)->process(refShape, gmxUtil));
+    //
+    //    Get the material
+    //
     XMLCh * material_tmp = XMLString::transcode("material");
     const XMLCh *material = element->getAttribute(material_tmp);
     DOMElement *refMaterial = doc->getElementById(material);
@@ -170,26 +162,25 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     }
     std::string nam_mat= XMLString::transcode(material);
 
-    const GeoMaterial* matGeo = nullptr;
+    GeoIntrusivePtr<const GeoMaterial> matGeo{};
 
     if (gmxUtil.matManager) {
         if (!gmxUtil.matManager->isMaterialDefined(nam_mat)) {
-            GeoMaterial* tempMat=dynamic_cast<GeoMaterial *>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
+            GeoIntrusivePtr<GeoMaterial> tempMat=dynamic_pointer_cast<GeoMaterial>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
             // we let GMX create the material and store it in the MM
             gmxUtil.matManager->addMaterial(tempMat);
-        }
-        matGeo = gmxUtil.matManager->getMaterial(nam_mat);
+        } matGeo = gmxUtil.matManager->getMaterial(nam_mat);
     } else {
-        matGeo = dynamic_cast<const GeoMaterial *>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
+        matGeo = dynamic_pointer_cast<const GeoMaterial>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
     }
 
     if (!matGeo) {
         THROW_EXCEPTION("Cannot process "<<nam_mat);
     }    
-//
-//    Make the LogVol and add it to the map ready for next time
-//
-    lv = new GeoLogVol(name, shGeo, matGeo);
+    //
+    //    Make the LogVol and add it to the map ready for next time
+    //
+    lv = make_intrusive<GeoLogVol>(name, shGeo, matGeo);
     store->logVol = lv;
 
     XMLString::release(&material_tmp);
@@ -203,24 +194,23 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     lv = entry->second.logVol;
   }
 
-
-//
-//    Process the logvol children (side effect: sets formulae for indexes before calculating them)
-//
-// RMB: Note -- here the code looks for "children of the LogVol" but this is not true: they are PhysVol children. In fact, they are later added to the newly created PhysVol... needs to be clearified/updated
+  //
+  //    Process the logvol children (side effect: sets formulae for indexes before calculating them)
+  //
+  // RMB: Note -- here the code looks for "children of the LogVol" but this is not true: they are PhysVol children. In fact, they are later added to the newly created PhysVol... needs to be clearified/updated
   GeoNodeList childrenAdd;
   for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) {
-    if (child->getNodeType() == DOMNode::ELEMENT_NODE) {
-      DOMElement *el = dynamic_cast<DOMElement *> (child);
-      name2release = XMLString::transcode(el->getNodeName());
-      string name(name2release);
-      XMLString::release(&name2release);
-      gmxUtil.processorRegistry.find(name)->process(el, gmxUtil, childrenAdd);
-    }
+      if (child->getNodeType() == DOMNode::ELEMENT_NODE) {
+        DOMElement *el = dynamic_cast<DOMElement *> (child);
+        name2release = XMLString::transcode(el->getNodeName());
+        string name(name2release);
+        XMLString::release(&name2release);
+        gmxUtil.processorRegistry.find(name)->process(el, gmxUtil, childrenAdd);
+      }
   }
-//
-//   Make a list of things to be added
-//
+  //
+  //   Make a list of things to be added
+  //
   if(isNamed) {
       if(!sensitive) toAdd.push_back(nameTag_physVolName);//If sensitive, it gets a different name in a moment...
   }
@@ -230,7 +220,7 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
   if (sensitive) {
     gmxUtil.positionIndex.setCopyNo(m_map[name].id++);
     gmxUtil.positionIndex.indices(index, gmxUtil.eval);
-    sensId = gmxUtil.gmxInterface()->sensorId(index);
+    sensId = gmxUtil.gmxInterface().sensorId(index);
     std::string newName = name;
     for(auto index_i:index){
             newName.append("_");
@@ -238,16 +228,15 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
             newName.append("_");
             newName.append(std::to_string(index_i.second));
     }
-    nameTag_physChildVolName = new GeoNameTag(newName);//Make sensitive always have a name, to extra Id information from
+    nameTag_physChildVolName = make_intrusive<GeoNameTag>(newName);//Make sensitive always have a name, to extra Id information from
     toAdd.push_back(nameTag_physChildVolName);
     if(hasIdentifier) { //TODO: check if all "sensitive" volumes must have an identifier. If that's the case, then we can remove this "if" here
-        //        toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number
-        toAdd.push_back(new GeoIdentifierTag(sensId));
+        toAdd.push_back(make_intrusive<GeoIdentifierTag>(sensId));
     }
   }
   else {
       if(hasIdentifier) {
-          toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number
+          toAdd.push_back(make_intrusive<GeoIdentifierTag>(m_map[name].id)); // Normal copy number
           gmxUtil.positionIndex.setCopyNo(m_map[name].id++);
       }
   }
@@ -266,7 +255,7 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
 
   if (sensitive || (alignable.compare(string("true")) == 0)) {
     //msglog << MSG::DEBUG << "Handling a FullPhysVol (i.e., an 'alignable' or 'sensitive' volume) ..." << endmsg;
-    GeoFullPhysVol *pv = new GeoFullPhysVol(cacheVolume(lv));
+    GeoIntrusivePtr<GeoFullPhysVol> pv = make_intrusive<GeoFullPhysVol>(cacheVolume(lv));
     if (is_envelope) GeoVolumeTagCatalog::VolumeTagCatalog()->addTaggedVolume("Envelope",name,pv);
     for (const auto& node : childrenAdd) {
 	     pv->add(node);
@@ -293,26 +282,27 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
         for(int i=0;i<splitLevel;i++){
           std::string field = "eta_module";//eventually specify in Xml the field to split in?
           std::pair<std::string,int> extraIndex(field,i);
-          gmxUtil.gmxInterface()->addSplitSensor(sensitiveName, index,extraIndex, sensId, dynamic_cast<GeoVFullPhysVol *> (pv),splitLevel);
+          gmxUtil.gmxInterface().addSplitSensor(sensitiveName, index,extraIndex, sensId, 
+                                                dynamic_pointer_cast<GeoVFullPhysVol> (pv),splitLevel);
         }
 	    }
-	    else gmxUtil.gmxInterface()->addSensor(sensitiveName, index, sensId, dynamic_cast<GeoVFullPhysVol *> (pv));
+	    else gmxUtil.gmxInterface().addSensor(sensitiveName, index, sensId, 
+                                             dynamic_pointer_cast<GeoVFullPhysVol>(pv));
         XMLString::release(&splitLevel_tmp);
     }
   }
   else {
-    //msglog << MSG::DEBUG << "Handling a standard PhysVol..." << endmsg;
-    GeoPhysVol *pv = new GeoPhysVol(cacheVolume(lv));
-    if (is_envelope) GeoVolumeTagCatalog::VolumeTagCatalog()->addTaggedVolume("Envelope",name,pv);
-    //msglog << MSG::DEBUG << "Now, looping over all the children of the LogVol (in the GMX meaning)..." << endmsg; 
-    for (const auto & node : childrenAdd) {
-      pv->add(node);
-      //msglog << MSG::DEBUG << "LVProc, PV child: " << *node << " -- " << getNodeType(*node) << endmsg;
-    }
-    //msglog << MSG::DEBUG << "End of loop over children." << endmsg;
-    toAdd.push_back(cacheVolume(pv).get());
+      //msglog << MSG::DEBUG << "Handling a standard PhysVol..." << endmsg;
+      GeoIntrusivePtr<GeoPhysVol> pv = make_intrusive<GeoPhysVol>(cacheVolume(lv));
+      if (is_envelope) GeoVolumeTagCatalog::VolumeTagCatalog()->addTaggedVolume("Envelope",name,pv);
+      //msglog << MSG::DEBUG << "Now, looping over all the children of the LogVol (in the GMX meaning)..." << endmsg; 
+      for (const auto & node : childrenAdd) {
+        pv->add(node);
+        //msglog << MSG::DEBUG << "LVProc, PV child: " << *node << " -- " << getNodeType(*node) << endmsg;
+      }
+      //msglog << MSG::DEBUG << "End of loop over children." << endmsg;
+      toAdd.push_back(cacheVolume(pv));
   }
-
   gmxUtil.positionIndex.decrementLevel();
   if(gmxUtil.positionIndex.level()==-1){ //should mean that we are at the end of processing the geometry
     gmxUtil.positionIndex.printLevelMap();
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeBox.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeBox.cxx
index 854c5cd445060ff5a1d4f06e066d0b638806f8c1..e9a3033b363f212323917c58c6897a8527268052 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeBox.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeBox.cxx
@@ -13,7 +13,7 @@
 #include <array>
 using namespace xercesc;
 
-RCBase * MakeBox::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase> MakeBox::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
   constexpr int nParams = 3; 
   static const std::array<std::string, nParams> parName{"xhalflength", "yhalflength", "zhalflength"};
   std::array<double, nParams> p{};
@@ -24,6 +24,5 @@ RCBase * MakeBox::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) con
       p[i] = gmxUtil.evaluate(toRelease);
       XMLString::release(&toRelease);
   }
-
-  return const_cast<GeoShape*>(cacheShape(new GeoBox(p[0], p[1], p[2])).get());
+  return const_pointer_cast(cacheShape(make_intrusive<GeoBox>(p[0], p[1], p[2])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeCons.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeCons.cxx
index 799b735d43fe8b05874e92f6b073a0c49bd4c823..9a71cd61263e82b4f9f586af0fe7810b7dcc8ff9 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeCons.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeCons.cxx
@@ -15,7 +15,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeCons::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase> MakeCons::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 7; 
     static const std::array<std::string, nParams> parName{"rmin1", "rmin2", "rmax1", "rmax2", "dz", "sphi", "dphi"};
     std::array<double, nParams> p{};
@@ -26,6 +26,5 @@ RCBase * MakeCons::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
         p[i] = gmxUtil.evaluate(toRelease);
         XMLString::release(&toRelease);
     }
-
-    return const_cast<GeoShape*>(cacheShape(new GeoCons(p[0], p[1], p[2], p[3], p[4], p[5], p[6])).get());
+    return const_pointer_cast(cacheShape(make_intrusive<GeoCons>(p[0], p[1], p[2], p[3], p[4], p[5], p[6])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeElement.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeElement.cxx
index b6c84ba0b56388b1744f88068605123d96b6e256..60883abc81168ab0704a1f4badc43686ec955924 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeElement.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeElement.cxx
@@ -15,22 +15,22 @@ using namespace GeoModelKernelUnits;
 
 MakeElement::MakeElement() {}
 
-RCBase * MakeElement::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakeElement::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
   //std::cout<<"this is MakeElement: make()"<<std::endl;
   char *name, *shortname, *z,*a;
   XMLCh *name_tmp,*shortname_tmp,*z_tmp,*a_tmp;
-  double zVal, aVal;
-//
-//   Get my Z
-//
+  double zVal{0.}, aVal{0.};
+  //
+  //   Get my Z
+  //
   z_tmp = XMLString::transcode("Z");
   z = XMLString::transcode(element->getAttribute(z_tmp));
   zVal = gmxUtil.evaluate(z);
   XMLString::release(&z);
   XMLString::release(&z_tmp);
-//
-//   Get my A
-//
+  //
+  //   Get my A
+  //
   a_tmp = XMLString::transcode("A");
   a = XMLString::transcode(element->getAttribute(a_tmp));
   aVal = gmxUtil.evaluate(a);
@@ -48,22 +48,17 @@ RCBase * MakeElement::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil)
   //
   //aVal *= gram/mole;
 
-  GeoElement *el=0;
-  if (gmxUtil.matManager)
-  {
-  	gmxUtil.matManager->addElement(name, shortname, zVal, aVal);
-	  el=const_cast<GeoElement *>(gmxUtil.matManager->getElement(name));
-    //std::cout<<"MaterialManager: element added "<<el->getName()<<std::endl;
-  }
-  else
-  {
-  	//std::cout<<" making new element "<<name<<" "<<shortname<<" "<<zVal<<" "<<aVal<<std::endl;
-  	el = new GeoElement(name, shortname, zVal, aVal*gram/mole);
+  GeoIntrusivePtr<const GeoElement> el{};
+  if (gmxUtil.matManager) {
+  	  gmxUtil.matManager->addElement(name, shortname, zVal, aVal);
+	    el=gmxUtil.matManager->getElement(name);    
+  } else {
+  	  //std::cout<<" making new element "<<name<<" "<<shortname<<" "<<zVal<<" "<<aVal<<std::endl;
+  	  el = make_intrusive<GeoElement>(name, shortname, zVal, aVal*gram/mole);
   }
   XMLString::release(&name);
   XMLString::release(&shortname);
   XMLString::release(&name_tmp);
   XMLString::release(&shortname_tmp);
-
-  return (RCBase *) el;
+  return const_pointer_cast(el);
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeEllipticalTube.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeEllipticalTube.cxx
index 178f4b022df8671bf53722a150be1545e63954fe..049e154e86df976a04fce394412909506388a43c 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeEllipticalTube.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeEllipticalTube.cxx
@@ -13,7 +13,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeEllipticalTube::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakeEllipticalTube::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 3; 
     static const std::array<std::string, nParams> parName{"xhalflength", "yhalflength", "zhalflength"};
     std::array<double, nParams> p{};
@@ -24,6 +24,5 @@ RCBase * MakeEllipticalTube::make(const xercesc::DOMElement *element, GmxUtil &g
         p[i] = gmxUtil.evaluate(toRelease);
         XMLString::release(&toRelease);
     }
-
-    return  const_cast<GeoShape*>(cacheShape(new GeoEllipticalTube(p[0], p[1], p[2])).get());
+    return  const_pointer_cast(cacheShape(make_intrusive<GeoEllipticalTube>(p[0], p[1], p[2])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeGenericTrap.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeGenericTrap.cxx
index d916c1f7defee402b921f5e45fba98cfaf652ff6..ff7cc6393716917615866f1f9ed27c3a9267cadd 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeGenericTrap.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeGenericTrap.cxx
@@ -19,7 +19,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeGenericTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakeGenericTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 17; 
     std::array<std::string, 17> parName{"x0", "y0", "x1", "y1", "x2", "y2", "x3", "y3", 
                                         "x4", "y4", "x5", "y5", "x6", "y6", "x7", "y7", "zhalflength"};
@@ -43,5 +43,5 @@ RCBase * MakeGenericTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxU
     p = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
 
-    return const_cast<GeoShape*>(cacheShape(new GeoGenericTrap(p, vertices)).get());
+    return const_pointer_cast(cacheShape(make_intrusive<GeoGenericTrap>(p, vertices)));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeIntersection.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeIntersection.cxx
index 8348b666f78498f9a608efb90bfe5e67a106a3c4..d047d0ea30eb7b95ee2e6d0251ea87d8210b05f7 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeIntersection.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeIntersection.cxx
@@ -21,39 +21,37 @@
 using namespace xercesc;
 using namespace std;
 
-RCBase * MakeIntersection::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
-// 
-//    Process child elements; first is first shaperef; then transform; then second shaperef.
-//
+GeoIntrusivePtr<RCBase>MakeIntersection::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+    // 
+    //    Process child elements; first is first shaperef; then transform; then second shaperef.
+    //
     GeoIntrusivePtr<const GeoShape> first{}, second{};
     GeoTrf::Transform3D hepXf=GeoTrf::Transform3D::Identity(); 
     int elementIndex = 0;
     for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) {
         if (child->getNodeType() == DOMNode::ELEMENT_NODE) { // Skips text nodes
-      switch (elementIndex) {
-      case 0: { // First element is first shaperef
-        first.reset(static_cast<const GeoShape *>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil)));
-        break;
-      }
-      case 1:  { // Second element is transformation or transformationref
-        char *toRelease = XMLString::transcode(child->getNodeName());
-        string nodeName(toRelease);
-        XMLString::release(&toRelease);
-        const GeoTransform *geoXf = (nodeName == "transformation")
-          ? static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformation.process(dynamic_cast<DOMElement *>(child), gmxUtil))
-          : static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformationref.process(dynamic_cast<DOMElement *>(child), gmxUtil));
-        hepXf = geoXf->getTransform();
-        break;
-      }
-      case 2: { // Third element is second shaperef
-        second.reset(static_cast<const GeoShape *>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil)));
-        break;
-      }
-      default: // More than 3 elements?
-        THROW_EXCEPTION("MakeIntersection: Incompatible DTD? got more than 3 child elements\n");
-      }
-      elementIndex++;
-        }
+          switch (elementIndex) {
+            case 0: { // First element is first shaperef
+               first = dynamic_pointer_cast<GeoShape>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
+               break;
+            } case 1:  { // Second element is transformation or transformationref
+              char *toRelease = XMLString::transcode(child->getNodeName());
+              string nodeName(toRelease);
+              XMLString::release(&toRelease);
+              GeoTrfPtr geoXf = (nodeName == "transformation") ?
+                      dynamic_pointer_cast<GeoTransform>( gmxUtil.tagHandler.transformation.process(dynamic_cast<DOMElement *>(child), gmxUtil)): 
+                      dynamic_pointer_cast<GeoTransform>( gmxUtil.tagHandler.transformationref.process(dynamic_cast<DOMElement *>(child), gmxUtil));
+              hepXf = geoXf->getTransform();
+              break;
+            } case 2: { // Third element is second shaperef
+              second = dynamic_pointer_cast<GeoShape>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
+              break;
+            }
+            default: // More than 3 elements?
+                THROW_EXCEPTION("MakeIntersection: Incompatible DTD? got more than 3 child elements\n");
+          }
+          elementIndex++;
+       }
     }
 
     if (!first || !second) {
@@ -61,12 +59,10 @@ RCBase * MakeIntersection::make(const xercesc::DOMElement *element, GmxUtil &gmx
     } 
     GeoIntrusivePtr<GeoShapeIntersection> isect{};
     static const GeoTrf::TransformSorter trfSorter{};
-    if (trfSorter.compare(hepXf, GeoTrf::Transform3D::Identity())) {
-        isect = new GeoShapeIntersection(first, new GeoShapeShift(second, hepXf));
+    if (true || trfSorter.compare(hepXf, GeoTrf::Transform3D::Identity())) {
+        isect = make_intrusive<GeoShapeIntersection>(first, make_intrusive<GeoShapeShift>(second, hepXf));
     } else {
-        isect = new GeoShapeIntersection(first, second);
-
-    }
-    std::cout<<isect->refCount()<<std::endl;
-    return const_cast<GeoShape*>(cacheShape(isect).get());
+        isect = make_intrusive<GeoShapeIntersection>(first, second);
+    }   
+    return const_pointer_cast(cacheShape(isect));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeMaterial.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeMaterial.cxx
index cfc7e63a75146bd56b37e971e592a58f9f4a2bf9..32fb289568d8b38ea26eb92ce1375ec392d414e9 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeMaterial.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeMaterial.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GeoModelXml/MakeMaterial.h"
@@ -11,6 +11,7 @@
 #include "xercesc/util/XMLString.hpp"
 #include "GeoModelXml/GmxUtil.h"
 #include "GeoModelKernel/Units.h"
+#include "GeoModelHelpers/throwExcept.h"
 
 using namespace xercesc;
 using namespace std;
@@ -18,64 +19,61 @@ using namespace GeoModelKernelUnits;
 
 MakeMaterial::MakeMaterial() {}
 
-RCBase * MakeMaterial::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
-char *name;
-char *density;
-char *densitySF;
-double rho;
-char *fracString;
-double fraction;
-char *qString;
-XMLCh *ref = XMLString::transcode("ref");
-XMLCh *materials_tmp = XMLString::transcode("materials");
-XMLCh *density_tmp = XMLString::transcode("density");
-XMLCh *densitysf_tmp = XMLString::transcode("densitysf");
-XMLCh *name_tmp = XMLString::transcode("name");
-XMLCh* elementref_tmp = XMLString::transcode("elementref");
-XMLCh *fraction_tmp = XMLString::transcode("fraction");
-XMLCh *chemicalref_tmp = XMLString::transcode("chemicalref");
-XMLCh *elemcontent_tmp = XMLString::transcode("elemcontent");
-XMLCh *quantity_tmp = XMLString::transcode("quantity");
-XMLCh *materialref_tmp = XMLString::transcode("materialref");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
-char *toRelease;
-
-//
-//    Get material density scale-factor for the block of materials this one is in
-//
+GeoIntrusivePtr<RCBase>MakeMaterial::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+    char *name;
+    char *density;
+    char *densitySF;
+    double rho{0.};
+    char *fracString;
+    double fraction{0.};
+    char *qString;
+    XMLCh *ref = XMLString::transcode("ref");
+    XMLCh *materials_tmp = XMLString::transcode("materials");
+    XMLCh *density_tmp = XMLString::transcode("density");
+    XMLCh *densitysf_tmp = XMLString::transcode("densitysf");
+    XMLCh *name_tmp = XMLString::transcode("name");
+    XMLCh* elementref_tmp = XMLString::transcode("elementref");
+    XMLCh *fraction_tmp = XMLString::transcode("fraction");
+    XMLCh *chemicalref_tmp = XMLString::transcode("chemicalref");
+    XMLCh *elemcontent_tmp = XMLString::transcode("elemcontent");
+    XMLCh *quantity_tmp = XMLString::transcode("quantity");
+    XMLCh *materialref_tmp = XMLString::transcode("materialref");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+
+    //
+    //    Get material density scale-factor for the block of materials this one is in
+    //
     DOMNode *parent = element->getParentNode();
     if (XMLString::compareIString(parent->getNodeName(), materials_tmp) != 0) {
-        msglog << MSG::FATAL << "Asked to make a material for non-material element. Parent element was " <<
-                             XMLString::transcode(parent->getNodeName()) << "; error in gmx file; exiting" << endmsg;
-	std::abort();
+       THROW_EXCEPTION("Asked to make a material for non-material element. Parent element was " <<
+                             XMLString::transcode(parent->getNodeName()) << "; error in gmx file; exiting");
     }
     double scaleFactor(1.0);
     DOMElement *el = dynamic_cast<DOMElement *> (parent);
-//    if (el->hasAttribute(XMLString::transcode("densitysf"))) { // Guaranteed by DTD; don't recheck.
-        densitySF = XMLString::transcode(el->getAttribute(densitysf_tmp));
-        scaleFactor = gmxUtil.evaluate(densitySF);
-//    }
-//
-//    Get my name
-//
+    densitySF = XMLString::transcode(el->getAttribute(densitysf_tmp));
+    scaleFactor = gmxUtil.evaluate(densitySF);
+    //
+    //    Get my name
+    //
     name = XMLString::transcode(element->getAttribute(name_tmp));
-//
-//   Get my density
-//
+    //
+    //   Get my density
+    //
     density = XMLString::transcode(element->getAttribute(density_tmp));
     rho = gmxUtil.evaluate(density) * scaleFactor;
     XMLString::release(&density);
-//
-//    Create it
-//
+    //
+    //    Create it
+    //
     //std::cout<<" MakeMaterial: creating material "<<name<<" "<<rho<<std::endl;
-    GeoMaterial *material=new GeoMaterial(name, rho * g/cm3);
+    GeoIntrusivePtr<GeoMaterial> material=  make_intrusive<GeoMaterial>(name, rho * g/cm3);
 
     XMLString::release(&name);
-//
-//   Add my element contents
-//
+    //
+    //   Add my element contents
+    //
     DOMNodeList *elRefs = element->getElementsByTagName(elementref_tmp);
     int nElRefs = elRefs->getLength();
     for (int i = 0; i < nElRefs; ++i) {
@@ -86,40 +84,32 @@ char *toRelease;
         toRelease = XMLString::transcode(elem->getNodeName());
         string nodeName(toRelease);
         XMLString::release(&toRelease);
-        if (nodeName != string("element")) {
-            msglog << MSG::FATAL << "Error in xml/gmx file: An elementref referenced a " << nodeName << " instead of an element."
-                              << endmsg;
-	    std::abort();
-	}
-
-	const GeoElement *geoElem = nullptr;
-	if (gmxUtil.matManager)
-	{
-		name=XMLString::transcode(idref);
-    		if (!gmxUtil.matManager->isElementDefined(name))
-    		{
-		  const GeoElement *temp=static_cast<const GeoElement *>( gmxUtil.tagHandler.element.process(elem, gmxUtil));
-		  //gmxUtil.matManager->addElement(temp);
-    		}
-		geoElem=gmxUtil.matManager->getElement(name);
-		XMLString::release(&name);
-	}
-	else
-	{
-	  geoElem=static_cast<const GeoElement *>( gmxUtil.tagHandler.element.process(elem, gmxUtil));
-	  if (!geoElem) std::cout<<"could not retrieve element!!!!!"<<std::endl;
-  	}
-
-
-  fracString = XMLString::transcode(elRef->getAttribute(fraction_tmp));
-  fraction = gmxUtil.evaluate(fracString);
-  XMLString::release(&fracString);
-  material->add(geoElem, fraction);
-  
-}
-//
-//   Add my chemical contents
-//
+        if (nodeName != "element") {
+            THROW_EXCEPTION("Error in xml/gmx file: An elementref referenced a " << nodeName << " instead of an element.");
+        }
+
+        GeoIntrusivePtr<const GeoElement> geoElem{};
+        if (gmxUtil.matManager) {
+            name=XMLString::transcode(idref);
+            if (!gmxUtil.matManager->isElementDefined(name)) {
+                gmxUtil.tagHandler.element.process(elem, gmxUtil);
+            }
+            geoElem=gmxUtil.matManager->getElement(name);
+            XMLString::release(&name);
+        } else {
+            geoElem= dynamic_pointer_cast<GeoElement>( gmxUtil.tagHandler.element.process(elem, gmxUtil));
+            if (!geoElem) THROW_EXCEPTION("could not retrieve element!!!!!");
+        }
+
+
+        fracString = XMLString::transcode(elRef->getAttribute(fraction_tmp));
+        fraction = gmxUtil.evaluate(fracString);
+        XMLString::release(&fracString);
+        material->add(geoElem, fraction);  
+    }
+    //
+    //   Add my chemical contents
+    //
     DOMNodeList *chemRefs = element->getElementsByTagName(chemicalref_tmp);
     int nChemRefs = chemRefs->getLength();
     
@@ -132,22 +122,18 @@ char *toRelease;
         string nodeName(toRelease);
         XMLString::release(&toRelease);
         if (nodeName != string("chemical")) {
-            msglog << MSG::FATAL << "Error in xml/gmx file: A chemref referenced a " << nodeName << " instead of a chemical." <<
-                                  endmsg;
-	    std::abort();
+            THROW_EXCEPTION("Error in xml/gmx file: A chemref referenced a " << nodeName << " instead of a chemical.");
         }
 
         fracString = XMLString::transcode(chemRef->getAttribute(fraction_tmp));
         fraction = gmxUtil.evaluate(fracString);
         XMLString::release(&fracString);
-
         // Loop over chemical contents, adding each element to this material
         DOMNodeList *chemEls = chem->getElementsByTagName(elemcontent_tmp);
         int nChemEls = chemEls->getLength();
-        vector<const GeoElement *> geoElem;
-        vector<double> atomicWeight;
+        vector<GeoIntrusivePtr<const GeoElement>> geoElem{};
+        vector<double> atomicWeight{}, formula{};
         double molWeight = 0.0;
-        vector<double> formula;
         for (int i = 0; i < nChemEls; ++i) {
             DOMElement *chemEl = dynamic_cast<DOMElement *>(chemEls->item(i));
             idref = chemEl->getAttribute(ref);
@@ -156,21 +142,17 @@ char *toRelease;
             toRelease = XMLString::transcode(elem->getNodeName());
             string nodeName(toRelease);
             XMLString::release(&toRelease);
-            if (nodeName != string("element")) {
-                msglog << MSG::FATAL <<
-                       "Error in xml/gmx file: An elementref referenced a " << nodeName << " instead of an element." << endmsg;
-		std::abort();
+            if (nodeName != "element") {
+                THROW_EXCEPTION("Error in xml/gmx file: An elementref referenced a " << nodeName 
+                                << " instead of an element.");
             }
 
-	    if (gmxUtil.matManager)
-	    {
-		name=XMLString::transcode(idref);
-		geoElem.push_back(gmxUtil.matManager->getElement(name));
-		XMLString::release(&name);
-	    }
-	    else
-	    {
-	      geoElem.push_back(static_cast<const GeoElement *>(gmxUtil.tagHandler.element.process(elem, gmxUtil)));
+            if (gmxUtil.matManager) {
+                name=XMLString::transcode(idref);
+                geoElem.push_back(gmxUtil.matManager->getElement(name));
+                XMLString::release(&name);
+            } else {
+                geoElem.push_back(dynamic_pointer_cast< GeoElement>(gmxUtil.tagHandler.element.process(elem, gmxUtil)));
             }
 
             atomicWeight.push_back(geoElem.back()->getA());
@@ -186,9 +168,9 @@ char *toRelease;
         }
     }
 
-//
-//   Add my material contents
-//
+    //
+    //   Add my material contents
+    //
     elRefs = element->getElementsByTagName(materialref_tmp);
     nElRefs = elRefs->getLength();
     
@@ -200,29 +182,22 @@ char *toRelease;
 
         toRelease = XMLString::transcode(elem->getNodeName());
         string nodeName(toRelease);
-	
-	
+    
+    
         XMLString::release(&toRelease);
-        if (nodeName != string("material")) {
-            msglog << MSG::FATAL <<
-                   "Error in xml/gmx file: A materialref referenced a " << nodeName << " instead of a material." << endmsg;
-            std::abort();
+        if (nodeName != "material") {
+            THROW_EXCEPTION("Error in xml/gmx file: A materialref referenced a " << nodeName << " instead of a material.");
         }
 
-        const GeoMaterial *geoMaterial=0;
-	if (gmxUtil.matManager)
-	{
-		name=XMLString::transcode(idref);
-		geoMaterial=gmxUtil.matManager->getMaterial(name);
-		XMLString::release(&name);
-	}
-	else
-	{
-		
-	        geoMaterial=static_cast<const GeoMaterial *>( gmxUtil.tagHandler.material.process(elem, gmxUtil));
-		if (!geoMaterial) std::cout<<"something is wrong!!!!"<<std::endl;
-  	}
-
+        GeoIntrusivePtr<const GeoMaterial>geoMaterial{};
+        if (gmxUtil.matManager) {
+            name=XMLString::transcode(idref);
+            geoMaterial=gmxUtil.matManager->getMaterial(name);
+            XMLString::release(&name);
+        } else {        
+            geoMaterial= dynamic_pointer_cast<GeoMaterial>( gmxUtil.tagHandler.material.process(elem, gmxUtil));
+            if (!geoMaterial) THROW_EXCEPTION("something is wrong!!!!");
+        }
         fracString = XMLString::transcode(elRef->getAttribute(fraction_tmp));
         fraction = gmxUtil.evaluate(fracString);
         XMLString::release(&fracString);
@@ -231,18 +206,16 @@ char *toRelease;
 
     material->lock(); // Calculate my params and prevent modification
 
-  XMLString::release(&ref);
-  XMLString::release(&materials_tmp);
-  XMLString::release(&density_tmp);
-  XMLString::release(&densitysf_tmp);
-  XMLString::release(&name_tmp);
-  XMLString::release(&elementref_tmp);
-  XMLString::release(&fraction_tmp);
-  XMLString::release(&chemicalref_tmp);
-  XMLString::release(&elemcontent_tmp);
-  XMLString::release(&quantity_tmp);
-  XMLString::release(&materialref_tmp);
-
-
-    return (RCBase *) material;
+    XMLString::release(&ref);
+    XMLString::release(&materials_tmp);
+    XMLString::release(&density_tmp);
+    XMLString::release(&densitysf_tmp);
+    XMLString::release(&name_tmp);
+    XMLString::release(&elementref_tmp);
+    XMLString::release(&fraction_tmp);
+    XMLString::release(&chemicalref_tmp);
+    XMLString::release(&elemcontent_tmp);
+    XMLString::release(&quantity_tmp);
+    XMLString::release(&materialref_tmp);
+    return material;
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePara.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePara.cxx
index edaf9c774ff0f2b562465f35112afeb8b0576cbd..60f685f75fb8c9f15be2252d118577ffdcc29805 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePara.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePara.cxx
@@ -14,7 +14,7 @@
 using namespace xercesc;
 
 
-RCBase * MakePara::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakePara::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 6; 
     static const std::array<std::string, nParams> parName{"xhalflength", "yhalflength", "zhalflength", "alpha", "theta", "phi"};
     std::array<double, nParams> p{};
@@ -26,5 +26,5 @@ RCBase * MakePara::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
         XMLString::release(&toRelease);
     }
 
-    return const_cast<GeoShape*>(cacheShape(new GeoPara(p[0], p[1], p[2], p[3], p[4], p[5])).get());
+    return const_pointer_cast(cacheShape(make_intrusive<GeoPara>(p[0], p[1], p[2], p[3], p[4], p[5])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePcon.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePcon.cxx
index ec658425a18fd66d84c3525c5add4258143022af..e1129d4c948fbed34d46626e9e056928fbbe982d 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePcon.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePcon.cxx
@@ -16,7 +16,7 @@
 using namespace xercesc;
 
 
-RCBase * MakePcon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakePcon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 2; 
     static const std::array<std::string, nParams> parName{"sphi", "dphi"};
     std::array<double, nParams> p{};
@@ -27,7 +27,7 @@ RCBase * MakePcon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
         XMLString::release(&toRelease);
     }
 
-    GeoIntrusivePtr<GeoPcon> pcon{new GeoPcon(p[0], p[1])};
+    GeoIntrusivePtr<GeoPcon> pcon = make_intrusive<GeoPcon>(p[0], p[1]);
     //
     //    Add planes
     //
@@ -46,5 +46,5 @@ RCBase * MakePcon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
     if (!pcon->isValid()) {
         THROW_EXCEPTION("Invalid Pcon defined "<<printGeoShape(pcon));
     }
-    return const_cast<GeoShape*>(cacheShape(pcon).get());
+    return const_pointer_cast(cacheShape(pcon));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePgon.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePgon.cxx
index 36d277c8726681b9dd70c0e1186cca17747a90e6..8cfeac59b04e90f7f07e8de323d84cb193b4747f 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePgon.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakePgon.cxx
@@ -14,7 +14,7 @@
 using namespace xercesc;
 
 
-RCBase * MakePgon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakePgon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 3; 
     static const std::array<std::string, nParams> parName {"sphi", "dphi", "nsides"};
     std::array<double, nParams> p{};
@@ -26,10 +26,10 @@ RCBase * MakePgon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
         XMLString::release(&toRelease);
     }
 
-    GeoIntrusivePtr<GeoPgon> pgon{new GeoPgon(p[0], p[1], p[2])};
-//
-//    Add planes
-//
+    GeoIntrusivePtr<GeoPgon> pgon = make_intrusive<GeoPgon>(p[0], p[1], p[2]);
+    //
+    //    Add planes
+    //
     double zPlane{0.}, rMinPlane{0.}, rMaxPlane{0.};
     for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) {
         if (child->getNodeType() == DOMNode::ELEMENT_NODE) {
@@ -42,5 +42,5 @@ RCBase * MakePgon::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
             }
         }
     }
-    return const_cast<GeoShape*>(cacheShape(pgon).get());
+    return const_pointer_cast(cacheShape(pgon));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeShaperef.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeShaperef.cxx
index ce74ffe59efa0440b23f4d131eb191b3954abfdd..82c29f3ac84b3b330369a2bb701c9b200312091f 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeShaperef.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeShaperef.cxx
@@ -15,38 +15,36 @@
 using namespace std;
 using namespace xercesc;
 
-RCBase *MakeShaperef::process(const DOMElement *element, GmxUtil &gmxUtil) const {
-//
-//    Get the referenced shape
-//
-
+GeoIntrusivePtr<RCBase> MakeShaperef::process(const DOMElement *element, GmxUtil &gmxUtil) const {
+    //
+    //    Get the referenced shape
+    //
     XMLCh * ref_tmp = XMLString::transcode("ref");
     XMLCh * shapes_tmp = XMLString::transcode("shapes");
 
     const XMLCh *idref = element->getAttribute(ref_tmp);
     DOMDocument *doc = element->getOwnerDocument();
     DOMElement *shape = doc->getElementById(idref);
-//
-//    Check it is the right sort: it's parent should be a shapes
-//
+    //
+    //    Check it is the right sort: it's parent should be a shapes
+    //
     DOMNode *parent = shape->getParentNode();
     if (XMLString::compareIString(parent->getNodeName(), shapes_tmp) != 0) {
       char* idref_s = XMLString::transcode (idref);
-      msglog << MSG::FATAL << "Error processing <shaperef> tag: An IDREF for a shape did not refer to a shape.\nShape ref was " << 
-               idref_s << "; exiting" << endmsg;
+      THROW_EXCEPTION("Error processing <shaperef> tag: An IDREF for a shape did not refer to a shape.\nShape ref was " 
+                    << idref_s << "; exiting" );
       XMLString::release (&idref_s);
-      std::abort();
     }
-//
-//    Get what sort of shape
-//
+    //
+    //    Get what sort of shape
+    //
     char *toRelease = XMLString::transcode(shape->getNodeName());
     string tag(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&ref_tmp);
     XMLString::release(&shapes_tmp);
-//
-//    Find and return it
-//
-    return (RCBase *) gmxUtil.geoItemRegistry.find(tag)->process(shape, gmxUtil);
+    //
+    //    Find and return it
+    //
+    return gmxUtil.geoItemRegistry.find(tag)->process(shape, gmxUtil);
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSimplePolygonBrep.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSimplePolygonBrep.cxx
index db7c8b9b3be6be79ef34df4b81d0e1f45724ab8c..7f0411cfff83a036241e1463cdc146888e689662 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSimplePolygonBrep.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSimplePolygonBrep.cxx
@@ -18,7 +18,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeSimplePolygonBrep::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase> MakeSimplePolygonBrep::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 3; 
     static const std::array<std::string, nParams> parName {"xpoints", "ypoints", "zhalflength"};
     double z{0.};
@@ -38,7 +38,7 @@ RCBase * MakeSimplePolygonBrep::make(const xercesc::DOMElement *element, GmxUtil
     z = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
 
-    GeoIntrusivePtr<GeoSimplePolygonBrep> poly{new GeoSimplePolygonBrep(z)};
+    GeoIntrusivePtr<GeoSimplePolygonBrep> poly = make_intrusive<GeoSimplePolygonBrep>(z);
 
     std::istringstream xSS(xPoints);
     while (!xSS.eof()) {
@@ -66,6 +66,6 @@ RCBase * MakeSimplePolygonBrep::make(const xercesc::DOMElement *element, GmxUtil
         poly->addVertex(x[i], y[i]);
     }
 
-    return const_cast<GeoShape*>(cacheShape(poly).get());
+    return const_pointer_cast(cacheShape(poly));
 
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSubtraction.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSubtraction.cxx
index 4ee9be38ad74ae7f796a6cbb1e48715feae403d7..9fa649711cab302fb014c05c60676583fcabd92e 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSubtraction.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeSubtraction.cxx
@@ -20,38 +20,36 @@ using namespace xercesc;
 using namespace std;
 
 
-RCBase * MakeSubtraction::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
-// 
-//    Process child elements; first is first shaperef; then transformation; then second shaperef.
-//
+GeoIntrusivePtr<RCBase>MakeSubtraction::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+    // 
+    //    Process child elements; first is first shaperef; then transformation; then second shaperef.
+    //
     GeoIntrusivePtr<const GeoShape> first{}, second{};
     GeoTrf::Transform3D hepXf=GeoTrf::Transform3D::Identity();
     int elementIndex = 0;
     for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) {
         if (child->getNodeType() == DOMNode::ELEMENT_NODE) { // Skips text nodes
-      switch (elementIndex) {
-      case 0: { // First element is first shaperef
-        first = static_cast<const GeoShape *>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
-        break;
-      }
-      case 1: { // Second element is transformation or transformationref
-        char *toRelease = XMLString::transcode(child->getNodeName());
-        string nodeName(toRelease);
-        XMLString::release(&toRelease);
-        const GeoTransform *geoXf = (nodeName == "transformation")
-          ? static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformation.process(dynamic_cast<DOMElement *>(child), gmxUtil))
-          : static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformationref.process(dynamic_cast<DOMElement *>(child), gmxUtil));
-        hepXf = geoXf->getTransform();
-        break;
-      }
-      case 2: { // Third element is second shaperef
-        second = static_cast<const GeoShape *>( gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
-        break;
-      }
-      default: // More than 3 elements?
-        THROW_EXCEPTION("MakeSubtraction: Incompatible DTD? got more than 3 child elements");
-      }
-      elementIndex++;
+          switch (elementIndex) {
+            case 0: { // First element is first shaperef
+              first = dynamic_pointer_cast<GeoShape>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
+              break;
+            }
+            case 1: { // Second element is transformation or transformationref
+              char *toRelease = XMLString::transcode(child->getNodeName());
+              string nodeName(toRelease);
+              XMLString::release(&toRelease);
+              GeoTrfPtr geoXf = (nodeName == "transformation") ? 
+                    dynamic_pointer_cast<GeoTransform>(gmxUtil.tagHandler.transformation.process(dynamic_cast<DOMElement *>(child), gmxUtil))
+                :   dynamic_pointer_cast<GeoTransform>(gmxUtil.tagHandler.transformationref.process(dynamic_cast<DOMElement *>(child), gmxUtil));
+              hepXf = geoXf->getTransform();
+              break;
+            } case 2: { // Third element is second shaperef
+              second = dynamic_pointer_cast<GeoShape>( gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
+              break;
+            } default: // More than 3 elements?
+              THROW_EXCEPTION("MakeSubtraction: Incompatible DTD? got more than 3 child elements");
+          }
+          elementIndex++;
         }
     }
 
@@ -59,13 +57,12 @@ RCBase * MakeSubtraction::make(const xercesc::DOMElement *element, GmxUtil &gmxU
         THROW_EXCEPTION("Only one of the two subtraction operands was defined.");
     }
 
-  
     GeoIntrusivePtr<GeoShapeSubtraction> subtract{};
     static const GeoTrf::TransformSorter sorter{};
-    if (sorter.compare(hepXf, GeoTrf::Transform3D::Identity())) {
-        subtract = new GeoShapeSubtraction(first, new GeoShapeShift(second, hepXf));
+    if (true || sorter.compare(hepXf, GeoTrf::Transform3D::Identity())) {
+        subtract = make_intrusive<GeoShapeSubtraction>(first, make_intrusive<GeoShapeShift>(second, hepXf));
     } else {
-        subtract = new GeoShapeSubtraction(first, second);
+        subtract = make_intrusive<GeoShapeSubtraction>(first, second);
     }
-    return const_cast<GeoShape*>(cacheShape(subtract).get());
+    return const_pointer_cast(cacheShape(subtract));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTorus.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTorus.cxx
index 923c040e38da2a0a6cbcf4c440eed6edeec5d498..759cdb6b5598b72d8c2a749f55d4a4686ff7c420 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTorus.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTorus.cxx
@@ -16,7 +16,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeTorus::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase> MakeTorus::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
   constexpr int nParams = 5; 
   static const std::array<std::string, nParams> parName {"rmin", "rmax", "rtor", "sphi", "dphi"};
   std::array<double, nParams> p{};
@@ -28,5 +28,5 @@ RCBase * MakeTorus::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) c
       XMLString::release(&toRelease);
   }
 
-  return  const_cast<GeoShape*>(cacheShape(new GeoTorus(p[0], p[1], p[2], p[3], p[4])).get());
+  return const_pointer_cast(cacheShape(make_intrusive<GeoTorus>(p[0], p[1], p[2], p[3], p[4])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformation.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformation.cxx
index fa5fb46c88a04006c8045790a9524c9e297417cd..729adc9cf5bbd46f5366b415d10cd43f4cb1f0b0 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformation.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformation.cxx
@@ -16,16 +16,13 @@
 using namespace xercesc;
 using namespace std;
 
-MakeTransformation::MakeTransformation() {
-    setTransformDeDuplication(false);
-}
 
-RCBase * MakeTransformation::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
-char *name2release;
- GeoTrf::Transform3D hepTransform=GeoTrf::Transform3D::Identity(); // Starts as Identity transform
-//
-//   Add my element contents
-//
+GeoIntrusivePtr<RCBase> MakeTransformation::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+    char *name2release;
+     GeoTrf::Transform3D hepTransform=GeoTrf::Transform3D::Identity(); // Starts as Identity transform
+    //
+    //   Add my element contents
+    //
     for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) {
         if (child->getNodeType() == DOMNode::ELEMENT_NODE) {
             name2release = XMLString::transcode(child->getNodeName());
@@ -37,17 +34,16 @@ char *name2release;
             else if (name == "rotation") {
                 hepTransform = hepTransform * gmxUtil.tagHandler.rotation.getTransform(el, gmxUtil); 
             }
-            else if (name == "scaling") {
-	    
-// TODO: figure out what to do in this case 	    
-//                hepTransform = hepTransform * gmxUtil.tagHandler.scaling.getTransform(el, gmxUtil); 
+            else if (name == "scaling") {	    
+                // TODO: figure out what to do in this case 	    
+                //                hepTransform = hepTransform * gmxUtil.tagHandler.scaling.getTransform(el, gmxUtil); 
             }
             XMLString::release(&name2release);
         }
     }
-//
-//    Create and return GeoModel transform
-//
+    //
+    //    Create and return GeoModel transform
+    //
 
     XMLCh * alignable_tmp = XMLString::transcode("alignable");
     char *toRelease = XMLString::transcode(element->getAttribute(alignable_tmp));
@@ -55,9 +51,7 @@ char *name2release;
     XMLString::release(&toRelease);
     XMLString::release(&alignable_tmp);
     if (alignable.compare(string("true")) == 0) {
-        return (RCBase *) new GeoAlignableTransform(hepTransform);
-    }
-    
-    return makeTransform(hepTransform);
-    
+        return make_intrusive<GeoAlignableTransform>(hepTransform);
+    }    
+    return makeTransform(hepTransform);    
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformationref.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformationref.cxx
index 31215493ea3e4d37bee9e71ad995cbd14dc41dce..9dde7393c4edfea47222f736b188207e3ef020e5 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformationref.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTransformationref.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -16,31 +16,29 @@
 using namespace std;
 using namespace xercesc;
 
-RCBase *MakeTransformationref::make(const DOMElement *element, GmxUtil &gmxUtil) const {
-XMLCh *ref = XMLString::transcode("ref");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
-char *toRelease;
-//
-//    Get the referenced element
-//
+GeoIntrusivePtr<RCBase> MakeTransformationref::make(const DOMElement *element, GmxUtil &gmxUtil) const {
+    XMLCh *ref = XMLString::transcode("ref");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+    //
+    //    Get the referenced element
+    //
     idref = element->getAttribute(ref);
     DOMElement *elem = doc->getElementById(idref);
-//
-//    Check it is the right sort
-//
+    //
+    //    Check it is the right sort
+    //
     toRelease = XMLString::transcode(elem->getNodeName());
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     if (nodeName != string("transformation")) {
-        msglog << MSG::FATAL << "Error in xml/gmx file: transformationref " << XMLString::transcode(idref) << " referenced a " << nodeName << 
-                " instead of a transformation." << endmsg;
-	std::abort();
+        THROW_EXCEPTION("Error in xml/gmx file: transformationref " << XMLString::transcode(idref) 
+                    << " referenced a " << nodeName << " instead of a transformation.");
     }
-//
-//    Process it
-//
+    //
+    //    Process it
+    //
     XMLString::release(&ref);
-    
     return gmxUtil.tagHandler.transformation.process(elem, gmxUtil);
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTranslation.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTranslation.cxx
index 5ca10a7ba7520133a8f2d708cd4ef2a0d05fbe68..075547e690a7991f5502661f1b29d194f794d8db 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTranslation.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTranslation.cxx
@@ -1,11 +1,9 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GeoModelXml/MakeTranslation.h"
 #include <xercesc/dom/DOM.hpp>
-//#include <CLHEP/Geometry/Transform3D.h>
-//#include <CLHEP/Geometry/Vector3D.h>
 #include "xercesc/util/XMLString.hpp"
 #include "GeoModelXml/GmxUtil.h"
 
@@ -13,17 +11,15 @@
 
 #include "GeoModelKernel/GeoDefinitions.h"
 
-MakeTranslation::MakeTranslation() {}
 
 using namespace xercesc;
 //using namespace HepGeom;
-
 GeoTrf::Translate3D MakeTranslation::getTransform(const DOMElement *translation, GmxUtil &gmxUtil) {
 
-const int nParams = 3; 
-static const std::array<std::string, nParams> parName {"x", "y", "z"};
-std::array<double, nParams> p{};
-char *toRelease;
+    const int nParams = 3; 
+    static const std::array<std::string, nParams> parName {"x", "y", "z"};
+    std::array<double, nParams> p{};
+    char *toRelease;
 
     for (int i = 0; i < nParams; ++i) {
         toRelease = XMLString::transcode(translation->getAttribute(XMLString::transcode(parName[i].data())));
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrap.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrap.cxx
index 1f586182848dc68b28c2d43c38d24e01bc47539e..ce37fc1d814f5bde3752e56a2478f0f7b94043f6 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrap.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrap.cxx
@@ -15,7 +15,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase> MakeTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
   constexpr int nParams = 11; 
   static const std::array<std::string, nParams> parName {"zhalflength", "theta", "phi", "dydzn", "dxdyndzn", "dxdypdzn", "angleydzn", "dydzp", "dxdyndzp", "dxdypdzp", "angleydzp"};
   std::array<double, nParams> p{};
@@ -27,7 +27,7 @@ RCBase * MakeTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
         XMLString::release(&toRelease);
     }
 
-    return  const_cast<GeoShape*>(cacheShape(new GeoTrap(p[0], p[1], p[2], p[3], 
-                                                         p[4], p[5], p[6], p[7], 
-                                                         p[8], p[9], p[10])).get());
+    return  const_pointer_cast(cacheShape(make_intrusive<GeoTrap>(p[0], p[1], p[2], p[3], 
+                                                                  p[4], p[5], p[6], p[7], 
+                                                                  p[8], p[9], p[10])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrd.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrd.cxx
index 322c02c9e052bcac5dc31272956daedb46a3885d..5653ac6265ac91ac60ac4c03d14096fd98e1f096 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrd.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTrd.cxx
@@ -15,7 +15,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeTrd::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakeTrd::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 5; 
     static const std::array<std::string, nParams> parName {"xhalflength1", "xhalflength2", "yhalflength1", "yhalflength2", "zhalflength"};
     std::array<double, nParams> p{};
@@ -27,5 +27,5 @@ RCBase * MakeTrd::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) con
         XMLString::release(&toRelease);
     }
 
-    return  const_cast<GeoShape*>(cacheShape(new GeoTrd(p[0], p[1], p[2], p[3], p[4])).get());
+    return const_pointer_cast(cacheShape(make_intrusive<GeoTrd>(p[0], p[1], p[2], p[3], p[4])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTube.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTube.cxx
index 459f5ed8a00b9e7b60718bbdef2e72fed07ceeea..f851f8c6c8edf1d8efe1fd631a70df836cd72838 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTube.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTube.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // Automatically generated code from /home/hessey/prog/gmx2geo/makeshape
@@ -14,8 +14,7 @@
 
 using namespace xercesc;
 
-
-RCBase * MakeTube::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase> MakeTube::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 3; 
     static const std::array<std::string, nParams> parName {"rmin", "rmax", "zhalflength"};
     std::array<double, nParams> p{};
@@ -27,5 +26,5 @@ RCBase * MakeTube::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
         XMLString::release(&toRelease);
     }
 
-    return const_cast<GeoShape*>(cacheShape(new GeoTube(p[0], p[1], p[2])).get());;
+    return const_pointer_cast(cacheShape(make_intrusive<GeoTube>(p[0], p[1], p[2])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTubs.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTubs.cxx
index 9fa63a26a1e76264fdae6383a91af9563c194206..0a7d506797882a02b896b3aca247da710aa98fe4 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTubs.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTubs.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 // Automatically generated code from /home/hessey/prog/gmx2geo/makeshape
@@ -15,7 +15,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeTubs::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase> MakeTubs::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
     constexpr int nParams = 5; 
     static const std::array<std::string, nParams> parName {"rmin", "rmax", "zhalflength", "sphi", "dphi"};
     std::array<double, nParams> p{};
@@ -26,6 +26,5 @@ RCBase * MakeTubs::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) co
         p[i] = gmxUtil.evaluate(toRelease);
         XMLString::release(&toRelease);
     }
-
-    return  const_cast<GeoShape*>(cacheShape(new GeoTubs(p[0], p[1], p[2], p[3], p[4])).get());
+    return const_pointer_cast(cacheShape(make_intrusive<GeoTubs>(p[0], p[1], p[2], p[3], p[4])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTwistedTrap.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTwistedTrap.cxx
index 775662058f6e0afaa374c3c3350db22f4f03aa11..6716552bcdc094bd4cf714eb391ae4f36c43eaba 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTwistedTrap.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeTwistedTrap.cxx
@@ -34,7 +34,7 @@
 using namespace xercesc;
 
 
-RCBase * MakeTwistedTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+GeoIntrusivePtr<RCBase>MakeTwistedTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
   constexpr int nParams = 11; 
   static const std::array<std::string, nParams> parName {"twist", "dz", "theta","phi","dy1","dx1","dx2","dy2","dx3","dx4","alpha"};
   std::array<double, nParams> p{};
@@ -46,7 +46,7 @@ RCBase * MakeTwistedTrap::make(const xercesc::DOMElement *element, GmxUtil &gmxU
         XMLString::release(&toRelease);
     }
 
-    return const_cast<GeoShape*>(cacheShape(new GeoTwistedTrap(p[0], p[1], p[2], p[3], 
-                                                               p[4], p[5], p[6], p[7], 
-                                                               p[8], p[9], p[10])).get());
+    return const_pointer_cast(cacheShape(make_intrusive<GeoTwistedTrap>(p[0], p[1], p[2], p[3], 
+                                                                        p[4], p[5], p[6], p[7], 
+                                                                        p[8], p[9], p[10])));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeUnion.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeUnion.cxx
index fc949f0b2880c2a5a7cc5970a961f9cf8cdc37d6..6ad32a0c25185a39557c43dec4aa65d147cebf61 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeUnion.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MakeUnion.cxx
@@ -16,52 +16,50 @@ using namespace xercesc;
 using namespace std;
 
 
-RCBase * MakeUnion::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
-// 
-//    Process child elements; first is first shaperef; then transform; then second shaperef.
-//
+GeoIntrusivePtr<RCBase>MakeUnion::make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const {
+    // 
+    //    Process child elements; first is first shaperef; then transform; then second shaperef.
+    //
     GeoIntrusivePtr<const GeoShape> first{}, second{};
     GeoTrf::Transform3D hepXf=GeoTrf::Transform3D::Identity();
     int elementIndex = 0;
     for (DOMNode *child = element->getFirstChild(); child != 0; child = child->getNextSibling()) {
         if (child->getNodeType() == DOMNode::ELEMENT_NODE) { // Skips text nodes
-      switch (elementIndex) {
-      case 0: { // First element is first shaperef
-        first = static_cast<GeoShape *>( gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
-        break;
-      }
-      case 1: { // Second element is transformation or transformationref
-        char *toRelease = XMLString::transcode(child->getNodeName());
-        string nodeName(toRelease);
-        XMLString::release(&toRelease);
-        const GeoTransform *geoXf = (nodeName == "transformation")
-          ? static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformation.process(dynamic_cast<DOMElement *>(child), gmxUtil))
-          : static_cast<const GeoTransform *>( gmxUtil.tagHandler.transformationref.process(dynamic_cast<DOMElement *>(child), gmxUtil));
-        hepXf = geoXf->getTransform();
-        break;
-      }
-      case 2: { // Third element is second shaperef
-        second = static_cast<const GeoShape *>( gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
-        break;
-      }
-      default: // More than 3 elements?
-        THROW_EXCEPTION("MakeUnion: Incompatible DTD? got more than 3 child elements");
-      }
-      elementIndex++;
+          switch (elementIndex) {
+            case 0: { // First element is first shaperef
+              first = dynamic_pointer_cast<GeoShape>(gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
+              break;
+            }
+            case 1: { // Second element is transformation or transformationref
+              char *toRelease = XMLString::transcode(child->getNodeName());
+              string nodeName(toRelease);
+              XMLString::release(&toRelease);
+              GeoTrfPtr geoXf = (nodeName == "transformation") ? 
+                    dynamic_pointer_cast<GeoTransform>(gmxUtil.tagHandler.transformation.process(dynamic_cast<DOMElement *>(child), gmxUtil))
+                :   dynamic_pointer_cast<GeoTransform>(gmxUtil.tagHandler.transformationref.process(dynamic_cast<DOMElement *>(child), gmxUtil));
+              hepXf = geoXf->getTransform();
+              break;
+            } case 2: { // Third element is second shaperef
+              second = dynamic_pointer_cast<GeoShape>( gmxUtil.tagHandler.shaperef.process(dynamic_cast<DOMElement *> (child), gmxUtil));
+              break;
+            } default: // More than 3 elements?
+              THROW_EXCEPTION("MakeUnion: Incompatible DTD? got more than 3 child elements");
+          }
+          elementIndex++;
         }
     }
 
     if (!first || !second) {
-		THROW_EXCEPTION("One of the two operands is not defined");
+		    THROW_EXCEPTION("One of the two operands is not defined");
     }
     GeoIntrusivePtr<const GeoShapeUnion> unionShape{};
 
    static const GeoTrf::TransformSorter sorter{};
-    if (sorter.compare(hepXf, GeoTrf::Transform3D::Identity())) {
-        unionShape = new GeoShapeUnion(first, new GeoShapeShift(second,hepXf));
+    if (true || sorter.compare(hepXf, GeoTrf::Transform3D::Identity())) {
+        unionShape = make_intrusive<GeoShapeUnion>(first, make_intrusive<GeoShapeShift>(second,hepXf));
     } else {
-        unionShape = new GeoShapeUnion(first, second);
+        unionShape = make_intrusive<GeoShapeUnion>(first, second);
     }
  
-    return  const_cast<GeoShape*>(cacheShape(unionShape).get());
+    return  const_pointer_cast(cacheShape(unionShape));
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MulticopyProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MulticopyProcessor.cxx
index 192aedf838979d9435db405df47fb94c3e22131a..f4c418b4165e97f1899bdf8ff1d4cee391ed5577 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MulticopyProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/MulticopyProcessor.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -37,33 +37,32 @@
 #include "GeoModelXml/ProcessorRegistry.h"
 #include "GeoModelXml/GmxUtil.h"
 
+#include "GeoModelHelpers/throwExcept.h"
 
 using namespace xercesc;
 using namespace std;
 
-MulticopyProcessor::MulticopyProcessor(){
-    setTransformDeDuplication(false);
-}
+
 void MulticopyProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-char *toRelease;
-XMLCh *ref = XMLString::transcode("ref");
-XMLCh * alignable_tmp = XMLString::transcode("alignable");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+    XMLCh *ref = XMLString::transcode("ref");
+    XMLCh * alignable_tmp = XMLString::transcode("alignable");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
 
     bool alignable = element->hasAttribute(alignable_tmp);
-//
-//    How many copies?
-//
-    int nCopies;
+    //
+    //    How many copies?
+    //
+    int nCopies{0};
     XMLCh * n_tmp = XMLString::transcode("n");
     toRelease = XMLString::transcode(element->getAttribute(n_tmp));
     nCopies = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&n_tmp);
-//
-//    See if it is in the map; if so, xfList is already done. If not, fill xfList.
-//
+    //
+    //    See if it is in the map; if so, xfList is already done. If not, fill xfList.
+    //
     XMLCh * name_tmp = XMLString::transcode("name");
     toRelease = XMLString::transcode(element->getAttribute(name_tmp));
     string name(toRelease);
@@ -72,85 +71,78 @@ DOMDocument *doc = element->getOwnerDocument();
     map<string, GeoNodeList>::iterator entry;
     GeoNodeList *xfList;
     if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Add empty node list to the map
-//
-        m_map[name] = GeoNodeList();
+        //
+        //    Add empty node list to the map
+        //       
         xfList = &m_map[name];
-//
-//    Loopvar Variable name
-//
-        string varname, firstElement;
-	XMLCh * loopvar_tmp = XMLString::transcode("loopvar");
+        //
+        //    Loopvar Variable name
+        //
+        string varname{}, firstElement{};
+        XMLCh * loopvar_tmp = XMLString::transcode("loopvar");
         bool hasVarname = (element->getAttributeNode(loopvar_tmp) != 0);
         if (hasVarname) {
             toRelease = XMLString::transcode(element->getAttribute(loopvar_tmp));
             varname = toRelease;
             XMLString::release(&toRelease);
-	    XMLString::release(&loopvar_tmp);
+            XMLString::release(&loopvar_tmp);
             // Check it is a vector
             firstElement = varname + "_0";
             if (!gmxUtil.eval.findVariable(firstElement.c_str())) {
-                msglog << MSG::FATAL << "Error in .gmx file. Processing multicopy element with name " << name << 
-                ". Found loopvar set to " << varname << ", but no vector with that name has been defined." << endmsg;
-		std::abort();
+                THROW_EXCEPTION("Error in .gmx file. Processing multicopy element with name " << name << 
+                ". Found loopvar set to " << varname << ", but no vector with that name has been defined.");
             }
         }
-//
-//    Get the transformation-element
-//
+        //
+        //    Get the transformation-element
+        //
         DOMElement *elXf = element->getFirstElementChild();
         toRelease = XMLString::transcode(elXf->getNodeName());
         string nodeName(toRelease);
         XMLString::release(&toRelease);
-        Element2GeoItem *xFormProcessor;
+        Element2GeoItem *xFormProcessor{nullptr};
         if (hasVarname) {
             if (nodeName == "transformation") { // OK
-                xFormProcessor = (Element2GeoItem *) &(gmxUtil.tagHandler.transformation);
-            }
-            else { // Not OK
-                msglog << MSG::FATAL << "Error in .gmx file. Processing multicopy element with name " << name <<
-                ". \nIt gives loopvar therefore should have a <transformation> and not a <transformationref> (despite the DTD)\n";
-		std::abort();
+                xFormProcessor = &(gmxUtil.tagHandler.transformation);
+            } else { // Not OK
+                THROW_EXCEPTION("Error in .gmx file. Processing multicopy element with name " << name <<
+                ". \nIt gives loopvar therefore should have a <transformation> and not a <transformationref> (despite the DTD)\n");
+        
             }
+        } else {
+            xFormProcessor = nodeName == "transformation"?(Element2GeoItem*) &(gmxUtil.tagHandler.transformation): 
+                                                          (Element2GeoItem*) &(gmxUtil.tagHandler.transformationref);
         }
-        else {
-            xFormProcessor = nodeName == "transformation"?
-                             (Element2GeoItem *) &(gmxUtil.tagHandler.transformation):
-                             (Element2GeoItem *) &(gmxUtil.tagHandler.transformationref);
-        }
-//
-//    Produce all the transformations
-//
-        GeoAlignableTransform *geoAXf;
-        GeoTransform *geoXf;
+        //
+        //    Produce all the transformations
+        //
+        GeoIntrusivePtr<GeoAlignableTransform> geoAXf{nullptr};
+        GeoIntrusivePtr<GeoTransform> geoXf{nullptr};
         if (hasVarname) {
             for (int i = 0; i < nCopies; ++i) {
                 gmxUtil.eval.setVariable(varname.c_str(), (varname + "_" + to_string(i)).c_str());
                 if (alignable) {
-		  geoAXf = static_cast<GeoAlignableTransform *>( xFormProcessor->make(elXf, gmxUtil));
-		  xfList->push_back((GeoGraphNode *) geoAXf);
+                    geoAXf = dynamic_pointer_cast<GeoAlignableTransform>(xFormProcessor->make(elXf, gmxUtil));
+                    xfList->push_back(geoAXf);
                 }
                 else {
-		  geoXf = static_cast<GeoTransform *>( xFormProcessor->make(elXf, gmxUtil));
-		  xfList->push_back((GeoGraphNode *) geoXf);
+                    geoXf = dynamic_pointer_cast<GeoTransform>( xFormProcessor->make(elXf, gmxUtil));
+                    xfList->push_back(geoXf);
                 }
                 gmxUtil.eval.removeVariable(varname.c_str()); // Avoids a warning status in evaluator
             }
-        }
-        else {
-//
-//    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
-//    No transform (i.e. identity) for the first; so one less transform than objects
-//
-	  GeoTrf::Transform3D hepXf0=GeoTrf::Transform3D::Identity();
+        } else {
+            //
+            //    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
+            //    No transform (i.e. identity) for the first; so one less transform than objects
+            //
+            GeoTrf::Transform3D hepXf0=GeoTrf::Transform3D::Identity();
             if (alignable) {
-	      geoAXf = static_cast<GeoAlignableTransform *>( xFormProcessor->make(elXf, gmxUtil));
-	      hepXf0 = geoAXf->getTransform();
-            }
-            else {
-	      geoXf = static_cast<GeoTransform *>( xFormProcessor->make(elXf, gmxUtil));
-	      hepXf0 = geoXf->getTransform();
+                geoAXf = dynamic_pointer_cast<GeoAlignableTransform>(xFormProcessor->make(elXf, gmxUtil));
+                hepXf0 = geoAXf->getTransform();
+            } else {
+                geoXf = dynamic_pointer_cast<GeoTransform>( xFormProcessor->make(elXf, gmxUtil));
+                hepXf0 = geoXf->getTransform();
             }
             GeoTrf::Transform3D hepXf=GeoTrf::Transform3D::Identity(); // Identity initially
             for (int i = 0; i < nCopies; ++i) {
@@ -158,22 +150,21 @@ DOMDocument *doc = element->getOwnerDocument();
                 hepXf = hepXf0 * hepXf;
             }
         }
-    }
-    else {
+    } else {
         xfList = &entry->second;
     }
-//
-//    Get object to be copied
-//
+    //
+    //    Get object to be copied
+    //
     DOMElement *object = element->getLastElementChild();
     toRelease = XMLString::transcode(object->getNodeName());
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     ElementProcessor *objectProcessor = gmxUtil.processorRegistry.find(nodeName);
-//
-//    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
-//    harmless in case of only one use.
-//
+    //
+    //    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
+    //    harmless in case of only one use.
+    //
     if (nodeName == "logvolref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
@@ -185,63 +176,58 @@ DOMDocument *doc = element->getOwnerDocument();
         gmxUtil.tagHandler.assembly.zeroId(elem);
     }
     else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
-      XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
-      DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
-      if (lvList->getLength() > 0) {
-	const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
-	DOMElement *lv = doc->getElementById(idref);
-	gmxUtil.tagHandler.logvol.zeroId(lv);
-	XMLString::release(&logvolref_tmp);
-      }
-      else {
-	XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
-	DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
-	if (asList->getLength() > 0) {
-	  const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
-	  DOMDocument *doc = element->getOwnerDocument();
-	  DOMElement *as = doc->getElementById(idref);
-	  gmxUtil.tagHandler.assembly.zeroId(as);
-	  XMLString::release(&assemblyref_tmp);
-	}
-	else {
-	  msglog << MSG::FATAL << 
-	    "multicopyprocessor: error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
-                    << "Exiting program" << endmsg;
-	  std::abort();
-	}
-      }
+        XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
+        DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
+        if (lvList->getLength() > 0) {
+            const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
+            DOMElement *lv = doc->getElementById(idref);
+            gmxUtil.tagHandler.logvol.zeroId(lv);
+            XMLString::release(&logvolref_tmp);
+        } else {
+            XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
+            DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
+            if (asList->getLength() > 0) {
+                const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
+                DOMDocument *doc = element->getOwnerDocument();
+                DOMElement *as = doc->getElementById(idref);
+                gmxUtil.tagHandler.assembly.zeroId(as);
+                XMLString::release(&assemblyref_tmp);
+            } else {
+                THROW_EXCEPTION(" error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
+                             << "Exiting program");
+            }
+        }
     }
-//
-//    If alignable, add transformation to DetectorManager via GmxInterface.
-//    (NB. Alignable is messy because it involves both a transformation and an object as well as
-//    the multicopy or transform element to tell us when to insert it and what level of alignment 
-//    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
-//    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
-//    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
-//
-//    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
-//    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
-//    a way now while things are fresh in my mind.
-//
-    int level;
+    //
+    //    If alignable, add transformation to DetectorManager via GmxInterface.
+    //    (NB. Alignable is messy because it involves both a transformation and an object as well as
+    //    the multicopy or transform element to tell us when to insert it and what level of alignment 
+    //    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
+    //    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
+    //    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
+    //
+    //    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
+    //    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
+    //    a way now while things are fresh in my mind.
+    //
+    int level{0};
     if (alignable) {
         istringstream(XMLString::transcode(element->getAttribute(alignable_tmp))) >> level;
     }
-//
-//    Add transforms and physvols etc. to list to be added
-//
+    //
+    //    Add transforms and physvols etc. to list to be added
+    //
     map<string, int> index;
     for (int copy = 0; copy < nCopies; ++copy) {
         toAdd.push_back((*xfList)[copy]);
         int lastTransform = toAdd.size() - 1;
         objectProcessor->process(object, gmxUtil, toAdd);
         if (alignable) {
-
             msglog << "copy = " << copy << "; level = " << level << endmsg;
             msglog << "Add Alignable named ";
-            msglog << ((GeoNameTag *) (toAdd[lastTransform + 1]))->getName();
+            msglog << dynamic_pointer_cast<GeoNameTag>(toAdd[lastTransform + 1])->getName();
             msglog << " with id ";
-            msglog << ((GeoIdentifierTag *) (toAdd[lastTransform + 2]))->getIdentifier() << endmsg;
+            msglog << dynamic_pointer_cast<GeoIdentifierTag>(toAdd[lastTransform + 2])->getIdentifier() << endmsg;
 
             gmxUtil.positionIndex.incrementLevel(); // Logvol has unfortunately already decremented this; temp. restore it
             gmxUtil.positionIndex.indices(index, gmxUtil.eval);
@@ -249,20 +235,22 @@ DOMDocument *doc = element->getOwnerDocument();
             XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel");
             bool split = element->hasAttribute(splitLevel_tmp);
             char* splitString;
-	        int splitLevel = 1;
-	        if (split) {
+            int splitLevel = 1;
+            if (split) {
                 splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp));
                 splitLevel = gmxUtil.evaluate(splitString);
                 XMLString::release(&splitString);
                 for(int i=0;i<splitLevel;i++){
                     std::string field = "eta_module";//eventually specify in Xml the field to split in?
                     std::pair<std::string,int> extraIndex(field,i);
-                    gmxUtil.gmxInterface()->addSplitAlignable(level, index, extraIndex, (GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+                    gmxUtil.gmxInterface().addSplitAlignable(level, index, extraIndex, 
+                                                             dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                             dynamic_pointer_cast<GeoAlignableTransform> (toAdd[lastTransform]));
                 }
             }
-            else gmxUtil.gmxInterface()->addAlignable(level, index, (GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+            else gmxUtil.gmxInterface().addAlignable(level, index, 
+                                                    dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                    dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
             gmxUtil.positionIndex.decrementLevel(); // Put it back where it was
             index.clear();
             XMLString::release(&splitLevel_tmp);
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/ProcessorRegistry.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/ProcessorRegistry.cxx
index 53eedd194683b934ec8360c489718090a3bd9f23..2b81d36e2409f7ef72e7805f860ce9e74356596a 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/ProcessorRegistry.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/ProcessorRegistry.cxx
@@ -1,20 +1,45 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GeoModelXml/ProcessorRegistry.h"
-#include "GeoModelXml/ElementProcessor.h"
 
-ProcessorRegistry::ProcessorRegistry() {
-    m_defaultProcessor = new ElementProcessor(); 
+
+void ProcessorRegistry::enableLogVolDeDuplication(bool enable){
+    m_deDuplicateLogVols = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setLogVolDeDuplication(enable);
+    }
+}
+void ProcessorRegistry::enableShapeDeDuplication(bool enable){
+    m_deDuplicateShapes = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setShapeDeDuplication(enable);
+    }
+}
+void ProcessorRegistry::enableTransformDeDuplication(bool enable) {
+    m_deDuplicateTransforms = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setTransformDeDuplication(enable);
+    }
+}
+void ProcessorRegistry::enablePhysVolDeDuplication(bool enable){
+    m_deDuplicatePhysVols = enable;
+    for (auto& [tagName, proc]: m_processor) {
+        proc->setPhysVolDeDuplication(enable);
+    }
 }
 
 void ProcessorRegistry::enregister(const std::string& tagName, ElementProcessor *processor) {
     m_processor[tagName] = processor;
+    processor->setPhysVolDeDuplication(m_deDuplicatePhysVols);
+    processor->setTransformDeDuplication(m_deDuplicateTransforms);
+    processor->setShapeDeDuplication(m_deDuplicateShapes);
+    processor->setLogVolDeDuplication(m_deDuplicateLogVols);
 }
 
 ElementProcessor * ProcessorRegistry::find(const std::string& name) {
     std::map<std::string, ElementProcessor *>::iterator it = m_processor.find(name);
 
-    return it == m_processor.end()? m_defaultProcessor: it->second;
+    return it == m_processor.end()? m_defaultProcessor.get(): it->second;
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaRPhiProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaRPhiProcessor.cxx
index 85ca13124164caa05711af962f417361ea6bdc54..08987098af789a4d4ed9d617a60a4f9a14ccfaea 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaRPhiProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaRPhiProcessor.cxx
@@ -29,40 +29,37 @@
 using namespace xercesc;
 using namespace std;
 
-ReplicaRPhiProcessor::ReplicaRPhiProcessor(){
-    setTransformDeDuplication(false);
-}
 
 void ReplicaRPhiProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-char *toRelease;
-XMLCh *ref = XMLString::transcode("ref");
-XMLCh * alignable_tmp = XMLString::transcode("alignable");
-XMLCh * skip_tmp = XMLString::transcode("skip");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+    XMLCh *ref = XMLString::transcode("ref");
+    XMLCh * alignable_tmp = XMLString::transcode("alignable");
+    XMLCh * skip_tmp = XMLString::transcode("skip");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
 
     bool alignable = element->hasAttribute(alignable_tmp);
-//
-//    How many copies?
-//
-    int nCopies;
+    //
+    //    How many copies?
+    //
+    int nCopies{0};
     XMLCh * n_tmp = XMLString::transcode("n");
     toRelease = XMLString::transcode(element->getAttribute(n_tmp));
     nCopies = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&n_tmp);
-//
-//   offset in phi
-//
+    //
+    //   offset in phi
+    //
     double offsetPhi=0;
     XMLCh * offset_tmp = XMLString::transcode("offsetPhi");
     toRelease = XMLString::transcode(element->getAttribute(offset_tmp));
     offsetPhi = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&offset_tmp);
-//
-//   step in phi
-//
+    //
+    //   step in phi
+    //
     double stepPhi=0;
     XMLCh * step_tmp = XMLString::transcode("stepPhi");
     toRelease = XMLString::transcode(element->getAttribute(step_tmp));
@@ -70,18 +67,18 @@ DOMDocument *doc = element->getOwnerDocument();
     XMLString::release(&toRelease);
     XMLString::release(&step_tmp);
     
-//
-//  z value
-// 
+    //
+    //  z value
+    // 
     double zVal=0;
     XMLCh * z_tmp = XMLString::transcode("zValue");
     toRelease = XMLString::transcode(element->getAttribute(z_tmp));
     zVal = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&z_tmp);
-//  
-//  radius
-//
+    //  
+    //  radius
+    //
     double radius=0.;
     XMLCh * rad_tmp = XMLString::transcode("radius");
     toRelease = XMLString::transcode(element->getAttribute(rad_tmp));
@@ -89,37 +86,30 @@ DOMDocument *doc = element->getOwnerDocument();
     XMLString::release(&toRelease);
     XMLString::release(&rad_tmp);
     
-//    
-//  skip
-//
+    //    
+    //  skip
+    //
 
     std::vector<int> elementsToSkip;
-    if (element->hasAttribute(skip_tmp))
-    {
-    	toRelease = XMLString::transcode(element->getAttribute(skip_tmp));
-	std::string skip_str(toRelease);
-	//std::cout << "skip string "<<skip_str<<std::endl;
-	std::vector<std::string> parsed = GeoStrUtils::tokenize(skip_str," ");
-	for (auto k : parsed) 
-	{
-		std::vector<std::string> tmp_parsed = GeoStrUtils::tokenize(k, "-");
-		if (tmp_parsed.size()==1) elementsToSkip.push_back(GeoStrUtils::atoi(tmp_parsed[0]));
-		else if (tmp_parsed.size()==2)
-		{
-			int i1=GeoStrUtils::atoi(tmp_parsed[0]);
-			int i2=GeoStrUtils::atoi(tmp_parsed[1]);
-			//std::cout<<" indices "<<i1<<" "<<i2<<std::endl;
-			assert(i1<i2);
-			for (int l=i1;l<i2+1;l++) elementsToSkip.push_back(l);
-		}
-		
-	}
-		
+    if (element->hasAttribute(skip_tmp)) {
+        toRelease = XMLString::transcode(element->getAttribute(skip_tmp));
+        std::string skip_str(toRelease);
+        std::vector<std::string> parsed = GeoStrUtils::tokenize(skip_str," ");
+        for (auto k : parsed)  {
+            std::vector<std::string> tmp_parsed = GeoStrUtils::tokenize(k, "-");
+            if (tmp_parsed.size()==1) elementsToSkip.push_back(GeoStrUtils::atoi(tmp_parsed[0]));
+            else if (tmp_parsed.size()==2) {
+                int i1=GeoStrUtils::atoi(tmp_parsed[0]);
+                int i2=GeoStrUtils::atoi(tmp_parsed[1]);
+                assert(i1<i2);
+                for (int l=i1;l<i2+1;l++) elementsToSkip.push_back(l);
+            }        
+        }        
     }
     
-//
-//    See if it is in the map; if so, xfList is already done. If not, fill xfList.
-//
+    //
+    //    See if it is in the map; if so, xfList is already done. If not, fill xfList.
+    //
     XMLCh * name_tmp = XMLString::transcode("name");
     toRelease = XMLString::transcode(element->getAttribute(name_tmp));
     string name(toRelease);
@@ -128,127 +118,115 @@ DOMDocument *doc = element->getOwnerDocument();
     map<string, GeoNodeList>::iterator entry;
     GeoNodeList *xfList;
     if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Add empty node list to the map
-//
-        m_map[name] = GeoNodeList();
+        //
+        //    Add empty node list to the map
+        //       
         xfList = &m_map[name];
+        //
+        //    Produce all the transformations
+        //
+        GeoIntrusivePtr<GeoAlignableTransform> geoAXf{};
+        GeoIntrusivePtr<GeoTransform> geoXf{};
 
-
-//
-//    Produce all the transformations
-//
-        GeoAlignableTransform *geoAXf;
-        GeoTransform *geoXf;
-
-//
-//    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
-//    No transform (i.e. identity) for the first; so one less transform than objects
-//
-	  GeoTrf::Transform3D hepXf0=GeoTrf::TranslateZ3D(zVal);
-            if (alignable) {
-                geoAXf = new GeoAlignableTransform (hepXf0) ;
-                hepXf0 = geoAXf->getTransform();
-            }
-            else {
-                geoXf = makeTransform (hepXf0);
-                hepXf0 = geoXf->getTransform();
-            }
-	    double angle=offsetPhi;
-            GeoTrf::Transform3D hepXf=hepXf0; 
-            for (int i = 0; i < nCopies; ++i) {
-	    	    hepXf=hepXf0*GeoTrf::TranslateX3D(radius*std::cos(angle))*
-                             GeoTrf::TranslateY3D(radius*std::sin(angle))*
-                             GeoTrf::RotateZ3D(angle);
-                xfList->push_back(makeTransform(hepXf));
-                // hepXf = hepXf * GeoTrf::RotateZ3D(stepPhi) ;
-		angle+=stepPhi;
-            }
-    }
-    else {
+        //
+        //    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
+        //    No transform (i.e. identity) for the first; so one less transform than objects
+        //
+        GeoTrf::Transform3D hepXf0 = GeoTrf::TranslateZ3D(zVal);
+        if (alignable) {
+            geoAXf = make_intrusive<GeoAlignableTransform>(hepXf0);
+            hepXf0 = geoAXf->getTransform();
+        }else {
+            geoXf = makeTransform (hepXf0);
+            hepXf0 = geoXf->getTransform();
+        }
+        double angle=offsetPhi;
+        GeoTrf::Transform3D hepXf=hepXf0; 
+        for (int i = 0; i < nCopies; ++i) {
+            hepXf=hepXf0*GeoTrf::TranslateX3D(radius*std::cos(angle))*
+                            GeoTrf::TranslateY3D(radius*std::sin(angle))*
+                            GeoTrf::RotateZ3D(angle);
+            xfList->push_back(makeTransform(hepXf));
+            // hepXf = hepXf * GeoTrf::RotateZ3D(stepPhi) ;
+            angle+=stepPhi;
+        }
+    } else {
         xfList = &entry->second;
     }
-//
-//    Get object to be copied
-//
+    //
+    //    Get object to be copied
+    //
     DOMElement *object = element->getLastElementChild();
     toRelease = XMLString::transcode(object->getNodeName());
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     ElementProcessor *objectProcessor = gmxUtil.processorRegistry.find(nodeName);
-//
-//    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
-//    harmless in case of only one use.
-//
+    //
+    //    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
+    //    harmless in case of only one use.
+    //
     if (nodeName == "logvolref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.logvol.zeroId(elem);
-    }
-    else if (nodeName == "assemblyref") {
+    } else if (nodeName == "assemblyref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.assembly.zeroId(elem);
+    } else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
+        XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
+        DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
+        if (lvList->getLength() > 0) {
+            const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
+            DOMElement *lv = doc->getElementById(idref);
+            gmxUtil.tagHandler.logvol.zeroId(lv);
+            XMLString::release(&logvolref_tmp);
+        } else {
+            XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
+            DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
+            if (asList->getLength() > 0) {
+                const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
+                DOMDocument *doc = element->getOwnerDocument();
+                DOMElement *as = doc->getElementById(idref);
+                gmxUtil.tagHandler.assembly.zeroId(as);
+                XMLString::release(&assemblyref_tmp);
+            } else {
+                THROW_EXCEPTION("ReplicaXProcessor: error in " << name 
+                            << ". <transform> object was neither assemblyref nor logvolref\nExiting ");    
+            }
+        }
     }
-    else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
-      XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
-      DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
-      if (lvList->getLength() > 0) {
-	const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
-	DOMElement *lv = doc->getElementById(idref);
-	gmxUtil.tagHandler.logvol.zeroId(lv);
-	XMLString::release(&logvolref_tmp);
-      }
-      else {
-	XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
-	DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
-	if (asList->getLength() > 0) {
-	  const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
-	  DOMDocument *doc = element->getOwnerDocument();
-	  DOMElement *as = doc->getElementById(idref);
-	  gmxUtil.tagHandler.assembly.zeroId(as);
-	  XMLString::release(&assemblyref_tmp);
-	}
-	else {
-	  msglog << MSG::FATAL << 
-	    "ReplicaXProcessor: error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
-                    << "Exiting " << endmsg;
-	  exit(999); // Should do better
-	}
-      }
-    }
-//
-//    If alignable, add transformation to DetectorManager via GmxInterface.
-//    (NB. Alignable is messy because it involves both a transformation and an object as well as
-//    the multicopy or transform element to tell us when to insert it and what level of alignment 
-//    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
-//    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
-//    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
-//
-//    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
-//    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
-//    a way now while things are fresh in my mind.
-//
-    int level;
+    //
+    //    If alignable, add transformation to DetectorManager via GmxInterface.
+    //    (NB. Alignable is messy because it involves both a transformation and an object as well as
+    //    the multicopy or transform element to tell us when to insert it and what level of alignment 
+    //    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
+    //    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
+    //    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
+    //
+    //    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
+    //    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
+    //    a way now while things are fresh in my mind.
+    //
+    int level{0};
     if (alignable) {
         istringstream(XMLString::transcode(element->getAttribute(alignable_tmp))) >> level;
     }
-//
-//    Add transforms and physvols etc. to list to be added
-//
+    //
+    //    Add transforms and physvols etc. to list to be added
+    //
     map<string, int> index;
     for (int copy = 0; copy < nCopies; ++copy) {
-    	if (elementsToSkip.size()>0 && std::find(elementsToSkip.begin(),elementsToSkip.end(),copy)!=elementsToSkip.end()) continue;
+        if (elementsToSkip.size()>0 && std::find(elementsToSkip.begin(),elementsToSkip.end(),copy)!=elementsToSkip.end()) continue;
         toAdd.push_back((*xfList)[copy]);
         int lastTransform = toAdd.size() - 1;
         objectProcessor->process(object, gmxUtil, toAdd);
         if (alignable) {
-
             cout << "copy = " << copy << "; level = " << level << endl;
             cout << "\nAdd Alignable named " << endl;
-            cout << ((GeoNameTag *) (toAdd[lastTransform + 1]))->getName() << endl;
+            cout << (dynamic_pointer_cast<GeoNameTag>(toAdd[lastTransform + 1]))->getName() << endl;
             cout << " with id " << endl;
-            cout << ((GeoIdentifierTag *) (toAdd[lastTransform + 2]))->getIdentifier() << endl;
+            cout << (dynamic_pointer_cast<GeoIdentifierTag>(toAdd[lastTransform + 2]))->getIdentifier() << endl;
 
             gmxUtil.positionIndex.incrementLevel(); // Logvol has unfortunately already decremented this; temp. restore it
             gmxUtil.positionIndex.indices(index, gmxUtil.eval);
@@ -256,26 +234,27 @@ DOMDocument *doc = element->getOwnerDocument();
             XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel");
             bool split = element->hasAttribute(splitLevel_tmp);
             char* splitString;
-	        int splitLevel = 1;
-	        if (split) {
+            int splitLevel = 1;
+            if (split) {
                 splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp));
                 splitLevel = gmxUtil.evaluate(splitString);
                 XMLString::release(&splitString);
                 for(int i=0;i<splitLevel;i++){
                     std::string field = "eta_module";//eventually specify in Xml the field to split in?
                     std::pair<std::string,int> extraIndex(field,i);
-                    gmxUtil.gmxInterface()->addSplitAlignable(level, index, extraIndex,(GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+                    gmxUtil.gmxInterface().addSplitAlignable(level, index, extraIndex,
+                                                             dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                             dynamic_pointer_cast< GeoAlignableTransform>(toAdd[lastTransform]));
                 }
             }
-            else gmxUtil.gmxInterface()->addAlignable(level, index, (GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+            else gmxUtil.gmxInterface().addAlignable(level, index, 
+                                                      dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                      dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
             gmxUtil.positionIndex.decrementLevel(); // Put it back where it was
             index.clear();
             XMLString::release(&splitLevel_tmp);
         }
     }
-
     XMLString::release(&ref);
     XMLString::release(&alignable_tmp);
     XMLString::release(&skip_tmp);
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXProcessor.cxx
index a904d524b48f1688087776a4fe10d337baa2f448..1af94d3c13d440a19d0b7f0b91146cb001302b5d 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXProcessor.cxx
@@ -28,38 +28,35 @@
 
 using namespace xercesc;
 using namespace std;
-ReplicaXProcessor::ReplicaXProcessor() {
-    setTransformDeDuplication(false);
-}
 void ReplicaXProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-char *toRelease;
-XMLCh *ref = XMLString::transcode("ref");
-XMLCh * alignable_tmp = XMLString::transcode("alignable");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+    XMLCh *ref = XMLString::transcode("ref");
+    XMLCh * alignable_tmp = XMLString::transcode("alignable");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
 
     bool alignable = element->hasAttribute(alignable_tmp);
-//
-//    How many copies?
-//
-    int nCopies;
+    //
+    //    How many copies?
+    //
+    int nCopies{0};
     XMLCh * n_tmp = XMLString::transcode("n");
     toRelease = XMLString::transcode(element->getAttribute(n_tmp));
     nCopies = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&n_tmp);
-//
-//   offset along X
-//
+    //
+    //   offset along X
+    //
     double offsetX=0;
     XMLCh * offset_tmp = XMLString::transcode("offset");
     toRelease = XMLString::transcode(element->getAttribute(offset_tmp));
     offsetX = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&offset_tmp);
-//
-//   step along X
-//
+    //
+    //   step along X
+    //
     double stepX=0;
     XMLCh * step_tmp = XMLString::transcode("step");
     toRelease = XMLString::transcode(element->getAttribute(step_tmp));
@@ -67,13 +64,12 @@ DOMDocument *doc = element->getOwnerDocument();
     XMLString::release(&toRelease);
     XMLString::release(&step_tmp);
 
-//
-//  skip
-//
+    //
+    //  skip
+    //
     XMLCh * skip_tmp = XMLString::transcode("skip");
     std::vector<int> elementsToSkip;
-    if (element->hasAttribute(skip_tmp))
-    {
+    if (element->hasAttribute(skip_tmp)) {
         toRelease = XMLString::transcode(element->getAttribute(skip_tmp));
         std::string skip_str(toRelease);
         //std::cout << "skip string "<<skip_str<<std::endl;
@@ -92,122 +88,111 @@ DOMDocument *doc = element->getOwnerDocument();
                 }
 
         }
-
     }
 
-//
-//    See if it is in the map; if so, xfList is already done. If not, fill xfList.
-//
+    //
+    //    See if it is in the map; if so, xfList is already done. If not, fill xfList.
+    //
     XMLCh * name_tmp = XMLString::transcode("name");
     toRelease = XMLString::transcode(element->getAttribute(name_tmp));
     string name(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&name_tmp);
-    map<string, GeoNodeList>::iterator entry;
-    GeoNodeList *xfList;
+    std::map<string, GeoNodeList>::iterator entry;
+    GeoNodeList *xfList{};
     if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Add empty node list to the map
-//
-        m_map[name] = GeoNodeList();
+        //
+        //    Add empty node list to the map
+        //    
         xfList = &m_map[name];
-
-
-//
-//    Produce all the transformations
-//
-        GeoAlignableTransform *geoAXf;
-        GeoTransform *geoXf;
-
-//
-//    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
-//    No transform (i.e. identity) for the first; so one less transform than objects
-//
-	  GeoTrf::Transform3D hepXf0=GeoTrf::TranslateX3D(offsetX);
-            if (alignable) {
-                geoAXf = new GeoAlignableTransform (hepXf0) ;
-                hepXf0 = geoAXf->getTransform();
-            } else {
-                geoXf = makeTransform (hepXf0);
-                hepXf0 = geoXf->getTransform();
-            }
-            GeoTrf::Transform3D hepXf=hepXf0; 
-            for (int i = 0; i < nCopies; ++i) {
-                xfList->push_back(makeTransform(hepXf));
-                hepXf = hepXf * GeoTrf::TranslateX3D(stepX) ;
-            }
-    }
-    else {
+        //
+        //    Produce all the transformations
+        //
+        GeoIntrusivePtr<GeoAlignableTransform> geoAXf{};
+        GeoIntrusivePtr<GeoTransform> geoXf{};
+
+        //
+        //    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
+        //    No transform (i.e. identity) for the first; so one less transform than objects
+        //
+        GeoTrf::Transform3D hepXf0=GeoTrf::TranslateX3D(offsetX);
+        if (alignable) {
+            geoAXf = make_intrusive<GeoAlignableTransform>(hepXf0);
+            hepXf0 = geoAXf->getTransform();
+        } else {
+            geoXf = makeTransform (hepXf0);
+            hepXf0 = geoXf->getTransform();
+        }
+        GeoTrf::Transform3D hepXf=hepXf0; 
+        for (int i = 0; i < nCopies; ++i) {
+            xfList->push_back(makeTransform(hepXf));
+            hepXf = hepXf * GeoTrf::TranslateX3D(stepX) ;
+        }
+    }else {
         xfList = &entry->second;
     }
-//
-//    Get object to be copied
-//
+    //
+    //    Get object to be copied
+    //
     DOMElement *object = element->getLastElementChild();
     toRelease = XMLString::transcode(object->getNodeName());
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     ElementProcessor *objectProcessor = gmxUtil.processorRegistry.find(nodeName);
-//
-//    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
-//    harmless in case of only one use.
-//
+    //
+    //    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
+    //    harmless in case of only one use.
+    //
     if (nodeName == "logvolref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.logvol.zeroId(elem);
-    }
-    else if (nodeName == "assemblyref") {
+    } else if (nodeName == "assemblyref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.assembly.zeroId(elem);
+    } else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
+        XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
+        DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
+        if (lvList->getLength() > 0) {
+          const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
+          DOMElement *lv = doc->getElementById(idref);
+          gmxUtil.tagHandler.logvol.zeroId(lv);
+          XMLString::release(&logvolref_tmp);
+        } else {
+            XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
+            DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
+            if (asList->getLength() > 0) {
+              const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
+              DOMDocument *doc = element->getOwnerDocument();
+              DOMElement *as = doc->getElementById(idref);
+              gmxUtil.tagHandler.assembly.zeroId(as);
+              XMLString::release(&assemblyref_tmp);
+            } else {
+                THROW_EXCEPTION("ReplicaXProcessor: error in " << name 
+                             << ". <transform> object was neither assemblyref nor logvolref\n Exiting ");
+            }
+        }
     }
-    else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
-      XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
-      DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
-      if (lvList->getLength() > 0) {
-	const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
-	DOMElement *lv = doc->getElementById(idref);
-	gmxUtil.tagHandler.logvol.zeroId(lv);
-	XMLString::release(&logvolref_tmp);
-      }
-      else {
-	XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
-	DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
-	if (asList->getLength() > 0) {
-	  const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
-	  DOMDocument *doc = element->getOwnerDocument();
-	  DOMElement *as = doc->getElementById(idref);
-	  gmxUtil.tagHandler.assembly.zeroId(as);
-	  XMLString::release(&assemblyref_tmp);
-	}
-	else {
-	  msglog << MSG::FATAL << 
-	    "ReplicaXProcessor: error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
-                    << "Exiting " << endmsg;
-	  exit(999); // Should do better
-	}
-      }
-    }
-//
-//    If alignable, add transformation to DetectorManager via GmxInterface.
-//    (NB. Alignable is messy because it involves both a transformation and an object as well as
-//    the multicopy or transform element to tell us when to insert it and what level of alignment 
-//    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
-//    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
-//    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
-//
-//    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
-//    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
-//    a way now while things are fresh in my mind.
-//
-    int level;
+    //
+    //    If alignable, add transformation to DetectorManager via GmxInterface.
+    //    (NB. Alignable is messy because it involves both a transformation and an object as well as
+    //    the multicopy or transform element to tell us when to insert it and what level of alignment 
+    //    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
+    //    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
+    //    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
+    //
+    //    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
+    //    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
+    //    a way now while things are fresh in my mind.
+    //
+    int level{0};
     if (alignable) {
         istringstream(XMLString::transcode(element->getAttribute(alignable_tmp))) >> level;
     }
-//
-//    Add transforms and physvols etc. to list to be added
-//
+    //
+    //    Add transforms and physvols etc. to list to be added
+    //
     map<string, int> index;
     for (int copy = 0; copy < nCopies; ++copy) {
         if (elementsToSkip.size()>0 && std::find(elementsToSkip.begin(),elementsToSkip.end(),copy)!=elementsToSkip.end()) continue;
@@ -215,12 +200,11 @@ DOMDocument *doc = element->getOwnerDocument();
         int lastTransform = toAdd.size() - 1;
         objectProcessor->process(object, gmxUtil, toAdd);
         if (alignable) {
-
             cout << "copy = " << copy << "; level = " << level << endl;
             cout << "\nAdd Alignable named " << endl;
-            cout << ((GeoNameTag *) (toAdd[lastTransform + 1]))->getName() << endl;
+            cout << (dynamic_pointer_cast<GeoNameTag>(toAdd[lastTransform + 1]))->getName() << endl;
             cout << " with id " << endl;
-            cout << ((GeoIdentifierTag *) (toAdd[lastTransform + 2]))->getIdentifier() << endl;
+            cout << (dynamic_pointer_cast<GeoIdentifierTag>(toAdd[lastTransform + 2]))->getIdentifier() << endl;
 
             gmxUtil.positionIndex.incrementLevel(); // Logvol has unfortunately already decremented this; temp. restore it
             gmxUtil.positionIndex.indices(index, gmxUtil.eval);
@@ -228,26 +212,27 @@ DOMDocument *doc = element->getOwnerDocument();
             XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel");
             bool split = element->hasAttribute(splitLevel_tmp);
             char* splitString;
-	        int splitLevel = 1;
-	        if (split) {
+            int splitLevel = 1;
+            if (split) {
                 splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp));
                 splitLevel = gmxUtil.evaluate(splitString);
                 XMLString::release(&splitString);
                 for(int i=0;i<splitLevel;i++){
                     std::string field = "eta_module";//eventually specify in Xml the field to split in?
                     std::pair<std::string,int> extraIndex(field,i);
-                    gmxUtil.gmxInterface()->addSplitAlignable(level, index, extraIndex,(GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+                    gmxUtil.gmxInterface().addSplitAlignable(level, index, extraIndex,
+                                                             dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                             dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
                 }
             }
-            else gmxUtil.gmxInterface()->addAlignable(level, index, (GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                 (GeoAlignableTransform *) toAdd[lastTransform]);
+            else gmxUtil.gmxInterface().addAlignable(level, index, 
+                                                      dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                      dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
             gmxUtil.positionIndex.decrementLevel(); // Put it back where it was
             index.clear();
             XMLString::release(&splitLevel_tmp);
         }
     }
-
     XMLString::release(&ref);
     XMLString::release(&alignable_tmp);
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXYArrays.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXYArrays.cxx
index d4dff151b6200f8dfb61fb09b9ff47b463cb205f..941cccc0d03561454397e5dc03e2728e11a28155 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXYArrays.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaXYArrays.cxx
@@ -28,15 +28,12 @@
 using namespace xercesc;
 using namespace std;
 
-ReplicaXYarraysProcessor::ReplicaXYarraysProcessor(){
-    setTransformDeDuplication(false);
-}
 void ReplicaXYarraysProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-char *toRelease;
-XMLCh *ref = XMLString::transcode("ref");
-XMLCh * alignable_tmp = XMLString::transcode("alignable");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+    XMLCh *ref = XMLString::transcode("ref");
+    XMLCh * alignable_tmp = XMLString::transcode("alignable");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
 
     bool alignable = element->hasAttribute(alignable_tmp);
     
@@ -45,87 +42,71 @@ DOMDocument *doc = element->getOwnerDocument();
     string name(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&name_tmp);
-//
-//    How many copies?
-//
-    int nCopies;
+    //
+    //    How many copies?
+    //
+    int nCopies{0};
     XMLCh * n_tmp = XMLString::transcode("n");
     toRelease = XMLString::transcode(element->getAttribute(n_tmp));
     nCopies = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&n_tmp);
     
-//
-//    Xcoordinates/Ycoordinates arrays
-//
-        string x_varname,y_varname, firstElement;
-	vector<double> xPos,yPos;
-        XMLCh * loopvar_tmp = XMLString::transcode("xCoordinates");
-        bool hasVarname = (element->getAttributeNode(loopvar_tmp) != 0);
-        if (hasVarname) {
-            toRelease = XMLString::transcode(element->getAttribute(loopvar_tmp));
-            x_varname = toRelease;
-            XMLString::release(&toRelease);
-            XMLString::release(&loopvar_tmp);
-            // Check it is a vector
-            firstElement = x_varname + "_0";
-            if (!gmxUtil.eval.findVariable(firstElement.c_str())) {
-                msglog << MSG::FATAL << "Error in .gmx file. Processing multicopy element with name " << name << 
-                ". Found xCoordinates set to " << x_varname << ", but no vector with that name has been defined." << endmsg;
-                exit(999); // Should do better
-            }
-	    else
-	    {
-	    	for (int i=0;i<nCopies;i++)
-		{
-		  ostringstream tempstr;
-		  tempstr<<x_varname + "_"<<i;
-		  if (!gmxUtil.eval.findVariable((tempstr.str()).c_str()))
-		  {
-		  	msglog << MSG::FATAL << "Error whem evaluating xPos, "<<tempstr.str()<<" not found!!"<<endmsg;
-			exit(999); // Should do better
-		  }
-		  else 
-		  	xPos.push_back(gmxUtil.evaluate(tempstr.str().c_str()));
-		}
-	    }
+    //
+    //    Xcoordinates/Ycoordinates arrays
+    //
+    string x_varname,y_varname, firstElement;
+    vector<double> xPos{}, yPos{};
+    XMLCh * loopvar_tmp = XMLString::transcode("xCoordinates");
+    bool hasVarname = (element->getAttributeNode(loopvar_tmp) != 0);
+    if (hasVarname) {
+        toRelease = XMLString::transcode(element->getAttribute(loopvar_tmp));
+        x_varname = toRelease;
+        XMLString::release(&toRelease);
+        XMLString::release(&loopvar_tmp);
+        // Check it is a vector
+        firstElement = x_varname + "_0";
+        if (!gmxUtil.eval.findVariable(firstElement.c_str())) {
+            THROW_EXCEPTION("Error in .gmx file. Processing multicopy element with name " << name << 
+            ". Found xCoordinates set to " << x_varname << ", but no vector with that name has been defined.");           
         }
-	loopvar_tmp = XMLString::transcode("yCoordinates");
-        hasVarname = (element->getAttributeNode(loopvar_tmp) != 0);
-        if (hasVarname) {
-            toRelease = XMLString::transcode(element->getAttribute(loopvar_tmp));
-            y_varname = toRelease;
-            XMLString::release(&toRelease);
-            XMLString::release(&loopvar_tmp);
-            // Check it is a vector
-            firstElement = y_varname + "_0";
-            if (!gmxUtil.eval.findVariable(firstElement.c_str())) {
-                msglog << MSG::FATAL << "Error in .gmx file. Processing multicopy element with name " << name << 
-                ". Found yCoordinates set to " << y_varname << ", but no vector with that name has been defined." << endmsg;
-                exit(999); // Should do better
-            }
-	    else
-	    {
-	    	for (int i=0;i<nCopies;i++)
-		{
-		  ostringstream tempstr;
-		  tempstr<<y_varname + "_"<<i;
-		  if (!gmxUtil.eval.findVariable(tempstr.str().c_str()))
-		  {
-		  	msglog << MSG::FATAL << "Error whem evaluating xPos, "<<tempstr.str()<<" not found!!"<<endmsg;
-			exit(999); // Should do better
-		  }
-		  else 
-		  	yPos.push_back(gmxUtil.evaluate(tempstr.str().c_str()));
-		}
-	    }
+        
+        for (int i=0;i<nCopies;++i) {
+          ostringstream tempstr;
+          tempstr<<x_varname + "_"<<i;
+          if (!gmxUtil.eval.findVariable((tempstr.str()).c_str())){
+            THROW_EXCEPTION("Error whem evaluating xPos, "<<tempstr.str()<<" not found!!");
+          }
+          xPos.push_back(gmxUtil.evaluate(tempstr.str().c_str()));
         }
-
-
-    
-//
-//  z value
-// 
+        
+    }
+    loopvar_tmp = XMLString::transcode("yCoordinates");
+    hasVarname = (element->getAttributeNode(loopvar_tmp) != 0);
+    if (hasVarname) {
+        toRelease = XMLString::transcode(element->getAttribute(loopvar_tmp));
+        y_varname = toRelease;
+        XMLString::release(&toRelease);
+        XMLString::release(&loopvar_tmp);
+        // Check it is a vector
+        firstElement = y_varname + "_0";
+        if (!gmxUtil.eval.findVariable(firstElement.c_str())) {
+            THROW_EXCEPTION("Error in .gmx file. Processing multicopy element with name " << name << 
+            ". Found yCoordinates set to " << y_varname << ", but no vector with that name has been defined.");
+        }
+       
+        for (int i=0;i<nCopies;++i) {
+            ostringstream tempstr;
+            tempstr<<y_varname + "_"<<i;
+            if (!gmxUtil.eval.findVariable(tempstr.str().c_str())) {
+              THROW_EXCEPTION("Error whem evaluating xPos, "<<tempstr.str()<<" not found!!");            
+            }         
+            yPos.push_back(gmxUtil.evaluate(tempstr.str().c_str()));
+        }        
+    }
+    //
+    //  z value
+    // 
     double zVal=0;
     XMLCh * z_tmp = XMLString::transcode("zValue");
     toRelease = XMLString::transcode(element->getAttribute(z_tmp));
@@ -133,128 +114,114 @@ DOMDocument *doc = element->getOwnerDocument();
     XMLString::release(&toRelease);
     XMLString::release(&z_tmp);
 
-//
-//    See if it is in the map; if so, xfList is already done. If not, fill xfList.
-//
-
+    //
+    //    See if it is in the map; if so, xfList is already done. If not, fill xfList.
+    //
     map<string, GeoNodeList>::iterator entry;
-    GeoNodeList *xfList;
+    GeoNodeList *xfList{nullptr};
     if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Add empty node list to the map
-//
-        m_map[name] = GeoNodeList();
+        //
+        //    Add empty node list to the map
+        //        
         xfList = &m_map[name];
-
-
-//
-//    Produce all the transformations
-//
-        GeoAlignableTransform *geoAXf;
-        GeoTransform *geoXf;
-
-//
-//    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
-//    No transform (i.e. identity) for the first; so one less transform than objects
-//
-	  GeoTrf::Transform3D hepXf0=GeoTrf::Transform3D::Identity();
-            if (alignable) {
-                geoAXf = new GeoAlignableTransform (hepXf0) ;
-                hepXf0 = geoAXf->getTransform();
-            }
-            else {
-                geoXf = makeTransform (hepXf0);
-                hepXf0 = geoXf->getTransform();
-            }
-            GeoTrf::Transform3D hepXf=hepXf0; 
-            for (int i = 0; i < nCopies; ++i) {
-	     	hepXf = GeoTrf::TranslateZ3D(zVal)*GeoTrf::TranslateX3D(xPos[i]) * GeoTrf::TranslateY3D(yPos[i]);
-                xfList->push_back(makeTransform(hepXf));
-            }
-    }
-    else {
+        //
+        //    Produce all the transformations
+        //
+        GeoIntrusivePtr<GeoAlignableTransform> geoAXf{};
+        GeoIntrusivePtr<GeoTransform> geoXf{};
+        //
+        //    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
+        //    No transform (i.e. identity) for the first; so one less transform than objects
+        //
+        GeoTrf::Transform3D hepXf0=GeoTrf::Transform3D::Identity();
+        if (alignable) {
+            geoAXf = make_intrusive<GeoAlignableTransform>(hepXf0) ;
+            hepXf0 = geoAXf->getTransform();
+        } else {
+            geoXf = makeTransform (hepXf0);
+            hepXf0 = geoXf->getTransform();
+        }
+        GeoTrf::Transform3D hepXf=hepXf0; 
+        for (int i = 0; i < nCopies; ++i) {
+            hepXf = GeoTrf::Translate3D(xPos[i], yPos[i], zVal);
+            xfList->push_back(makeTransform(hepXf));
+        }
+    }else {
         xfList = &entry->second;
     }
-//
-//    Get object to be copied
-//
+    //
+    //    Get object to be copied
+    //
     DOMElement *object = element->getLastElementChild();
     toRelease = XMLString::transcode(object->getNodeName());
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     ElementProcessor *objectProcessor = gmxUtil.processorRegistry.find(nodeName);
-//
-//    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
-//    harmless in case of only one use.
-//
+    //
+    //    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
+    //    harmless in case of only one use.
+    //
     if (nodeName == "logvolref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.logvol.zeroId(elem);
-    }
-    else if (nodeName == "assemblyref") {
+    } else if (nodeName == "assemblyref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.assembly.zeroId(elem);
+    } else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
+        XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
+        DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
+        if (lvList->getLength() > 0) {
+            const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
+            DOMElement *lv = doc->getElementById(idref);
+            gmxUtil.tagHandler.logvol.zeroId(lv);
+            XMLString::release(&logvolref_tmp);
+        } else {
+            XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
+            DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
+            if (asList->getLength() > 0) {
+                const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
+                DOMDocument *doc = element->getOwnerDocument();
+                DOMElement *as = doc->getElementById(idref);
+                gmxUtil.tagHandler.assembly.zeroId(as);
+                XMLString::release(&assemblyref_tmp);
+            } else {
+            THROW_EXCEPTION("ReplicaXProcessor: error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
+                      << "Exiting ");
+             }
+        }
     }
-    else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
-      XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
-      DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
-      if (lvList->getLength() > 0) {
-	const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
-	DOMElement *lv = doc->getElementById(idref);
-	gmxUtil.tagHandler.logvol.zeroId(lv);
-	XMLString::release(&logvolref_tmp);
-      }
-      else {
-	XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
-	DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
-	if (asList->getLength() > 0) {
-	  const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
-	  DOMDocument *doc = element->getOwnerDocument();
-	  DOMElement *as = doc->getElementById(idref);
-	  gmxUtil.tagHandler.assembly.zeroId(as);
-	  XMLString::release(&assemblyref_tmp);
-	}
-	else {
-	  msglog << MSG::FATAL << 
-	    "ReplicaXProcessor: error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
-                    << "Exiting " << endmsg;
-	  exit(999); // Should do better
-	}
-      }
-    }
-//
-//    If alignable, add transformation to DetectorManager via GmxInterface.
-//    (NB. Alignable is messy because it involves both a transformation and an object as well as
-//    the multicopy or transform element to tell us when to insert it and what level of alignment 
-//    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
-//    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
-//    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
-//
-//    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
-//    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
-//    a way now while things are fresh in my mind.
-//
-    int level;
+    //
+    //    If alignable, add transformation to DetectorManager via GmxInterface.
+    //    (NB. Alignable is messy because it involves both a transformation and an object as well as
+    //    the multicopy or transform element to tell us when to insert it and what level of alignment 
+    //    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
+    //    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
+    //    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
+    //
+    //    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
+    //    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
+    //    a way now while things are fresh in my mind.
+    //
+    int level{0};
     if (alignable) {
         istringstream(XMLString::transcode(element->getAttribute(alignable_tmp))) >> level;
     }
-//
-//    Add transforms and physvols etc. to list to be added
-//
+    //
+    //    Add transforms and physvols etc. to list to be added
+    //
     map<string, int> index;
     for (int copy = 0; copy < nCopies; ++copy) {
         toAdd.push_back((*xfList)[copy]);
         int lastTransform = toAdd.size() - 1;
         objectProcessor->process(object, gmxUtil, toAdd);
         if (alignable) {
-
             cout << "copy = " << copy << "; level = " << level << endl;
             cout << "\nAdd Alignable named " << endl;
-            cout << ((GeoNameTag *) (toAdd[lastTransform + 1]))->getName() << endl;
+            cout << (dynamic_pointer_cast<GeoNameTag>(toAdd[lastTransform + 1]))->getName() << endl;
             cout << " with id " << endl;
-            cout << ((GeoIdentifierTag *) (toAdd[lastTransform + 2]))->getIdentifier() << endl;
+            cout << (dynamic_pointer_cast<GeoIdentifierTag>(toAdd[lastTransform + 2]))->getIdentifier() << endl;
 
             gmxUtil.positionIndex.incrementLevel(); // Logvol has unfortunately already decremented this; temp. restore it
             gmxUtil.positionIndex.indices(index, gmxUtil.eval);
@@ -262,20 +229,21 @@ DOMDocument *doc = element->getOwnerDocument();
             XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel");
             bool split = element->hasAttribute(splitLevel_tmp);
             char* splitString;
-	        int splitLevel = 1;
-	        if (split) {
+            int splitLevel = 1;
+            if (split) {
                 splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp));
                 splitLevel = gmxUtil.evaluate(splitString);
                 XMLString::release(&splitString);
                 for(int i=0;i<splitLevel;i++){
                     std::string field = "eta_module";//eventually specify in Xml the field to split in?
                     std::pair<std::string,int> extraIndex(field,i);
-                    gmxUtil.gmxInterface()->addSplitAlignable(level, index, extraIndex,(GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+                    gmxUtil.gmxInterface().addSplitAlignable(level, index, extraIndex,
+                                                             dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                             dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
                 }
-            }
-            else gmxUtil.gmxInterface()->addAlignable(level, index, (GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                 (GeoAlignableTransform *) toAdd[lastTransform]);
+            } else gmxUtil.gmxInterface().addAlignable(level, index, 
+                                                     dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                     dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
             gmxUtil.positionIndex.decrementLevel(); // Put it back where it was
             index.clear();
             XMLString::release(&splitLevel_tmp);
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaYProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaYProcessor.cxx
index ee38fbfb96efb0ce975426dce5cc71e7e30b976a..3f7b15f883d655b12cceae1cb48911824d111de7 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaYProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaYProcessor.cxx
@@ -23,201 +23,182 @@
 using namespace xercesc;
 using namespace std;
 
-ReplicaYProcessor::ReplicaYProcessor(){
-    setTransformDeDuplication(false);
-}
-
 
 void ReplicaYProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-char *toRelease;
-XMLCh *ref = XMLString::transcode("ref");
-XMLCh * alignable_tmp = XMLString::transcode("alignable");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+    XMLCh *ref = XMLString::transcode("ref");
+    XMLCh * alignable_tmp = XMLString::transcode("alignable");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
 
     bool alignable = element->hasAttribute(alignable_tmp);
-//
-//    How many copies?
-//
-    int nCopies;
+    //
+    //    How many copies?
+    //
+    int nCopies{0};
     XMLCh * n_tmp = XMLString::transcode("n");
     toRelease = XMLString::transcode(element->getAttribute(n_tmp));
     nCopies = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&n_tmp);
-//
-//   offset along Y
-//
+    //
+    //   offset along Y
+    //
     double offsetY=0;
     XMLCh * offset_tmp = XMLString::transcode("offset");
     toRelease = XMLString::transcode(element->getAttribute(offset_tmp));
     offsetY = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&offset_tmp);
-//
-//   step along Y
-//
+    //
+    //   step along Y
+    //
     double stepY=0;
     XMLCh * step_tmp = XMLString::transcode("step");
     toRelease = XMLString::transcode(element->getAttribute(step_tmp));
     stepY = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&step_tmp);
-
-//   
-//  skip
-//
+    //   
+    //  skip
+    //
     XMLCh * skip_tmp = XMLString::transcode("skip");
     std::vector<int> elementsToSkip;
-    if (element->hasAttribute(skip_tmp))
-    {   
+    if (element->hasAttribute(skip_tmp)) {   
         toRelease = XMLString::transcode(element->getAttribute(skip_tmp));
         std::string skip_str(toRelease);
         //std::cout << "skip string "<<skip_str<<std::endl;
         std::vector<std::string> parsed = GeoStrUtils::tokenize(skip_str," ");
         for (const std::string& k : parsed) {       
-                std::vector<std::string> tmp_parsed = GeoStrUtils::tokenize(k,"-");
-                if (tmp_parsed.size()==1) elementsToSkip.push_back(GeoStrUtils::atoi(tmp_parsed[0]));
-                else if (tmp_parsed.size()==2)
-                {       
-                        int i1=GeoStrUtils::atoi(tmp_parsed[0]);
-                        int i2=GeoStrUtils::atoi(tmp_parsed[1]);
-                        //std::cout<<" indices "<<i1<<" "<<i2<<std::endl;
-                        assert(i1<i2);
-                        for (int l=i1;l<i2+1;l++) elementsToSkip.push_back(l);
-                }
-         
-        }
-     
+            std::vector<std::string> tmp_parsed = GeoStrUtils::tokenize(k,"-");
+            if (tmp_parsed.size()==1) elementsToSkip.push_back(GeoStrUtils::atoi(tmp_parsed[0]));
+            else if (tmp_parsed.size()==2) {       
+                int i1=GeoStrUtils::atoi(tmp_parsed[0]);
+                int i2=GeoStrUtils::atoi(tmp_parsed[1]);
+                //std::cout<<" indices "<<i1<<" "<<i2<<std::endl;
+                assert(i1<i2);
+                for (int l=i1;l<i2+1;l++) elementsToSkip.push_back(l);
+            }         
+        }     
     }
 
-//
-//    See if it is in the map; if so, xfList is already done. If not, fill xfList.
-//
+    //
+    //    See if it is in the map; if so, xfList is already done. If not, fill xfList.
+    //
     XMLCh * name_tmp = XMLString::transcode("name");
     toRelease = XMLString::transcode(element->getAttribute(name_tmp));
     string name(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&name_tmp);
     map<string, GeoNodeList>::iterator entry;
-    GeoNodeList *xfList;
+    GeoNodeList *xfList{nullptr};
     if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Add empty node list to the map
-//
-        m_map[name] = GeoNodeList();
+        //
+        //    Add empty node list to the map
+        //
         xfList = &m_map[name];
 
 
-//
-//    Produce all the transformations
-//
-        GeoAlignableTransform *geoAXf;
-        GeoTransform *geoXf;
-
-//
-//    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
-//    No transform (i.e. identity) for the first; so one less transform than objects
-//
-	  GeoTrf::Transform3D hepXf0=GeoTrf::TranslateY3D(offsetY);
-            if (alignable) {
-                geoAXf = new GeoAlignableTransform (hepXf0) ;
-                hepXf0 = geoAXf->getTransform();
-            }
-            else {
-                geoXf = makeTransform (hepXf0);
-                hepXf0 = geoXf->getTransform();
-            }
-            GeoTrf::Transform3D hepXf=hepXf0; 
-            for (int i = 0; i < nCopies; ++i) {
-                xfList->push_back(makeTransform(hepXf));
-                hepXf = hepXf * GeoTrf::TranslateY3D(stepY) ;
-            }
-    }
-    else {
+        //
+        //    Produce all the transformations
+        //
+        GeoIntrusivePtr<GeoAlignableTransform> geoAXf{};
+        GeoIntrusivePtr<GeoTransform> geoXf{};
+        //
+        //    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
+        //    No transform (i.e. identity) for the first; so one less transform than objects
+        //
+        GeoTrf::Transform3D hepXf0=GeoTrf::TranslateY3D(offsetY);
+        if (alignable) {
+            geoAXf = make_intrusive<GeoAlignableTransform>(hepXf0);
+            hepXf0 = geoAXf->getTransform();
+        } else {
+            geoXf = makeTransform (hepXf0);
+            hepXf0 = geoXf->getTransform();
+        }
+        GeoTrf::Transform3D hepXf=hepXf0; 
+        for (int i = 0; i < nCopies; ++i) {
+            xfList->push_back(makeTransform(hepXf));
+            hepXf = hepXf * GeoTrf::TranslateY3D(stepY) ;
+        }
+    } else {
         xfList = &entry->second;
     }
-//
-//    Get object to be copied
-//
+    //
+    //    Get object to be copied
+    //
     DOMElement *object = element->getLastElementChild();
     toRelease = XMLString::transcode(object->getNodeName());
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     ElementProcessor *objectProcessor = gmxUtil.processorRegistry.find(nodeName);
-//
-//    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
-//    harmless in case of only one use.
-//
+    //
+    //    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
+    //    harmless in case of only one use.
+    //
     if (nodeName == "logvolref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.logvol.zeroId(elem);
-    }
-    else if (nodeName == "assemblyref") {
+    } else if (nodeName == "assemblyref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.assembly.zeroId(elem);
+    } else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
+        XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
+        DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
+        if (lvList->getLength() > 0) {
+            const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
+            DOMElement *lv = doc->getElementById(idref);
+            gmxUtil.tagHandler.logvol.zeroId(lv);
+            XMLString::release(&logvolref_tmp);
+        } else {
+            XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
+            DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
+            if (asList->getLength() > 0) {
+                const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
+                DOMDocument *doc = element->getOwnerDocument();
+                DOMElement *as = doc->getElementById(idref);
+                gmxUtil.tagHandler.assembly.zeroId(as);
+                XMLString::release(&assemblyref_tmp);
+            } else {
+                THROW_EXCEPTION("ReplicaYProcessor: error in " << name 
+                            << ". <transform> object was neither assemblyref nor logvolref\n Exiting ");
+     
+            }
+        }
     }
-    else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
-      XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
-      DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
-      if (lvList->getLength() > 0) {
-	const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
-	DOMElement *lv = doc->getElementById(idref);
-	gmxUtil.tagHandler.logvol.zeroId(lv);
-	XMLString::release(&logvolref_tmp);
-      }
-      else {
-	XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
-	DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
-	if (asList->getLength() > 0) {
-	  const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
-	  DOMDocument *doc = element->getOwnerDocument();
-	  DOMElement *as = doc->getElementById(idref);
-	  gmxUtil.tagHandler.assembly.zeroId(as);
-	  XMLString::release(&assemblyref_tmp);
-	}
-	else {
-	  msglog << MSG::FATAL << 
-	    "ReplicaYProcessor: error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
-                    << "Exiting " << endmsg;
-	  exit(999); // Should do better
-	}
-      }
-    }
-//
-//    If alignable, add transformation to DetectorManager via GmxInterface.
-//    (NB. Alignable is messy because it involves both a transformation and an object as well as
-//    the multicopy or transform element to tell us when to insert it and what level of alignment 
-//    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
-//    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
-//    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
-//
-//    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
-//    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
-//    a way now while things are fresh in my mind.
-//
-    int level;
+    //
+    //    If alignable, add transformation to DetectorManager via GmxInterface.
+    //    (NB. Alignable is messy because it involves both a transformation and an object as well as
+    //    the multicopy or transform element to tell us when to insert it and what level of alignment 
+    //    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
+    //    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
+    //    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
+    //
+    //    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
+    //    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
+    //    a way now while things are fresh in my mind.
+    //
+    int level{0};
     if (alignable) {
         istringstream(XMLString::transcode(element->getAttribute(alignable_tmp))) >> level;
     }
-//
-//    Add transforms and physvols etc. to list to be added
-//
-    map<string, int> index;
+    //
+    //    Add transforms and physvols etc. to list to be added
+    //
+    std::map<string, int> index;
     for (int copy = 0; copy < nCopies; ++copy) {
         if (elementsToSkip.size()>0 && std::find(elementsToSkip.begin(),elementsToSkip.end(),copy)!=elementsToSkip.end()) continue;
         toAdd.push_back((*xfList)[copy]);
         int lastTransform = toAdd.size() - 1;
         objectProcessor->process(object, gmxUtil, toAdd);
         if (alignable) {
-
             cout << "copy = " << copy << "; level = " << level << endl;
             cout << "\nAdd Alignable named " << endl;
-            cout << ((GeoNameTag *) (toAdd[lastTransform + 1]))->getName() << endl;
+            cout << (dynamic_pointer_cast<GeoNameTag>(toAdd[lastTransform + 1]))->getName() << endl;
             cout << " with id " << endl;
-            cout << ((GeoIdentifierTag *) (toAdd[lastTransform + 2]))->getIdentifier() << endl;
+            cout << (dynamic_pointer_cast<GeoIdentifierTag>(toAdd[lastTransform + 2]))->getIdentifier() << endl;
 
             gmxUtil.positionIndex.incrementLevel(); // Logvol has unfortunately already decremented this; temp. restore it
             gmxUtil.positionIndex.indices(index, gmxUtil.eval);
@@ -225,26 +206,26 @@ DOMDocument *doc = element->getOwnerDocument();
             XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel");
             bool split = element->hasAttribute(splitLevel_tmp);
             char* splitString;
-	        int splitLevel = 1;
-	        if (split) {
+            int splitLevel = 1;
+            if (split) {
                 splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp));
                 splitLevel = gmxUtil.evaluate(splitString);
                 XMLString::release(&splitString);
                 for(int i=0;i<splitLevel;i++){
                     std::string field = "eta_module";//eventually specify in Xml the field to split in?
                     std::pair<std::string,int> extraIndex(field,i);
-                    gmxUtil.gmxInterface()->addSplitAlignable(level, index, extraIndex,(GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+                    gmxUtil.gmxInterface().addSplitAlignable(level, index, extraIndex,
+                                                             dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                             dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
                 }
-            }
-            else gmxUtil.gmxInterface()->addAlignable(level, index, (GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                 (GeoAlignableTransform *) toAdd[lastTransform]);
+            } else gmxUtil.gmxInterface().addAlignable(level, index, 
+                                                        dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                        dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
             gmxUtil.positionIndex.decrementLevel(); // Put it back where it was
             index.clear();
             XMLString::release(&splitLevel_tmp);
         }
     }
-
     XMLString::release(&ref);
     XMLString::release(&alignable_tmp);
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaZProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaZProcessor.cxx
index 7340f0eac95d8fece288eafefa17ec93b228c262..5c493bbbd06e369e14dc5ac35588f6cac413575e 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaZProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/ReplicaZProcessor.cxx
@@ -19,6 +19,8 @@
 #include "GeoModelKernel/GeoNameTag.h"
 #include "GeoModelKernel/GeoDefinitions.h"
 #include "GeoModelHelpers/StringUtils.h"
+#include "GeoModelHelpers/throwExcept.h"
+
 
 #include "xercesc/util/XMLString.hpp"
 #include "GeoModelXml/GeoNodeList.h"
@@ -30,80 +32,66 @@
 using namespace xercesc;
 using namespace std;
 
-
-ReplicaZProcessor::ReplicaZProcessor(){
-    setTransformDeDuplication(false);
-}
-
-
 void ReplicaZProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-char *toRelease;
-XMLCh *ref = XMLString::transcode("ref");
-XMLCh * alignable_tmp = XMLString::transcode("alignable");
-const XMLCh *idref;
-DOMDocument *doc = element->getOwnerDocument();
+    char *toRelease;
+    XMLCh *ref = XMLString::transcode("ref");
+    XMLCh * alignable_tmp = XMLString::transcode("alignable");
+    const XMLCh *idref;
+    DOMDocument *doc = element->getOwnerDocument();
 
     bool alignable = element->hasAttribute(alignable_tmp);
-//
-//    How many copies?
-//
-    int nCopies;
+    //
+    //    How many copies?
+    //
+    int nCopies{0};
     XMLCh * n_tmp = XMLString::transcode("n");
     toRelease = XMLString::transcode(element->getAttribute(n_tmp));
     nCopies = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&n_tmp);
-//
-//   offset along Z
-//
+    //
+    //   offset along Z
+    //
     double offsetZ=0;
     XMLCh * offset_tmp = XMLString::transcode("offset");
     toRelease = XMLString::transcode(element->getAttribute(offset_tmp));
     offsetZ = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&offset_tmp);
-//
-//   step along Z
-//
-    double stepZ=0;
+    //
+    //   step along Z
+    //
+    double stepZ{0};
     XMLCh * step_tmp = XMLString::transcode("step");
     toRelease = XMLString::transcode(element->getAttribute(step_tmp));
     stepZ = gmxUtil.evaluate(toRelease);
     XMLString::release(&toRelease);
     XMLString::release(&step_tmp);
-
-//  
-//  skip
-//
+    //  
+    //  skip
+    //
     XMLCh * skip_tmp = XMLString::transcode("skip");
     std::vector<int> elementsToSkip;
-    if (element->hasAttribute(skip_tmp))
-    {
+    if (element->hasAttribute(skip_tmp)) {
         toRelease = XMLString::transcode(element->getAttribute(skip_tmp));
         std::string skip_str(toRelease);
         //std::cout << "skip string "<<skip_str<<std::endl;
         std::vector<std::string> parsed = GeoStrUtils::tokenize(skip_str," ");
-        for (auto k : parsed)
-        {
-                std::vector<std::string> tmp_parsed =GeoStrUtils::tokenize(k,"-");
-                if (tmp_parsed.size()==1) elementsToSkip.push_back(GeoStrUtils::atoi(tmp_parsed[0]));
-                else if (tmp_parsed.size()==2)
-                {
-                        int i1=GeoStrUtils::atoi(tmp_parsed[0]);
-                        int i2=GeoStrUtils::atoi(tmp_parsed[1]);
-                        //std::cout<<" indices "<<i1<<" "<<i2<<std::endl;
-                        assert(i1<i2);
-                        for (int l=i1;l<i2+1;l++) elementsToSkip.push_back(l);
-                }
-
+        for (auto k : parsed) {
+            std::vector<std::string> tmp_parsed =GeoStrUtils::tokenize(k,"-");
+            if (tmp_parsed.size()==1) elementsToSkip.push_back(GeoStrUtils::atoi(tmp_parsed[0]));
+            else if (tmp_parsed.size()==2) {
+                int i1=GeoStrUtils::atoi(tmp_parsed[0]);
+                int i2=GeoStrUtils::atoi(tmp_parsed[1]);
+                //std::cout<<" indices "<<i1<<" "<<i2<<std::endl;
+                assert(i1<i2);
+                for (int l=i1;l<i2+1;l++) elementsToSkip.push_back(l);
+            }
         }
-
     }
-
-
-//
-//    See if it is in the map; if so, xfList is already done. If not, fill xfList.
-//
+    //
+    //    See if it is in the map; if so, xfList is already done. If not, fill xfList.
+    //
     XMLCh * name_tmp = XMLString::transcode("name");
     toRelease = XMLString::transcode(element->getAttribute(name_tmp));
     string name(toRelease);
@@ -112,109 +100,98 @@ DOMDocument *doc = element->getOwnerDocument();
     map<string, GeoNodeList>::iterator entry;
     GeoNodeList *xfList;
     if ((entry = m_map.find(name)) == m_map.end()) { // Not in registry; make a new item
-//
-//    Add empty node list to the map
-//
-        m_map[name] = GeoNodeList();
+        //
+        //    Add empty node list to the map
+        //
         xfList = &m_map[name];
-
-
-//
-//    Produce all the transformations
-//
-        GeoAlignableTransform *geoAXf;
-        GeoTransform *geoXf;
-
-//
-//    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
-//    No transform (i.e. identity) for the first; so one less transform than objects
-//
-	  GeoTrf::Transform3D hepXf0=GeoTrf::TranslateZ3D(offsetZ);
-            if (alignable) {
-                geoAXf = new GeoAlignableTransform (hepXf0) ;
-                hepXf0 = geoAXf->getTransform();
-            }
-            else {
-                geoXf = makeTransform (hepXf0);
-                hepXf0 = geoXf->getTransform();
-            }
-            GeoTrf::Transform3D hepXf=hepXf0; 
-            for (int i = 0; i < nCopies; ++i) {
-                xfList->push_back(makeTransform(hepXf));
-                hepXf = hepXf * GeoTrf::TranslateZ3D(stepZ) ;
-            }
-    }
-    else {
+        //
+        //    Produce all the transformations
+        //
+        GeoIntrusivePtr<GeoAlignableTransform> geoAXf{};
+        GeoIntrusivePtr<GeoTransform> geoXf{};
+
+        //
+        //    If varname not given, we get the CLHEP xForm and raise it to the power i, so NOT applied to first object.
+        //    No transform (i.e. identity) for the first; so one less transform than objects
+        //
+        GeoTrf::Transform3D hepXf0=GeoTrf::TranslateZ3D(offsetZ);
+        if (alignable) {
+            geoAXf = make_intrusive<GeoAlignableTransform>(hepXf0) ;
+            hepXf0 = geoAXf->getTransform();
+        } else {
+            geoXf = makeTransform (hepXf0);
+            hepXf0 = geoXf->getTransform();
+        }
+        GeoTrf::Transform3D hepXf=hepXf0; 
+        for (int i = 0; i < nCopies; ++i) {
+            xfList->push_back(makeTransform(hepXf));
+            hepXf = hepXf * GeoTrf::TranslateZ3D(stepZ) ;
+        }
+    } else {
         xfList = &entry->second;
     }
-//
-//    Get object to be copied
-//
+    //
+    //    Get object to be copied
+    //
     DOMElement *object = element->getLastElementChild();
     toRelease = XMLString::transcode(object->getNodeName());
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     ElementProcessor *objectProcessor = gmxUtil.processorRegistry.find(nodeName);
-//
-//    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
-//    harmless in case of only one use.
-//
+    //
+    //    Zero its copy number. Only needed if an item is used in 2 or more multicopies;
+    //    harmless in case of only one use.
+    //
     if (nodeName == "logvolref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.logvol.zeroId(elem);
-    }
-    else if (nodeName == "assemblyref") {
+    } else if (nodeName == "assemblyref") {
         idref = object->getAttribute(ref);
         DOMElement *elem = doc->getElementById(idref);
         gmxUtil.tagHandler.assembly.zeroId(elem);
+    } else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
+        XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
+        DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
+        if (lvList->getLength() > 0) {
+            const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
+            DOMElement *lv = doc->getElementById(idref);
+            gmxUtil.tagHandler.logvol.zeroId(lv);
+            XMLString::release(&logvolref_tmp);
+        } else {
+            XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
+            DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
+            if (asList->getLength() > 0) {
+                const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
+                DOMDocument *doc = element->getOwnerDocument();
+                DOMElement *as = doc->getElementById(idref);
+                gmxUtil.tagHandler.assembly.zeroId(as);
+                XMLString::release(&assemblyref_tmp);
+            } else {
+                THROW_EXCEPTION("ReplicaYProcessor: error in " << name 
+                            << ". <transform> object was neither assemblyref nor logvolref\nExiting ");
+            }
+        }
     }
-    else if (nodeName == "transform") { // Object is either an assemlyref or logvolref, and there is only one of these
-      XMLCh * logvolref_tmp = XMLString::transcode("logvolref");
-      DOMNodeList *lvList = element->getElementsByTagName(logvolref_tmp);
-      if (lvList->getLength() > 0) {
-	const XMLCh *idref =  dynamic_cast<DOMElement *> (lvList->item(0))->getAttribute(ref);
-	DOMElement *lv = doc->getElementById(idref);
-	gmxUtil.tagHandler.logvol.zeroId(lv);
-	XMLString::release(&logvolref_tmp);
-      }
-      else {
-	XMLCh * assemblyref_tmp = XMLString::transcode("assemblyref") ;
-	DOMNodeList *asList = element->getElementsByTagName(assemblyref_tmp);
-	if (asList->getLength() > 0) {
-	  const XMLCh *idref =  dynamic_cast<DOMElement *> (asList->item(0))->getAttribute(ref);
-	  DOMDocument *doc = element->getOwnerDocument();
-	  DOMElement *as = doc->getElementById(idref);
-	  gmxUtil.tagHandler.assembly.zeroId(as);
-	  XMLString::release(&assemblyref_tmp);
-	}
-	else {
-	  msglog << MSG::FATAL << 
-	    "ReplicaYProcessor: error in " << name << ". <transform> object was neither assemblyref nor logvolref\n"
-                    << "Exiting " << endmsg;
-	  exit(999); // Should do better
-	}
-      }
-    }
-//
-//    If alignable, add transformation to DetectorManager via GmxInterface.
-//    (NB. Alignable is messy because it involves both a transformation and an object as well as
-//    the multicopy or transform element to tell us when to insert it and what level of alignment 
-//    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
-//    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
-//    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
-//
-//    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
-//    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
-//    a way now while things are fresh in my mind.
-//
-    int level;
+    //
+    //    If alignable, add transformation to DetectorManager via GmxInterface.
+    //    (NB. Alignable is messy because it involves both a transformation and an object as well as
+    //    the multicopy or transform element to tell us when to insert it and what level of alignment 
+    //    is wanted; and passing info from one routine to another when you try to keep a uniform interface is 
+    //    difficult; and we only have partial GeoModel trees so we cannot use GeoModel tree traversal at this 
+    //    moment (comes back to no way of knowing if we have a GeoFullPV or GeoPV)).
+    //
+    //    Also: no one is using it at the time of writing, so it is ***TOTALLY*** untested.
+    //    It is done now to (i) make sure there ought to be a solution (ii) implement (imperfectly) 
+    //    a way now while things are fresh in my mind.
+    //
+    int level{0};
     if (alignable) {
         istringstream(XMLString::transcode(element->getAttribute(alignable_tmp))) >> level;
     }
-//
-//    Add transforms and physvols etc. to list to be added
-//
+    //
+    //    Add transforms and physvols etc. to list to be added
+    //
     map<string, int> index;
     for (int copy = 0; copy < nCopies; ++copy) {
         if (elementsToSkip.size()>0 && std::find(elementsToSkip.begin(),elementsToSkip.end(),copy)!=elementsToSkip.end()) continue;
@@ -222,12 +199,11 @@ DOMDocument *doc = element->getOwnerDocument();
         int lastTransform = toAdd.size() - 1;
         objectProcessor->process(object, gmxUtil, toAdd);
         if (alignable) {
-
             cout << "copy = " << copy << "; level = " << level << endl;
             cout << "\nAdd Alignable named " << endl;
-            cout << ((GeoNameTag *) (toAdd[lastTransform + 1]))->getName() << endl;
+            cout << (dynamic_pointer_cast<GeoNameTag>(toAdd[lastTransform + 1]))->getName() << endl;
             cout << " with id " << endl;
-            cout << ((GeoIdentifierTag *) (toAdd[lastTransform + 2]))->getIdentifier() << endl;
+            cout << (dynamic_pointer_cast<GeoIdentifierTag>(toAdd[lastTransform + 2]))->getIdentifier() << endl;
 
             gmxUtil.positionIndex.incrementLevel(); // Logvol has unfortunately already decremented this; temp. restore it
             gmxUtil.positionIndex.indices(index, gmxUtil.eval);
@@ -235,20 +211,22 @@ DOMDocument *doc = element->getOwnerDocument();
             XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel");
             bool split = element->hasAttribute(splitLevel_tmp);
             char* splitString;
-	        int splitLevel = 1;
-	        if (split) {
+            int splitLevel = 1;
+            if (split) {
                 splitString = XMLString::transcode(element->getAttribute(splitLevel_tmp));
                 splitLevel = gmxUtil.evaluate(splitString);
                 XMLString::release(&splitString);
                 for(int i=0;i<splitLevel;i++){
                     std::string field = "eta_module";//eventually specify in Xml the field to split in?
                     std::pair<std::string,int> extraIndex(field,i);
-                    gmxUtil.gmxInterface()->addSplitAlignable(level, index, extraIndex,(GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                    (GeoAlignableTransform *) toAdd[lastTransform]);
+                    gmxUtil.gmxInterface().addSplitAlignable(level, index, extraIndex,
+                                                    dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                    dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
                 }
             }
-            else gmxUtil.gmxInterface()->addAlignable(level, index, (GeoVFullPhysVol *) toAdd[lastTransform + 3],
-                                                 (GeoAlignableTransform *) toAdd[lastTransform]);
+            else gmxUtil.gmxInterface().addAlignable(level, index, 
+                                                     dynamic_pointer_cast<GeoVFullPhysVol>(toAdd[lastTransform + 3]),
+                                                     dynamic_pointer_cast<GeoAlignableTransform>(toAdd[lastTransform]));
             gmxUtil.positionIndex.decrementLevel(); // Put it back where it was
             index.clear();
             XMLString::release(&splitLevel_tmp);
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
index 1c31e8b3c6cc310cc1bc8c4dcaa7c8d8cbc7dc63..85127dacb0687814989ac8312457d6db399e8301 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
@@ -35,34 +35,34 @@ using namespace std;
 using namespace xercesc;
 
 void TransformProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
-char *tagName;
- XMLCh * alignable_tmp;
+    char *tagName;
+    XMLCh * alignable_tmp;
 
- alignable_tmp = XMLString::transcode("alignable");
- bool alignable = element->hasAttribute(alignable_tmp);
- //
- //    Do second element first, to find what sort of transform is needed (shape or logvol etc.?)
- //
- GeoNodeList objectsToAdd;
- DOMElement *object = element->getLastElementChild();
- tagName = XMLString::transcode(object->getTagName());
- string objectName(tagName);
- gmxUtil.processorRegistry.find(objectName)->process(object, gmxUtil, objectsToAdd);
- XMLString::release(&tagName);
- XMLString::release(&alignable_tmp);
- //
- //    Get the transformation
- //
- DOMElement *transformation = element->getFirstElementChild();
- tagName = XMLString::transcode(transformation->getTagName()); // transformation or transformationref
+    alignable_tmp = XMLString::transcode("alignable");
+    bool alignable = element->hasAttribute(alignable_tmp);
+    //
+    //    Do second element first, to find what sort of transform is needed (shape or logvol etc.?)
+    //
+    GeoNodeList objectsToAdd;
+    DOMElement *object = element->getLastElementChild();
+    tagName = XMLString::transcode(object->getTagName());
+    string objectName(tagName);
+    gmxUtil.processorRegistry.find(objectName)->process(object, gmxUtil, objectsToAdd);
+    XMLString::release(&tagName);
+    XMLString::release(&alignable_tmp);
+    //
+    //    Get the transformation
+    //
+    DOMElement *transformation = element->getFirstElementChild();
+    tagName = XMLString::transcode(transformation->getTagName()); // transformation or transformationref
  
- // TODO:  ******* Should check here that an alignable transform is given an alignable transformation and object; to be done
+    // TODO:  ******* Should check here that an alignable transform is given an alignable transformation and object; to be done
  
- toAdd.push_back((GeoGraphNode *)(gmxUtil.geoItemRegistry.find(string(tagName))->process(transformation, gmxUtil)));
- XMLString::release(&tagName);
- //
- //    Add transformation to DetectorManager via GmxInterface, if it is alignable
-//
+    toAdd.push_back(dynamic_pointer_cast<GeoGraphNode>(gmxUtil.geoItemRegistry.find(string(tagName))->process(transformation, gmxUtil)));
+    XMLString::release(&tagName);
+    //
+    //    Add transformation to DetectorManager via GmxInterface, if it is alignable
+    //
     if (alignable) { 
         int level;
         alignable_tmp = XMLString::transcode("alignable");
@@ -73,15 +73,14 @@ char *tagName;
 
         //Checking all objects to find right one not so efficient - Define const int in LogvolProcessor?
         //sanity check... see if we find a FullPhysVol somewhere in the object list...
-        GeoVFullPhysVol * fpv;
-        for(GeoGraphNode * iFpv:objectsToAdd){ //maybe this needs to be in reverse???
-        fpv = dynamic_cast<GeoVFullPhysVol*> (iFpv);
-        if (fpv) break; //if we find it, use it...
+        GeoIntrusivePtr<GeoVFullPhysVol>  fpv;
+        for(GeoIntrusivePtr<GeoGraphNode>  iFpv: objectsToAdd){ //maybe this needs to be in reverse???
+            fpv = dynamic_pointer_cast<GeoVFullPhysVol> (iFpv);
+            if (fpv) break; //if we find it, use it...
         }
 
         //now check that the AlignableTransform is actually valid!
-        GeoAlignableTransform * gat = dynamic_cast<GeoAlignableTransform *>(toAdd.back());
-
+        GeoIntrusivePtr<GeoAlignableTransform> gat = dynamic_pointer_cast<GeoAlignableTransform>(toAdd.back());
         if(fpv && gat) {
             //splitting sensors where we would like multiple DetectorElements per GeoVFullPhysVol (e.g.ITk Strips)
             XMLCh * splitLevel_tmp = XMLString::transcode("splitLevel");
@@ -95,10 +94,10 @@ char *tagName;
                 for(int i=0;i<splitLevel;i++){
                     std::string field = "eta_module";//eventually specify in Xml the field to split in?
                     std::pair<std::string,int> extraIndex(field,i);
-                    gmxUtil.gmxInterface()->addSplitAlignable(level, index, extraIndex,fpv,gat);
+                    gmxUtil.gmxInterface().addSplitAlignable(level, index, extraIndex,fpv,gat);
                 }
             }
-            else gmxUtil.gmxInterface()->addAlignable(level, index,fpv,gat);
+            else gmxUtil.gmxInterface().addAlignable(level, index,fpv,gat);
             XMLString::release(&splitLevel_tmp);
         }    
         else{
@@ -113,12 +112,10 @@ char *tagName;
         }
 
         gmxUtil.positionIndex.decrementLevel(); 
-	XMLString::release(&alignable_tmp);
+	    XMLString::release(&alignable_tmp);
     }
-//
-//    And add the name and physvol etc. after the transformation
-//
+    //
+    //    And add the name and physvol etc. after the transformation
+    //
     toAdd.insert(toAdd.end(), objectsToAdd.begin(), objectsToAdd.end());
-
-    return;
 }
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformrefProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformrefProcessor.cxx
index 7db59b85b3da71c22a9164244ded51ff44f4a170..a0e57980f2748fee4b76cb12398f5d5a41b55b39 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformrefProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformrefProcessor.cxx
@@ -12,6 +12,7 @@
 #include "GeoModelXml/GmxUtil.h"
 #include "GeoModelXml/GeoNodeList.h"
 #include "xercesc/util/XMLString.hpp"
+#include "GeoModelHelpers/throwExcept.h"
 
 using namespace std;
 using namespace xercesc;
@@ -33,9 +34,8 @@ char *toRelease;
     string nodeName(toRelease);
     XMLString::release(&toRelease);
     if (nodeName != "transform") {
-        msglog << MSG::FATAL<< "Error in xml/gmx file: transformref " << XMLString::transcode(idref) << " referenced a " << nodeName << 
-                " instead of a logvol." << endmsg;
-	std::abort();
+        THROW_EXCEPTION( "Error in xml/gmx file: transformref " << XMLString::transcode(idref) 
+                    << " referenced a " << nodeName << " instead of a transform.");
     }
 //
 //    Process it
diff --git a/athena_ci/package_filters.txt b/athena_ci/package_filters.txt
index b56c38152d09bb4146d5261e7f88535483d0f8da..85ed841bfe37ecce7938607f73e1f46d31a03890 100644
--- a/athena_ci/package_filters.txt
+++ b/athena_ci/package_filters.txt
@@ -43,6 +43,7 @@
 + InnerDetector/InDetDetDescr/InDetServMatGeoModel
 + InnerDetector/InDetDetDescr/InDetTrackingGeometry
 + InnerDetector/InDetDetDescr/PixelGeoModel
++ InnerDetector/InDetDetDescr/PixelGeoModelXml
 + InnerDetector/InDetDetDescr/PixelReadoutGeometry
 + InnerDetector/InDetDetDescr/SCT_GeoModel
 + InnerDetector/InDetDetDescr/SCT_ReadoutGeometry
@@ -50,6 +51,7 @@
 + InnerDetector/InDetDetDescr/StripGeoModelXml
 + InnerDetector/InDetDetDescr/TRT_GeoModel
 + InnerDetector/InDetDetDescr/TRT_ReadoutGeometry
++ InnerDetector/InDetDetDescr/PLRGeoModelXml
 + InnerDetector/InDetDigitization/TRT_Digitization
 + InnerDetector/InDetExample/InDetDetDescrExample
 + InnerDetector/InDetG4/PixelG4_SD
diff --git a/athena_ci/patch_package_filters.txt b/athena_ci/patch_package_filters.txt
index 3319774188cb62999008eb90b6eb533158604767..b9fc84ffaa2118fa956c7028a30f8d95eaf3b49e 100644
--- a/athena_ci/patch_package_filters.txt
+++ b/athena_ci/patch_package_filters.txt
@@ -2,5 +2,12 @@
 # due to patches in the `patches` directory
 
 + InnerDetector/InDetDetDescr/InDetServMatGeoModel
-+ InnerDetector/InDetDetDescr/PixelGeoModel
-+ DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter
+
++ HighGranularityTimingDetector/HGTD_DetDescr/HGTD_GeoModelXml
++ InnerDetector/InDetDetDescr/BCMPrimeGeoModelXml
++ InnerDetector/InDetDetDescr/InDetGeoModelUtils
++ InnerDetector/InDetDetDescr/PixelGeoModelXml	
++ InnerDetector/InDetDetDescr/ServiceExtensionGeoModelXml	
++ InnerDetector/InDetDetDescr/StripGeoModelXml	
++ InnerDetector/InDetDetDescr/PLRGeoModelXml
+ 
diff --git a/athena_ci/patches/0002-Remove-the-QApplication-relic-to-fix-segfault-on-Alm.patch b/athena_ci/patches/0002-Remove-the-QApplication-relic-to-fix-segfault-on-Alm.patch
deleted file mode 100644
index 94be09c91ba241dce2ec37dddc26b45a55014726..0000000000000000000000000000000000000000
--- a/athena_ci/patches/0002-Remove-the-QApplication-relic-to-fix-segfault-on-Alm.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 8f1f207ab929105adad81598ced898b5d61fc638 Mon Sep 17 00:00:00 2001
-From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch>
-Date: Fri, 1 Mar 2024 19:43:43 +0100
-Subject: [PATCH] Remove the QApplication relic to fix segfault on Alma9, it's
- not needed.
-
----
- .../GeoModelStandalone/GeoExporter/src/GeoExporter.cxx    | 8 --------
- 1 file changed, 8 deletions(-)
-
-diff --git a/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx b/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx
-index e465bc4bddc..153832f99fa 100755
---- a/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx
-+++ b/DetectorDescription/GeoModel/GeoModelStandalone/GeoExporter/src/GeoExporter.cxx
-@@ -35,7 +35,6 @@
- #include "GeoModelWrite/WriteGeoModel.h"
- // #include "GeoModelHelpers/defineWorld.h" //TODO: Use this as soon as we have the latest GeoModel in Athena main
- 
--#include <QCoreApplication>
- #include <QtCore/QStringList>
- #include <QtCore/QFile>
- #include <QtCore/QFileInfo>
-@@ -145,13 +144,6 @@ void GeoExporter::init()
-   VP1Msg::message("===================================================");
-   VP1Msg::message("");
- 
--  int argc=1;
--  char *argv[2];
--
--  QCoreApplication app(argc, argv);
--  QCoreApplication::setOrganizationName("ATLAS");
--  QCoreApplication::setApplicationName("GeoExporter");
--
-   VP1Msg::message("Accessing the ATLAS geometry...");
-   StoreGateSvc* detstore = m_d->detstore;
-  //Get the world volume:
--- 
-2.41.0
-