diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h
index a3b44e18f599c3ca959869433f2c75190ca92ddf..8a0a28ab8e5bfab53ba4bd6e730a137314053083 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/LogvolProcessor.h
@@ -15,6 +15,7 @@
 class GmxUtil;
 class GeoNameTag;
 class GeoLogVol;
+class GeoPhysVol;
 
 class LogvolProcessor: public ElementProcessor {
 public:
@@ -28,6 +29,7 @@ public:
     void zeroId(const xercesc::DOMElement *element);
 private:
     std::map<std::string, LogVolStore> m_map; 
+    std::map<std::string, GeoPhysVol*> m_mapPV; 
 };
 
 #endif // LOGVOL_PROCESSOR_H
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx
index 527e72ff2e9821922e00f533f512a41a3322c1ac..ab1a44796b90092d468a651dd5fd7cc4448f0fad 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolProcessor.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -10,6 +10,14 @@
 //   Process children and get list of things to be added to the physvol.
 //   Add them to the physvol.
 //
+//
+// Updates:
+// - 2022/02, Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
+//            * Removed the automatic cration of a GeoNameTag for each volume, to save memory
+//            * Added support for the GeoNameTag node
+//
+
+
 #include "GeoModelXml/LogvolProcessor.h"
 #include "OutputDirector.h"
 
@@ -32,19 +40,69 @@
 using namespace std;
 using namespace xercesc;
 
+//class GeoSerialDenominator;
+//class GeoSerialTransformer;
+//class GeoSerialIdentifier;
+
+std::string getNodeType(const GeoGraphNode* node) {
+    if ( dynamic_cast<const GeoPhysVol*>(node) )
+        return "GeoPhysVol";
+    if ( dynamic_cast<const GeoFullPhysVol*>(node) )
+        return "GeoFullPhysVol";
+    if ( dynamic_cast<const GeoIdentifierTag*>(node) )
+        return "GeoIdentifierTag";
+    if ( dynamic_cast<const GeoNameTag*>(node) )
+        return "GeoNameTag";
+    if ( dynamic_cast<const GeoLogVol*>(node) )
+        return "GeoLogVol";
+    if ( dynamic_cast<const GeoShape*>(node) )
+        return "GeoShape";
+    if ( dynamic_cast<const GeoMaterial*>(node) )
+        return "GeoMaterial";
+    //if ( dynamic_cast<const GeoSerialDenominator*>(node) )
+        //return "GeoSerialDenominator";
+    //if ( dynamic_cast<const GeoSerialIdentifier*>(node) )
+        //return "GeoSerialIdentifier";
+    //if ( dynamic_cast<const GeoSerialTransformer*>(node) )
+        //return "GeoSerialTransformer";
+    if ( dynamic_cast<const GeoTransform*>(node) )
+        return "GeoTransform";
+    return "UnidentifiedNode";
+}
+
 void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNodeList &toAdd) {
   GeoLogVol *lv;
-  GeoNameTag *physVolName;
+  GeoNameTag *nameTag_physVolName;
 
   gmxUtil.positionIndex.incrementLevel();
 
+  // get the name of the LogVol
   XMLCh * name_tmp = XMLString::transcode("name");
   char *name2release = XMLString::transcode(element->getAttribute(name_tmp));
   string name(name2release);
   XMLString::release(&name2release);
   XMLString::release(&name_tmp);
+  std::cout << "LogVol name: " << name << std::endl; 
 
-//
+  // get the value for the "named" option,
+  // to add a GeoNameTag to the tree if "true"
+  XMLCh * named_tmp = XMLString::transcode("named");
+  char *toRelease2 = XMLString::transcode(element->getAttribute(named_tmp));
+  string named(toRelease2);
+  XMLString::release(&toRelease2);
+  XMLString::release(&named_tmp);
+  bool isNamed = bool(named.compare(string("true")) == 0);
+  
+  // get the value for the "identifier" option,
+  // to add a GeoIdentifierTag to the tree if "true"
+  XMLCh * id_tmp = XMLString::transcode("identifier");
+  char *toRelease3 = XMLString::transcode(element->getAttribute(id_tmp));
+  string idStr(toRelease3);
+  XMLString::release(&toRelease3);
+  XMLString::release(&id_tmp);
+  bool hasIdentifier = bool(idStr.compare(string("true")) == 0);
+
+  //
 
   XMLCh * envelope_tmp = XMLString::transcode("envelope");
   char *env = XMLString::transcode(element->getAttribute(envelope_tmp));
@@ -57,13 +115,15 @@ 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];
-    physVolName = new GeoNameTag(name);
-    store->name = physVolName;
+    if(isNamed) {
+        nameTag_physVolName = new GeoNameTag(name);
+        store->name = nameTag_physVolName;
+    }
     store->id = 0;
 //
 //    Get the shape.
