diff --git a/GeoModelCore/GeoModelFuncSnippets/GeoModelFuncSnippets/MaterialManager.h b/GeoModelCore/GeoModelFuncSnippets/GeoModelFuncSnippets/MaterialManager.h
new file mode 100755
index 0000000000000000000000000000000000000000..3110306f5251c736ff1620293b82049f4bb31b98
--- /dev/null
+++ b/GeoModelCore/GeoModelFuncSnippets/GeoModelFuncSnippets/MaterialManager.h
@@ -0,0 +1,128 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef GEO_MODEL_XML_MATERIAL_MANAGER_H
+#define GEO_MODEL_XML_MATERIAL_MANAGER_H
+
+#include "GeoModelKernel/GeoMaterial.h"
+#include "GeoModelKernel/GeoElement.h"
+#include "GeoModelKernel/GeoIntrusivePtr.h"
+
+#include <memory>
+#include <string>
+#include <map>
+
+
+
+class MaterialManager {
+
+  friend class Gmx2Geo;
+
+ public:
+
+    /// @brief  Retrieve a GeoElement by name
+    const GeoElement* getElement(const std::string & name) const;
+    /// @brief  Retrieve a GeoElement by number from the periodic table
+    const GeoElement* getElement(unsigned int atomicNumber) const;
+    /// @brief  Creates a new GeoElement
+    /// @param name Name inside the GeoElement map
+    /// @param symbol Chemical symbol
+    /// @param z Number in the periodic table
+    /// @param a Atomic weight
+    void addElement(const std::string &name, 
+                    const std::string &symbol, 
+                    double z, 
+                    double a);
+    /// @brief  Add a GeoElement* to the managed objects. If an element with the same name
+    ///         has already been registered, then an exception is thrown
+    void addElement(GeoElement* elePtr);
+    /// @brief Returns whether the element is already registered
+    bool isElementDefined(const std::string& eleName) const;
+
+    
+    /// @brief Returns the GeoMaterial by name. The name is expected to start with
+    ///        a namespace. If the Material couldn't be found in the registry, the
+    ///        current namespace is attempted to find the Material
+    /// @param name 
+    /// @return 
+    const GeoMaterial* getMaterial(const std::string & name) const;
+    
+    /// @brief Checks whether the matieral already exists in the database
+    bool isMaterialDefined(const std::string& matName) const;
+
+    /// @brief Sets the name space underwich the following material are going to be added
+    void setMaterialNamespace(const std::string &name);
+    /// @brief Returns the current Material namespace
+    const std::string& materialNameSpace() const;
+
+    /// @brief  Dumps the complete content of the Material database
+    void printAll() const;
+    /// @brief Creates a new material called <name> with density
+    ///        If the name contains ::, it's assumed that the prestring
+    ///        Is part of another namespace as the current one.
+    void addMaterial(const std::string &name, double density);
+
+    /// @brief Registers a new material to the database
+    void addMaterial(GeoMaterial* matPtr);
+
+    /// @brief: Adds a new Material component to the current factory by name.
+    ///         It's first checked whether the name corresponds to an element
+    ///         in the Material database otherwise, the Element database is queried.
+    void addMatComponent(const std::string &name, double fraction);
+
+    /// @brief  Finalizes the Material definition in the current Material factory.
+    void lockMaterial();
+    /// @brief  Returns the singelton to this instance of the Material Manager
+    static MaterialManager* getManager();
+ 
+    virtual ~MaterialManager();
+
+    using ElementPtr = GeoIntrusivePtr<GeoElement>;
+    using ConstElementPtr = GeoIntrusivePtr<const GeoElement>;
+    using MaterialPtr = GeoIntrusivePtr<GeoMaterial>;
+    using ConstMaterialPtr = GeoIntrusivePtr<const GeoMaterial>;
+
+    /// @brief  Small helper struct to build complex materials
+    struct MaterialFactory {
+       
+       
+       ~MaterialFactory();
+        MaterialFactory(MaterialPtr mat);
+
+        void addComponent(ConstMaterialPtr mat, double fraction);
+        void addComponent(ConstElementPtr ele, double fraction);
+
+        const GeoMaterial* get() const;
+      private:
+        using ElementComponent = std::pair<ConstElementPtr, double>;
+        std::vector<ElementComponent> m_components{};
+        double m_totFraction{0.};
+        MaterialPtr m_material{};
+    };
+
+ protected:
+    MaterialManager();
+    static MaterialManager* s_instance;
+  private:
+    // Map of elements indexed by Name
+    using ElementMap = std::map<std::string, ElementPtr>;
+    ElementMap m_elements{};
+    
+    /// Map of materials indexed by fully qualified name Namespace::MaterialName
+    using MaterialMap = std::map<std::string, MaterialPtr>;
+    MaterialMap m_materials{};
+
+    /// @brief The namespace under which all materials are being added
+    ///        to the Manager. The namespace is as well used if the 
+    ///        Material cannot be found in the MaterialMap. Then
+    ///        it's prepended to the material name
+    std::string m_currentNameSpace{};
+
+    // Build special materials
+    void buildSpecialMaterials();
+
+    std::unique_ptr<MaterialFactory> m_factory{};
+};
+
+#endif
diff --git a/GeoModelCore/GeoModelFuncSnippets/src/MaterialManager.cxx b/GeoModelCore/GeoModelFuncSnippets/src/MaterialManager.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e3179074e3501ffe7de019d1cc0c69bb4ef07d49
--- /dev/null
+++ b/GeoModelCore/GeoModelFuncSnippets/src/MaterialManager.cxx
@@ -0,0 +1,213 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "GeoModelFuncSnippets/MaterialManager.h"
+
+
+#include "GeoModelKernel/GeoIntrusivePtr.h"
+#include "GeoModelKernel/GeoElement.h"
+#include "GeoModelKernel/GeoMaterial.h"
+#include "GeoModelKernel/Units.h"
+
+#include "GeoModelFuncSnippets/throwExcept.h"
+#include "GeoModelFuncSnippets/StringUtils.h"
+
+#include <cstdlib>
+#include <iomanip>
+#include <stdio.h>
+#include <iostream>
+
+namespace {
+   std::string replaceDColon(const std::string& name) {
+        return GeoStrUtils::replaceExpInString(name, "__dColon__", "::");
+   }
+   constexpr double atomicDensity = GeoModelKernelUnits::gram / GeoModelKernelUnits::mole;
+   constexpr double volDensity = GeoModelKernelUnits::gram / GeoModelKernelUnits::cm3;
+   constexpr double invAtomicDensity = 1. / atomicDensity;
+   constexpr double invVolDensity = 1. / volDensity;
+}
+
+
+const GeoMaterial* MaterialManager::MaterialFactory::get() const { return m_material; }
+MaterialManager::MaterialFactory::~MaterialFactory() {
+    if (!m_material) return;
+    // std::cout<<"MaterialFactory() -- finalize " <<m_material->getName()<<std::endl;
+    if (m_components.empty()) {
+      m_material->lock();
+      return;
+    }
+    const double inv_totalFraction = 1. / m_totFraction;
+    for(const auto& [element, fraction] : m_components) {
+      m_material->add(element, 
+                      fraction * element->getA() * inv_totalFraction);
+    }
+    m_material->lock();
+}
+
+MaterialManager::MaterialFactory::MaterialFactory(MaterialPtr mat):
+    m_material{mat} {
+}
+
+void MaterialManager::MaterialFactory::addComponent(ConstMaterialPtr mat, double fraction) {
+    for (unsigned int ele = 0 ; ele < mat->getNumElements(); ++ele) {
+        ConstElementPtr elePtr{mat->getElement(ele)};
+        addComponent(elePtr, mat->getFraction(ele) * fraction);
+    }
+}
+void MaterialManager::MaterialFactory::addComponent(ConstElementPtr ele, 
+                                                    double fraction) {
+    m_components.emplace_back(std::make_pair(ele, fraction));
+    m_totFraction += fraction;
+}
+
+MaterialManager* MaterialManager::s_instance{nullptr};
+
+
+MaterialManager::MaterialManager() {
+    buildSpecialMaterials();
+}
+
+MaterialManager::~MaterialManager() {
+  s_instance = nullptr;
+};
+
+MaterialManager* MaterialManager::getManager() {
+  if(!s_instance) {
+    s_instance = new MaterialManager();
+  }
+  return s_instance;
+}
+
+bool MaterialManager::isMaterialDefined(const std::string& matName) const {
+  return m_materials.find(replaceDColon(matName))!= m_materials.end();
+}
+
+const GeoMaterial* MaterialManager::getMaterial(const std::string & name) const {
+    //std::cout << "Material Manager: attempt at retrieving material : "<<name<<std::endl;
+    // step 1 - check for simple name
+    const std::string matName = replaceDColon(name);
+    MaterialMap::const_iterator matItr = m_materials.find(matName);
+    if (matItr != m_materials.end()) {
+        return matItr->second;
+    }
+    // step 2 - check for material in namespace
+    std::string nameNS= m_currentNameSpace+"::"+matName;
+    matItr = m_materials.find(nameNS);
+    if (matItr != m_materials.end()) {      
+      return matItr->second;
+    }
+    printAll();
+    THROW_EXCEPTION("Could not find the material "<<matName);
+    return nullptr;
+}
+
+const GeoElement* MaterialManager::getElement(const std::string & name) const {
+  ElementMap::const_iterator elementIt = m_elements.find(name);
+  return  elementIt== m_elements.end() ? nullptr : elementIt->second;
+}
+
+const GeoElement* MaterialManager::getElement(unsigned int atomicNumber) const {
+    for(const auto& [name, element]: m_elements) {
+      if((unsigned)(element->getZ())==atomicNumber) {
+        return element;
+      }
+    }
+    return nullptr;
+}
+
+void MaterialManager::printAll() const {
+  std::cout << "============Material Manager Element List========================" << std::endl;
+
+  for (const auto&[ name,  el]  : m_elements) {    
+    std::cout << el->getSymbol() << '\t' << el->getZ() << '\t'
+              << el->getA() * invAtomicDensity << '\t' <<name << std::endl;
+  }
+  for (const auto&[material, mat]: m_materials) {
+    std::cout << "Material: " << material <<  " Density " << mat->getDensity() * invVolDensity << std::endl;
+    for (size_t i = 0; i< mat->getNumElements(); ++i) {
+      std::cout << " ***** ***** "
+         << int (mat->getFraction(i)*100) << "% \t"
+         << mat->getElement(i)->getName() << std::endl;
+    }
+  }
+}
+
+void MaterialManager::addElement(const std::string &name, const std::string &symbol, double z, double a) {
+    GeoIntrusivePtr<GeoElement> newElement{new GeoElement(name,symbol,z,a*atomicDensity)};
+    addElement(newElement);
+}
+
+void MaterialManager::addElement(GeoElement* el) {
+    GeoIntrusivePtr<GeoElement> newElement{el};
+    auto result = m_elements.insert(std::make_pair(newElement->getName(), newElement));
+    if(!result.second) {
+      THROW_EXCEPTION("Attempted to redefine element " << newElement->getName());
+    }
+}
+
+
+const std::string& MaterialManager::materialNameSpace() const {
+   return m_currentNameSpace;
+}
+void MaterialManager::setMaterialNamespace(const std::string &name) {    
+    m_currentNameSpace = name;
+    lockMaterial();
+}
+void MaterialManager::lockMaterial() { m_factory.reset(); }
+
+void MaterialManager::addMaterial(const std::string &name, double density) {
+    MaterialPtr newMat{new GeoMaterial(name, density * volDensity)};
+    addMaterial(newMat);
+}
+
+void MaterialManager::addMaterial(GeoMaterial* mat) {
+  
+  std::string matName = replaceDColon(mat->getName());
+  if (matName.find("::") == std::string::npos) {
+     if (materialNameSpace().empty()) {
+         THROW_EXCEPTION("Material " << matName << " has not beed defined within a namespace");
+     } else {
+        matName = materialNameSpace() + "::" + matName;
+     }
+  }
+  MaterialPtr matPtr{mat};
+  auto result = m_materials.insert(std::make_pair(matName, matPtr));
+  if(!result.second) {
+    THROW_EXCEPTION("Attempted to redefine material " << matName);
+  }
+  m_factory = std::make_unique<MaterialFactory>(matPtr);
+}
+bool MaterialManager::isElementDefined(const std::string& eleName) const {
+  return m_elements.find(eleName)!=m_elements.end();
+}
+
+void MaterialManager::addMatComponent(const std::string &name, double fraction) {
+  if (!m_factory){
+     THROW_EXCEPTION("No Material factory defiend at the moment");
+  }
+  std::string cmpName{replaceDColon(name)};
+  if(!isMaterialDefined(name) || cmpName.find("::") == std::string::npos) {
+    // New components is an element    
+    const GeoElement* element = getElement(name);
+    m_factory->addComponent(element, fraction);
+  } else {   
+    const GeoMaterial* material = getMaterial(name);
+    m_factory->addComponent(material, fraction);
+
+  }
+}
+void MaterialManager::buildSpecialMaterials() {
+  // Ether  
+  GeoIntrusivePtr<GeoElement> ethElement{new GeoElement("Ether","ET",500.0,0.0)};
+  m_elements.insert(std::make_pair("Ether",ethElement));
+  GeoIntrusivePtr<GeoMaterial> ether{new GeoMaterial("Ether",0.0)};
+  ether->add(ethElement,1.);
+  ether->lock();
+  m_materials.insert(std::make_pair("special::Ether", ether));
+  // HyperUranium
+  GeoIntrusivePtr<GeoMaterial> hu{new GeoMaterial("HyperUranium",0.0)};
+  hu->add(ethElement,1.);
+  hu->lock();
+  m_materials.insert(std::make_pair("special::HyperUranium", hu));
+}
diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoMaterialManager.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoMaterialManager.h
deleted file mode 100755
index 2fb78a99978a8d108a1b965ae5152b1359560210..0000000000000000000000000000000000000000
--- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoMaterialManager.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef GEOMATMANAGER_GEOMATMANAGER_H
-#define GEOMATMANAGER_GEOMATMANAGER_H
-
-#include "GeoModelKernel/IGeoMaterialManager.h"
-
-#include <iostream>
-
-class GeoElement;
-class GeoMaterial;
-class Impl;
-
-class GeoMaterialManager: public IGeoMaterialManager {
-  
-  friend class Impl;
-  
- public:
-  static const GeoMaterialManager* getManager();
-  
-  const GeoMaterial *getMaterial(const std::string & name) const;
-  const GeoElement *getElement(const std::string & name) const;
-  const GeoElement *getElement(unsigned int atomicNumber) const;
-
-  std::ostream & printAll(std::ostream & o=std::cout) const;
-
-  void addElement(const std::string &name
-		  , const std::string &symbol
-		  , double z
-		  , double a);
-
-  void addNamespace(const std::string &name);
-
-  void addMaterial(const std::string &name
-		   , double density);
-
-  void addMatComponent(const std::string &name
-		       , double fraction);
-
-  void lockMaterial();
-
-  void dump();
-
- private:
-  Impl* m_pImpl;
-  static GeoMaterialManager* s_instance;
-
-  GeoMaterialManager();
-  ~GeoMaterialManager();
-
-  // Build special materials
-  // void buildSpecialMaterials();
-};
-
-#endif
diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/IGeoMaterialManager.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/IGeoMaterialManager.h
deleted file mode 100755
index 64dad733d3539364cb4fd0f176eb19ddfdb3b4e9..0000000000000000000000000000000000000000
--- a/GeoModelCore/GeoModelKernel/GeoModelKernel/IGeoMaterialManager.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef IGEOMATMANAGER_IGEOMATMANAGER_H
-#define IGEOMATMANAGER_IGEOMATMANAGER_H
-
-#include <iostream>
-
-class GeoElement;
-class GeoMaterial;
-
-class IGeoMaterialManager {
-  
- public:
-  
-  virtual const GeoMaterial *getMaterial(const std::string & name) const =0;
-  virtual const GeoElement *getElement(const std::string & name) const =0;
-  virtual const GeoElement *getElement(unsigned int atomicNumber) const=0;
-
-  virtual void addElement(const std::string &name
-		  , const std::string &symbol
-		  , double z
-		  , double a) =0;
-
-  virtual void addNamespace(const std::string &name) =0;
-
-  virtual void addMaterial(const std::string &name
-		   , double density) =0;
-
-  virtual void addMatComponent(const std::string &name
-		       , double fraction) =0;
-
-  IGeoMaterialManager() {;}
-  virtual ~IGeoMaterialManager() {;}
-
-};
-
-#endif
diff --git a/GeoModelCore/GeoModelKernel/src/GeoMaterialManager.cxx b/GeoModelCore/GeoModelKernel/src/GeoMaterialManager.cxx
deleted file mode 100644
index 93492a1c69a41097fc502f729f5e687042685322..0000000000000000000000000000000000000000
--- a/GeoModelCore/GeoModelKernel/src/GeoMaterialManager.cxx
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "GeoModelKernel/GeoMaterialManager.h"
-
-#include "GeoModelKernel/GeoElement.h"
-#include "GeoModelKernel/GeoMaterial.h"
-#include "GeoModelKernel/Units.h"
-
-#include <cstdlib>
-#include <iomanip>
-#include <stdio.h>
-#include <map>
-#include <vector>
-
-GeoMaterialManager* GeoMaterialManager::s_instance{nullptr};
-
-class Impl {
-public:
-  Impl(GeoMaterialManager* /*man*/)
-  {}
-  ~Impl(){}
-
-  // Map of elements indexed by Name
-  typedef std::map<std::string, GeoElement*> ElementMap;
-  ElementMap m_elements;
-
-  // Map of materials indexed by fully qualified name Namespace::MaterialName
-  typedef std::map<std::string, GeoMaterial*> MaterialMap;
-  MaterialMap m_materials;
-
-  //______________________________________________________ 
-  // Auxiliary variables for building new material
-  std::string m_currentNamespace{""};
-  GeoMaterial* m_currentMaterial{nullptr};
-  bool m_firstComponent{true};
-  bool m_hasSubMaterial{false};
-  bool m_calculateFraction{false};
-  double m_totalFraction{0.};
-  std::vector<GeoElement*> m_elementComponents;
-  std::vector<double>      m_elementFractions;
-  
-};
-
-
-GeoMaterialManager::GeoMaterialManager()
-  : m_pImpl(new Impl(this))
-{
- 
-}
-
-GeoMaterialManager::~GeoMaterialManager()
-{
-  delete m_pImpl;
-}
-
-const GeoMaterialManager* GeoMaterialManager::getManager()
-{
-  if(!s_instance) {
-    try {
-      s_instance = new GeoMaterialManager();
-    }
-    catch(std::runtime_error& ex) {
-      std::cerr << ex.what() << std::endl;
-      return nullptr;
-    }
-  }
-  return s_instance;
-}
-
-const GeoMaterial* GeoMaterialManager::getMaterial(const std::string & name) const
-{
-  auto materialIt = m_pImpl->m_materials.find(name);
-  return materialIt==m_pImpl->m_materials.end() ? nullptr : materialIt->second;  
-}
-
-const GeoElement* GeoMaterialManager::getElement(const std::string & name) const
-{
-  auto elementIt = m_pImpl->m_elements.find(name);
-  return elementIt==m_pImpl->m_elements.end() ? nullptr : elementIt->second;
-}
-
-const GeoElement* GeoMaterialManager::getElement(unsigned int atomicNumber) const
-{
-  for(auto element : m_pImpl->m_elements) {
-    if((unsigned)(element.second->getZ())==atomicNumber) {
-      return element.second;
-    }
-  }
-  return nullptr;
-}
-
-std::ostream& GeoMaterialManager::printAll(std::ostream& o) const
-{
-  o << "============Material Manager Element List========================" << std::endl;
-
-  for (auto element : m_pImpl->m_elements) {
-    GeoElement* el = element.second;
-    o << el->getSymbol() << '\t' 
-      << el->getZ() << '\t' 
-      << el->getA() * (GeoModelKernelUnits::mole / GeoModelKernelUnits::gram) << '\t' 
-      << el->getName() << std::endl;    
-  }
-
-  for (auto material : m_pImpl->m_materials) {
-    GeoMaterial* mat = material.second;
-    o << "Material: " << material.first 
-      <<  " Density " << mat->getDensity() * (GeoModelKernelUnits::cm3 / GeoModelKernelUnits::gram)  
-      << std::endl;
-    for (size_t i = 0; i< mat->getNumElements(); ++i) {
-      o << " ***** ***** " 
-	<< int (mat->getFraction(i)*100) << "% \t"  
-	<< mat->getElement(i)->getName() << std::endl;
-    }
-  }  	  	
-  return o;
-}
-
-void GeoMaterialManager::addElement(const std::string &name
-				  , const std::string &symbol
-				  , double z
-				  , double a)
-{
-  GeoElement* newElement = new GeoElement(name,symbol,z,a*(GeoModelKernelUnits::gram/GeoModelKernelUnits::mole));
-  newElement->ref();
-  auto result = m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>(name,newElement));
-  if(!result.second) {
-    std::string errorMessage("Attempted to redefine element" + name);
-    throw std::runtime_error(errorMessage.c_str());
-  }
-}
-
-void GeoMaterialManager::addNamespace(const std::string &name)
-{
-  lockMaterial();
-  m_pImpl->m_currentNamespace = name;
-}
-
-void GeoMaterialManager::addMaterial(const std::string &name
-				   , double density)
-{
-  if(m_pImpl->m_currentNamespace.empty()) {
-    std::string errorMessage("Material " + name + " has not beed defined within a namespace");
-    throw std::runtime_error(errorMessage.c_str());
-  }
-  lockMaterial();
-  m_pImpl->m_currentMaterial = new GeoMaterial(name, density * (GeoModelKernelUnits::gram / GeoModelKernelUnits::cm3));
-  auto result = m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>(m_pImpl->m_currentNamespace+"::"+name, m_pImpl->m_currentMaterial));
-  if(!result.second) {
-    std::string errorMessage("Attempted to redefine material " + name);
-    throw std::runtime_error(errorMessage.c_str());
-  }
-}
-
-void GeoMaterialManager::addMatComponent(const std::string &name
-				       , double fraction)
-{
-  if(m_pImpl->m_firstComponent) {
-    m_pImpl->m_firstComponent = false;
-    if(fraction>=1.) {
-      m_pImpl->m_calculateFraction = true;
-    }
-  }
-
-  size_t separatorPos = name.find("::");
-  if(separatorPos==std::string::npos) {
-    // New components is an element
-    auto elementIt = m_pImpl->m_elements.find(name);
-    if(elementIt==m_pImpl->m_elements.end()) {
-      std::string errorMessage("Unknown element " + name + " used in the definition of material " + m_pImpl->m_currentMaterial->getName());
-      throw std::runtime_error(errorMessage.c_str());
-    }
-    GeoElement* element = elementIt->second;
-
-    if(m_pImpl->m_calculateFraction) {
-      m_pImpl->m_totalFraction += fraction*element->getA();
-      m_pImpl->m_elementComponents.push_back(element);
-      m_pImpl->m_elementFractions.push_back(fraction);
-    }
-    else {
-      m_pImpl->m_currentMaterial->add(element,fraction);
-    }
-  }
-  else {
-    // New component is a material
-    auto materialIt = m_pImpl->m_materials.find(name);
-    if(materialIt==m_pImpl->m_materials.end()) {
-      std::string errorMessage("Unknown material " + name + " used in the components name " + name);
-      throw std::runtime_error(errorMessage.c_str());
-    }
-    GeoMaterial* material = materialIt->second;
-    m_pImpl->m_hasSubMaterial = true;
-    m_pImpl->m_currentMaterial->add(material, fraction);
-  }		
-}
-
-void GeoMaterialManager::lockMaterial()
-{
-  if(!m_pImpl->m_currentMaterial) return;
-  
-  if(m_pImpl->m_calculateFraction && m_pImpl->m_hasSubMaterial && m_pImpl->m_elementComponents.size()>0) {
-    std::string errorMessage("Wrong definition of the material " + m_pImpl->m_currentMaterial->getName() + ". The exact fraction for elements must be indicated");
-    throw std::runtime_error(errorMessage.c_str());
-  }
-
-  if(m_pImpl->m_calculateFraction && !m_pImpl->m_elementComponents.empty()) {
-    const double inv_totalFraction = 1. / m_pImpl->m_totalFraction;
-    for(unsigned i=0; i<m_pImpl->m_elementComponents.size(); i++) {
-      m_pImpl->m_currentMaterial->add(m_pImpl->m_elementComponents[i],m_pImpl->m_elementFractions[i]*m_pImpl->m_elementComponents[i]->getA() * inv_totalFraction);
-    }
-  }
-  m_pImpl->m_currentMaterial->lock();
-  m_pImpl->m_currentMaterial->ref();
-
-  // Get ready for building next material
-  m_pImpl->m_currentMaterial = nullptr;
-  m_pImpl->m_firstComponent = true;
-  m_pImpl->m_hasSubMaterial = false;
-  m_pImpl->m_calculateFraction = false;
-  m_pImpl->m_totalFraction = 0.;
-  m_pImpl->m_elementComponents.clear();
-  m_pImpl->m_elementFractions.clear();
-}
-
-void GeoMaterialManager::dump()
-{
-  const char separator(' ');
-  std::cout << "*******************************************************" << std::endl;
-  std::cout << "***               GeoXmlMaterialManager             ***" << std::endl;
-  std::cout << "*******************************************************" << std::endl;
-  std::cout << "*** Elements:" << std::endl;
-
-  for(const auto& item : m_pImpl->m_elements) {
-    GeoElement* element = item.second;
-    std::cout << "* "<<  std::left << std::setw(15) << std::setfill(separator) << element->getName()
-	      << " " << std::left << std::setw(5) << std::setfill(separator) << element->getSymbol()
-	      << " " <<  std::left << std::setw(15) << std::setfill(separator) << element->getZ()
-	      << " " <<  std::left << std::setw(5) << std::setfill(separator) << element->getA()
-	      << std::endl;
-  }
-  std::cout << "*******************************************************" << std::endl;
-
-}
-
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h
index b27cc1619d7e54c576dbba6e6e73b935e9d3b9c0..ff53275924f839043d10077f0c9bcdeb39fda2ce 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h
@@ -10,7 +10,7 @@
 //
 #include <string>
 #include "ExpressionEvaluator/Evaluator.h"