@@ -75,12 +135,12 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     // Check it is a shape... its parent should be a <shapes>. DTD cannot do this for us.
     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 <<
-	". Error in gmx file. An IDREF for a logvol shape did not refer to a shape.\n" <<
-	"Shape ref was " << shape_s << "; exiting" << endmsg;
-      XMLString::release (&shape_s);
-      std::abort();
+        char* shape_s = XMLString::transcode (shape);
+        msglog << MSG::FATAL << "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;
+        XMLString::release (&shape_s);
+        std::abort();
     }
 //
 //    What sort of shape?
@@ -90,7 +150,7 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     XMLString::release(&name2release);
     XMLString::release(&shape_tmp);
 
-    const GeoShape *s = static_cast<const GeoShape *>(gmxUtil.geoItemRegistry.find(shapeType)->process(refShape, gmxUtil));
+    const GeoShape *shGeo = static_cast<const GeoShape *>(gmxUtil.geoItemRegistry.find(shapeType)->process(refShape, gmxUtil));
 //
 //    Get the material
 //
@@ -101,42 +161,45 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     parent = refMaterial->getParentNode();
     XMLCh * materials_tmp = XMLString::transcode("materials");
     if (XMLString::compareIString(parent->getNodeName(), materials_tmp) != 0) {
-      char* material_s = XMLString::transcode (material);
-      msglog << MSG::FATAL << "Processing logvol " << name <<
-	". Error in gmx file. An IDREF for a logvol material did not refer to a material.\n" <<
-	"Material ref was " << material_s << "; exiting" << endmsg;
-      XMLString::release (&material_s);
-      std::abort();
+        char* material_s = XMLString::transcode (material);
+        msglog << MSG::FATAL << "Processing logvol " << name <<
+            ". Error in gmx file. An IDREF for a logvol material did not refer to a material.\n" <<
+            "Material ref was " << material_s << "; exiting" << endmsg;
+        XMLString::release (&material_s);
+        std::abort();
     }
     std::string nam_mat=XMLString::transcode(material);
 
-    const GeoMaterial* m=nullptr;
+    const GeoMaterial* matGeo = nullptr;
 
     if (gmxUtil.matManager)
     {
-      if (!gmxUtil.matManager->isMaterialDefined(nam_mat))
-      {
-        GeoMaterial* tempMat=static_cast<GeoMaterial *>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
-        // we let GMX create the material and store it in the MM
+        if (!gmxUtil.matManager->isMaterialDefined(nam_mat))
+        {
+            GeoMaterial* tempMat=static_cast<GeoMaterial *>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
+            // we let GMX create the material and store it in the MM
 
-        gmxUtil.matManager->addMaterial(tempMat);
-      }
-      m=gmxUtil.matManager->getMaterial(nam_mat);
+            gmxUtil.matManager->addMaterial(tempMat);
+        }
+        matGeo = gmxUtil.matManager->getMaterial(nam_mat);
+    }
+    else {
+        matGeo = static_cast<const GeoMaterial *>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
     }
-    else
-      m=static_cast<const GeoMaterial *>(gmxUtil.tagHandler.material.process(refMaterial, gmxUtil));
-
 //
 //    Make the LogVol and add it to the map ready for next time
 //
-    lv = new GeoLogVol(name, s, m);
+    lv = new GeoLogVol(name, shGeo, matGeo);
     store->logVol = lv;
 