-#include "GeoModelXml/MaterialManager.h"
+#include "GeoModelFuncSnippets/MaterialManager.h"
 #include "GeoModelXml/ProcessorRegistry.h"
 #include "GeoModelXml/Element2GeoItemRegistry.h"
 
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MaterialManager.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MaterialManager.h
deleted file mode 100755
index 87a1963cb9a5b76379ca848dbe43cfa339b0d7cd..0000000000000000000000000000000000000000
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MaterialManager.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef GEO_MODEL_XML_MATERIAL_MANAGER_H
-#define GEO_MODEL_XML_MATERIAL_MANAGER_H
-
-#include "GeoModelKernel/IGeoMaterialManager.h"
-
-#include <iostream>
-
-class GeoElement;
-class GeoMaterial;
-class Impl;
-
-class MaterialManager: public IGeoMaterialManager {
-
-  friend class Impl;
-  friend class Gmx2Geo;
-
- public:
-
-  const GeoMaterial *getMaterial(const std::string & name) const;
-  const GeoElement *getElement(const std::string & name) const;
-  const GeoElement *getElement(unsigned int atomicNumber) const;
-
-  void printAll() const;
-
-  void addElement(const std::string &name
-		  , const std::string &symbol
-		  , double z
-		  , double a);
-
-  void addElement(GeoElement*);
-
-  void addNamespace(const std::string &name);
-
-  void addMaterial(const std::string &name
-		   , double density);
-
-  void addMaterial(GeoMaterial*);
-
-  void addMatComponent(const std::string &name
-		       , double fraction);
-
-  void lockMaterial();
-
-  void dump();
-
-  bool isMaterialDefined(const std::string s) const;
-
-  bool isElementDefined(const std::string s) const;
-
-  static MaterialManager* getManager();
- private:
-  Impl* m_pImpl;
-  static MaterialManager* s_instance;
-
-
-  MaterialManager();
-  ~MaterialManager();
-
-  // Build special materials
-  void buildSpecialMaterials();
-};
-
-#endif
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx
index 4ae47791de96cd745c976561802dd0e350198828..036b17fd0b1f4d7fd380395618ebaab85d83a4dd 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx
@@ -6,6 +6,7 @@
 #include "GeoModelXml/GmxUtil.h"
 #include <string>
 #include <sstream>
+#include <iostream>
 
 #include <xercesc/dom/DOM.hpp>
 #include "xercesc/util/XMLString.hpp"
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx
index 5de2274ad1f524e817b0d1519d0ded6775421ea1..31fd4ebd824e7ed34b91025dd42341c3c0bb5c66 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx
@@ -28,7 +28,7 @@
 #include "GeoModelXml/GmxUtil.h"
 #include "GeoModelXml/GmxInterface.h"
 #include "GeoModelXml/createdomdocument.h"
-#include "GeoModelXml/MaterialManager.h"
+#include "GeoModelFuncSnippets/MaterialManager.h"
 
 using namespace std;
 using namespace xercesc;
@@ -81,7 +81,7 @@ Gmx2Geo::Gmx2Geo(const string& xmlFile, GeoVPhysVol *addHere, GmxInterface &gmxI
 // if the material manager is set, create a namespace
 // 
 
-    if (gmxUtil.matManager) gmxUtil.matManager->addNamespace(XMLString::transcode(attribute));
+    if (gmxUtil.matManager) gmxUtil.matManager->setMaterialNamespace(XMLString::transcode(attribute));
 
 //
 //    Add all constant definitions to the evaluator, so they are ready if needed.
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MaterialManager.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MaterialManager.cxx
deleted file mode 100644
index cd2ba784658ead844926606096824bdcaa1bb04c..0000000000000000000000000000000000000000
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MaterialManager.cxx
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "GeoModelXml/MaterialManager.h"
-
-#include "GeoModelKernel/GeoElement.h"
-#include "GeoModelKernel/GeoMaterial.h"
-#include "GeoModelKernel/Units.h"
-
-#include <cstdlib>
-#include <iomanip>
-#include <stdio.h>
-#include <map>
-#include <vector>
-
-MaterialManager* MaterialManager::s_instance{nullptr};
-
-class Impl {
-public:
-  Impl(MaterialManager* man)
-  {}
-  ~Impl(){}
-
-  // Map of elements indexed by Name
-  typedef std::map<std::string, GeoElement*> ElementMap;
-  ElementMap m_elements;
-
-  // Map of materials indexed by fully qualified name Namespace::MaterialName
-  typedef std::map<std::string, GeoMaterial*> MaterialMap;
-  MaterialMap m_materials;
-
-  //______________________________________________________
-  // Auxiliary variables for building new material
-  std::string m_currentNamespace{""};
-  GeoMaterial* m_currentMaterial{nullptr};
-  bool m_firstComponent{true};
-  bool m_hasSubMaterial{false};
-  bool m_calculateFraction{false};
-  double m_totalFraction{0.};
-  std::vector<GeoElement*> m_elementComponents;
-  std::vector<double>      m_elementFractions;
-
-};
-
-
-MaterialManager::MaterialManager()
-  : m_pImpl(new Impl(this))
-{
-	// std::cout<<" this is the GMX MaterialManager being instantiated!"<<std::endl;
-	// std::cout<<"     building special materials "<<std::endl;
-	buildSpecialMaterials();
-}
-
-MaterialManager::~MaterialManager()
-{
-  delete m_pImpl;
-}
-
-MaterialManager* MaterialManager::getManager()
-{
-  if(!s_instance) {
-    try {
-      s_instance = new MaterialManager();
-    }
-    catch(std::runtime_error& ex) {
-      std::cerr << ex.what() << std::endl;
-      return nullptr;
-    }
-  }
-  return s_instance;
-}
-
-const GeoMaterial* MaterialManager::getMaterial(const std::string & name) const
-{
-  //std::cout << "Material Manager: attempt at retrieving material : "<<name<<std::endl;
-  // step 1 - check for simple name
-  auto materialIt = m_pImpl->m_materials.find(name);
-  if (materialIt!=m_pImpl->m_materials.end())
-  {
-    //std::cout<<" material "<<name<<" found!"<<std::endl;
-    return materialIt->second;
-  }
-  // step 2 - check for material in namespace
-  std::string nameNS=m_pImpl->m_currentNamespace+"::"+name;
-  auto materialNSIt = m_pImpl->m_materials.find(nameNS);
-  if (materialNSIt!=m_pImpl->m_materials.end())
-  {
-    //std::cout<<" material "<<nameNS<<" found!"<<std::endl;
-    return materialNSIt->second;
-  }
-
-  // well, something is wrong...
-  //std::cout<<"MaterialManager::getMaterial() Warning! could not find material "<<name<<std::endl;
-  return nullptr;
-}
-
-const GeoElement* MaterialManager::getElement(const std::string & name) const
-{
-  //std::cout << "Material Manager: attempt at retrieving element : "<<name<<std::endl;
-  auto elementIt = m_pImpl->m_elements.find(name);
-  return elementIt==m_pImpl->m_elements.end() ? nullptr : elementIt->second;
-}
-
-const GeoElement* MaterialManager::getElement(unsigned int atomicNumber) const
-{
-  //std::cout << "Material Manager: attempt at retrieving material : "<<atomicNumber<<std::endl;
-  for(auto element : m_pImpl->m_elements) {
-    if((unsigned)(element.second->getZ())==atomicNumber) {
-      return element.second;
-    }
-  }
-  return nullptr;
-}
-
-void MaterialManager::printAll() const
-{
-  std::cout << "============Material Manager Element List========================" << std::endl;
-
-  for (auto element : m_pImpl->m_elements) {
-    GeoElement* el = element.second;
-    std::cout << el->getSymbol() << '\t'
-      << el->getZ() << '\t'
-      << el->getA() * (GeoModelKernelUnits::mole / GeoModelKernelUnits::gram) << '\t'
-      << el->getName() << std::endl;
-  }
-
-  for (auto material : m_pImpl->m_materials) {
-    GeoMaterial* mat = material.second;
-    std::cout << "Material: " << material.first
-      <<  " Density " << mat->getDensity() * (GeoModelKernelUnits::cm3 / GeoModelKernelUnits::gram)
-      << std::endl;
-    for (size_t i = 0; i< mat->getNumElements(); ++i) {
-      std::cout << " ***** ***** "
-	     << int (mat->getFraction(i)*100) << "% \t"
-	     << mat->getElement(i)->getName() << std::endl;
-    }
-  }
-}
-
-void MaterialManager::addElement(const std::string &name
-				  , const std::string &symbol
-				  , double z
-				  , double a)
-{
-  //std::cout << "Material Manager: adding element : "<<name<<" "<<symbol<<" "<<z<<" "<<a<<std::endl;
-  GeoElement* newElement = new GeoElement(name,symbol,z,a*(GeoModelKernelUnits::gram/GeoModelKernelUnits::mole));
-  newElement->ref();
-  auto result = m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>(name,newElement));
-  if(!result.second) {
-    std::string errorMessage("Attempted to redefine element" + name);
-    throw std::runtime_error(errorMessage.c_str());
-  }
-}
-
-void MaterialManager::addElement(GeoElement* el)
-{
-  std::string name=el->getName();
-  //std::cout << "Material Manager: adding element : "<<name<<std::endl;
-  GeoElement* newElement = el;
-  newElement->ref();
-  auto result = m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>(name,newElement));
-  if(!result.second) {
-    std::string errorMessage("Attempted to redefine element" + name);
-    throw std::runtime_error(errorMessage.c_str());
-  }
-}
-
-void MaterialManager::addNamespace(const std::string &name)
-{
-  //std::cout << "Material Manager: adding namespace : "<<name<<std::endl;
-  lockMaterial();
-  m_pImpl->m_currentNamespace = name;
-}
-
-void MaterialManager::addMaterial(const std::string &name
-				   , double density)
-{
-  //std::cout << "Material Manager: adding material : "<<name<<" "<<density<<std::endl;
-  if(m_pImpl->m_currentNamespace.empty()) {
-    std::string errorMessage("Material " + name + " has not beed defined within a namespace");
-    throw std::runtime_error(errorMessage.c_str());
-  }
-  lockMaterial();
-  m_pImpl->m_currentMaterial = new GeoMaterial(name, density * (GeoModelKernelUnits::gram / GeoModelKernelUnits::cm3));
-  auto result = m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>(m_pImpl->m_currentNamespace+"::"+name, m_pImpl->m_currentMaterial));
-  if(!result.second) {
-    std::string errorMessage("Attempted to redefine material " + name);
-    throw std::runtime_error(errorMessage.c_str());
-  }
-}
-
-void MaterialManager::addMaterial(GeoMaterial* mat)
-{
-  const std::string name=mat->getName();
-  //std::cout << "Material Manager: adding material : "<<name<<std::endl;
-  if(m_pImpl->m_currentNamespace.empty()) {
-    std::string errorMessage("Material " + name + " has not beed defined within a namespace");
-    throw std::runtime_error(errorMessage.c_str());
-  }
-  lockMaterial();
-  m_pImpl->m_currentMaterial = mat;
-  auto result = m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>(m_pImpl->m_currentNamespace+"::"+name, m_pImpl->m_currentMaterial));
-  if(!result.second) {
-    std::string errorMessage("Attempted to redefine material " + name);
-    throw std::runtime_error(errorMessage.c_str());
-  }
-}
-
-bool MaterialManager::isMaterialDefined(const std::string s) const
-{
-  if(m_pImpl->m_currentNamespace.empty()) {
-    std::string errorMessage("Material " + s + " has not beed defined within a namespace");
-    throw std::runtime_error(errorMessage.c_str());
-  }
-  return (m_pImpl->m_materials.find(s)!=m_pImpl->m_materials.end());
-}
-
-bool MaterialManager::isElementDefined(const std::string s) const
-{
-  return (m_pImpl->m_elements.find(s)!=m_pImpl->m_elements.end());
-}
-
-void MaterialManager::addMatComponent(const std::string &name
-				       , double fraction)
-{
-  //std::cout << "Material Manager: adding material component : "<<name<<" "<<fraction<<std::endl;
-  if(m_pImpl->m_firstComponent) {
-    m_pImpl->m_firstComponent = false;
-    if(fraction>=1.) {
-      m_pImpl->m_calculateFraction = true;
-    }
-  }
-
-  size_t separatorPos = name.find("::");
-  if(separatorPos==std::string::npos) {
-    // New components is an element
-    auto elementIt = m_pImpl->m_elements.find(name);
-    if(elementIt==m_pImpl->m_elements.end()) {
-      std::string errorMessage("Unknown element " + name + " used in the definition of material " + m_pImpl->m_currentMaterial->getName());
-      throw std::runtime_error(errorMessage.c_str());
-    }
-    GeoElement* element = elementIt->second;
-
-    if(m_pImpl->m_calculateFraction) {
-      m_pImpl->m_totalFraction += fraction*element->getA();
-      m_pImpl->m_elementComponents.push_back(element);
-      m_pImpl->m_elementFractions.push_back(fraction);
-    }
-    else {
-      m_pImpl->m_currentMaterial->add(element,fraction);
-    }
-  }
-  else {
-    // New component is a material
-    auto materialIt = m_pImpl->m_materials.find(name);
-    if(materialIt==m_pImpl->m_materials.end()) {
-      std::string errorMessage("Unknown material " + name + " used in the components name " + name);
-      throw std::runtime_error(errorMessage.c_str());
-    }
-    GeoMaterial* material = materialIt->second;
-    m_pImpl->m_hasSubMaterial = true;
-    m_pImpl->m_currentMaterial->add(material, fraction);
-  }
-}
-
-void MaterialManager::lockMaterial()
-{
-  if(!m_pImpl->m_currentMaterial) return;
-
-  if(m_pImpl->m_calculateFraction && m_pImpl->m_hasSubMaterial && m_pImpl->m_elementComponents.size()>0) {
-    std::string errorMessage("Wrong definition of the material " + m_pImpl->m_currentMaterial->getName() + ". The exact fraction for elements must be indicated");
-    throw std::runtime_error(errorMessage.c_str());
-  }
-
-  if(m_pImpl->m_calculateFraction && !m_pImpl->m_elementComponents.empty()) {
-    const double inv_totalFraction = 1. / m_pImpl->m_totalFraction;
-    for(unsigned i=0; i<m_pImpl->m_elementComponents.size(); i++) {
-      m_pImpl->m_currentMaterial->add(m_pImpl->m_elementComponents[i],m_pImpl->m_elementFractions[i]*m_pImpl->m_elementComponents[i]->getA() * inv_totalFraction);
-    }
-  }
-  m_pImpl->m_currentMaterial->lock();
-  m_pImpl->m_currentMaterial->ref();
-
-  // Get ready for building next material
-  m_pImpl->m_currentMaterial = nullptr;
-  m_pImpl->m_firstComponent = true;
-  m_pImpl->m_hasSubMaterial = false;
-  m_pImpl->m_calculateFraction = false;
-  m_pImpl->m_totalFraction = 0.;
-  m_pImpl->m_elementComponents.clear();
-  m_pImpl->m_elementFractions.clear();
-}
-
-void MaterialManager::dump()
-{
-  const char separator(' ');
-  std::cout << "*******************************************************" << std::endl;
-  std::cout << "***               GeoXmlMaterialManager             ***" << std::endl;
-  std::cout << "*******************************************************" << std::endl;
-  std::cout << "*** Elements:" << std::endl;
-
-  for(const auto& item : m_pImpl->m_elements) {
-    GeoElement* element = item.second;
-    std::cout << "* "<<  std::left << std::setw(15) << std::setfill(separator) << element->getName()
-	      << " " << std::left << std::setw(5) << std::setfill(separator) << element->getSymbol()
-	      << " " <<  std::left << std::setw(15) << std::setfill(separator) << element->getZ()
-	      << " " <<  std::left << std::setw(5) << std::setfill(separator) << element->getA()
-	      << std::endl;
-  }
-  std::cout << "*******************************************************" << std::endl;
-
-}
-
-void MaterialManager::buildSpecialMaterials()
-{
-  // Ether
-  GeoElement* ethElement = new GeoElement("Ether","ET",500.0,0.0);
-  ethElement->ref();
-  m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>("Ether",ethElement));
-  GeoMaterial* ether = new GeoMaterial("Ether",0.0);
-  ether->add(ethElement,1.);
-  ether->lock();
-  m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>("special::Ether", ether));
-  // HyperUranium
-  GeoMaterial* hu = new GeoMaterial("HyperUranium",0.0);
-  hu->add(ethElement,1.);
-  hu->lock();
-  m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>("special::HyperUranium", hu));
-}
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
index 72d42b3c61577eb5cb2ee8215c68c46dffbfe923..1c31e8b3c6cc310cc1bc8c4dcaa7c8d8cbc7dc63 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
@@ -17,6 +17,7 @@
 
 #include <string>
 #include <sstream>
+#include <iostream>
 #include <vector>
 #include <xercesc/dom/DOM.hpp>
 #include "GeoModelKernel/GeoNameTag.h"