-	  XMLString::release(&material_tmp);
-	  XMLString::release(&materials_tmp);
+    XMLString::release(&material_tmp);
+    XMLString::release(&materials_tmp);
   }
   else { // Already in the registry; use it.
-    physVolName = entry->second.name;
+    msglog << MSG::DEBUG << "LogVol w/ name '" << name << "' already present, picking it from cache..." << endmsg;
+    if(isNamed) {
+        nameTag_physVolName = entry->second.name;
+    }
     lv = entry->second.logVol;
   }
 
@@ -144,6 +207,7 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
 //
 //    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) {
@@ -157,7 +221,10 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
 //
 //   Make a list of things to be added
 //
-  toAdd.push_back(physVolName);
+  if(isNamed) {
+      toAdd.push_back(nameTag_physVolName);
+  }
+
   XMLCh * sensitive_tmp = XMLString::transcode("sensitive");
   bool sensitive = element->hasAttribute(sensitive_tmp);
   int sensId = 0;
@@ -168,23 +235,32 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     gmxUtil.positionIndex.setCopyNo(m_map[name].id++);
     gmxUtil.positionIndex.indices(index, gmxUtil.eval);
     sensId = gmxUtil.gmxInterface()->sensorId(index);
-    //        toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number
-    toAdd.push_back(new GeoIdentifierTag(sensId));
+    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));
+    }
   }
   else {
-    toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number
-    gmxUtil.positionIndex.setCopyNo(m_map[name].id++);
+      if(hasIdentifier) {
+          toAdd.push_back(new GeoIdentifierTag(m_map[name].id)); // Normal copy number
+          gmxUtil.positionIndex.setCopyNo(m_map[name].id++);
+      }
   }
   XMLString::release(&sensitive_tmp);
   //
-  //    Make a new PhysVol and add everything to it, then add it to the list of things for my caller to add
+  //    Make a new PhysVol/FullPhysVol and add everything to it, then add it to the list of things for my caller to add
   //
+  
+  // get the value for the "alignable" option
   XMLCh * alignable_tmp = XMLString::transcode("alignable");
   char *toRelease = XMLString::transcode(element->getAttribute(alignable_tmp));
   string alignable(toRelease);
   XMLString::release(&toRelease);
   XMLString::release(&alignable_tmp);
+  
+
   if (sensitive || (alignable.compare(string("true")) == 0)) {
+    msglog << MSG::DEBUG << "Handling a FullPhysVol (alignable or sensitive) ..." << endmsg;
     GeoFullPhysVol *pv = new GeoFullPhysVol(lv);
     if (is_envelope) GeoVolumeTagCatalog::VolumeTagCatalog()->addTaggedVolume("Envelope",name,pv);
     for (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) {
@@ -220,11 +296,15 @@ void LogvolProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, GeoNo
     }
   }
   else {
+    msglog << MSG::DEBUG << "Handling a standard PhysVol..." << endmsg;
     GeoPhysVol *pv = new GeoPhysVol(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 (GeoNodeList::iterator node = childrenAdd.begin(); node != childrenAdd.end(); ++node) {
       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(pv);
   }
 
@@ -248,3 +328,5 @@ void LogvolProcessor::zeroId(const xercesc::DOMElement *element) {
   }
   /* else: Not an error: it is usually just about to be made with id = 0; no action needed. */
 }
+
+
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolrefProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolrefProcessor.cxx
index 9b3bcbd97733d59df83b3b4451a3b7b764926fe3..667622799d27848ea7860ba86e2dfff52073d8fa 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolrefProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/LogvolrefProcessor.cxx
@@ -47,6 +47,7 @@ char *toRelease;
         gmxUtil.tagHandler.logvol.zeroId(elem);
     }
 
+    msglog << MSG::DEBUG << "\n\nLogvolrefProcessor -- Calling the processor for the LogVol element..." << endmsg;
     gmxUtil.tagHandler.logvol.process(elem, gmxUtil, toAdd);
     XMLString::release(&ref);
     XMLString::release(&zeroid_tmp);