From d56e69c57af381b2187bf50347c7e92c71a62254 Mon Sep 17 00:00:00 2001
From: Robert Johannes Langenberg <robert.langenberg@cern.ch>
Date: Fri, 19 Jun 2020 14:41:25 +0000
Subject: [PATCH] Tracking geometry conditions alg

---
 .../CaloTrackingGeometryBuilderCond.h         |  145 +
 ...nfiguredCaloTrackingGeometryBuilderCond.py |   48 +
 .../src/CaloTrackingGeometryBuilder.cxx       |    3 +-
 .../src/CaloTrackingGeometryBuilderCond.cxx   | 1698 +++++++++++
 .../CaloTrackingGeometry_entries.cxx          |    3 +
 .../BeamPipeBuilderCond.h                     |  119 +
 .../RobustTrackingGeometryBuilderCond.h       |  138 +
 .../SiLayerBuilderCond.h                      |  162 +
 .../StagedTrackingGeometryBuilderCond.h       |  255 ++
 .../TRT_LayerBuilderCond.h                    |  117 +
 ...figuredInDetTrackingGeometryBuilderCond.py |  201 ++
 ...iguredStagedTrackingGeometryBuilderCond.py |  223 ++
 .../src/BeamPipeBuilderCond.cxx               |  170 ++
 .../src/RobustTrackingGeometryBuilderCond.cxx |  771 +++++
 .../src/SiLayerBuilderCond.cxx                | 1178 ++++++++
 .../src/StagedTrackingGeometryBuilderCond.cxx |  718 +++++
 .../src/TRT_LayerBuilderCond.cxx              |  729 +++++
 .../InDetTrackingGeometry_entries.cxx         |   12 +
 .../MuonTrackingGeometryBuilderCond.h         |  190 ++
 ...nfiguredMuonTrackingGeometryBuilderCond.py |   44 +
 .../ConfiguredMuonTrackingGeometryCond.py     |   30 +
 .../src/MuonTrackingGeometryBuilderCond.cxx   | 2655 +++++++++++++++++
 .../MuonTrackingGeometry_entries.cxx          |    2 +
 .../LayerMaterialProvider.h                   |   12 +-
 .../src/LayerMaterialProvider.cxx             |   12 +-
 .../TrackingGeometryCondAlg/CMakeLists.txt    |   40 +
 .../TrackingGeometryCondAlg.h                 |   45 +
 .../python/AtlasTrackingGeometryCondAlg.py    |  180 ++
 .../AtlasTrackingGeometryCondAlgConfig.py     |  293 ++
 .../src/TrackingGeometryCondAlg.cxx           |   71 +
 .../TrackingGeometryCondAlg_entries.cxx       |    3 +
 .../TrkConditions/TrkCondTest/CMakeLists.txt  |   40 +
 .../TrkCondTest/TrackingGeometryCondAlgTest.h |   40 +
 .../share/TrackingGeometryTest_jobOptions.py  |  105 +
 .../src/TrackingGeometryCondAlgTest.cxx       |   47 +
 .../src/components/TrkCondTest_entries.cxx    |    3 +
 .../IGeometryBuilderCond.h                    |   69 +
 .../IGeometryProcessor.h                      |   10 +-
 .../TrkDetDescrInterfaces/ILayerBuilderCond.h |   73 +
 .../ILayerProviderCond.h                      |   62 +
 .../GeometryAsciiDumper.h                     |   10 +-
 .../TrkDetDescrTestTools/GeometryJsonDumper.h |   12 +-
 .../GeometryTTreeDumper.h                     |   10 +-
 .../LayerMaterialInspector.h                  |   10 +-
 .../RecursiveGeometryProcessor.h              |   16 +-
 .../TrackingVolumeDisplayer.h                 |    8 +-
 .../src/GeometryAsciiDumper.cxx               |    8 +-
 .../src/GeometryJsonDumper.cxx                |    8 +-
 .../src/GeometryTTreeDumper.cxx               |    8 +-
 .../src/LayerMaterialInspector.cxx            |    8 +-
 .../src/RecursiveGeometryProcessor.cxx        |   16 +-
 .../src/TrackingVolumeDisplayer.cxx           |    8 +-
 .../GenericGeometryBuilderCond.h              |   83 +
 .../TrkDetDescrTools/GeometryBuilderCond.h    |  107 +
 .../InputLayerMaterialProvider.h              |   10 +-
 .../TrkDetDescrTools/LayerMaterialProvider.h  |   16 +-
 .../TrkDetDescrTools/LayerProviderCond.h      |   72 +
 .../src/GenericGeometryBuilderCond.cxx        |  281 ++
 .../src/GeometryBuilderCond.cxx               |  451 +++
 .../src/InputLayerMaterialProvider.cxx        |   10 +-
 .../src/LayerMaterialProvider.cxx             |   36 +-
 .../src/LayerProviderCond.cxx                 |  114 +
 .../components/TrkDetDescrTools_entries.cxx   |    7 +
 .../TrkGeometry/TrackingGeometry.h            |    6 +
 64 files changed, 11919 insertions(+), 112 deletions(-)
 create mode 100755 Calorimeter/CaloTrackingGeometry/CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h
 create mode 100644 Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilderCond.py
 create mode 100755 Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilderCond.cxx
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/BeamPipeBuilderCond.h
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/SiLayerBuilderCond.h
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/TRT_LayerBuilderCond.h
 create mode 100644 InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilderCond.py
 create mode 100644 InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredStagedTrackingGeometryBuilderCond.py
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilderCond.cxx
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/RobustTrackingGeometryBuilderCond.cxx
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/SiLayerBuilderCond.cxx
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/StagedTrackingGeometryBuilderCond.cxx
 create mode 100755 InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/TRT_LayerBuilderCond.cxx
 create mode 100644 MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h
 create mode 100644 MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryBuilderCond.py
 create mode 100644 MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryCond.py
 create mode 100644 MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/MuonTrackingGeometryBuilderCond.cxx
 create mode 100644 Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
 create mode 100644 Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
 create mode 100644 Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
 create mode 100644 Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
 create mode 100644 Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
 create mode 100644 Tracking/TrkConditions/TrackingGeometryCondAlg/src/components/TrackingGeometryCondAlg_entries.cxx
 create mode 100644 Tracking/TrkConditions/TrkCondTest/CMakeLists.txt
 create mode 100644 Tracking/TrkConditions/TrkCondTest/TrkCondTest/TrackingGeometryCondAlgTest.h
 create mode 100644 Tracking/TrkConditions/TrkCondTest/share/TrackingGeometryTest_jobOptions.py
 create mode 100644 Tracking/TrkConditions/TrkCondTest/src/TrackingGeometryCondAlgTest.cxx
 create mode 100644 Tracking/TrkConditions/TrkCondTest/src/components/TrkCondTest_entries.cxx
 create mode 100755 Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryBuilderCond.h
 create mode 100755 Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerBuilderCond.h
 create mode 100644 Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerProviderCond.h
 create mode 100644 Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GenericGeometryBuilderCond.h
 create mode 100755 Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GeometryBuilderCond.h
 create mode 100644 Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerProviderCond.h
 create mode 100644 Tracking/TrkDetDescr/TrkDetDescrTools/src/GenericGeometryBuilderCond.cxx
 create mode 100755 Tracking/TrkDetDescr/TrkDetDescrTools/src/GeometryBuilderCond.cxx
 create mode 100644 Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerProviderCond.cxx

diff --git a/Calorimeter/CaloTrackingGeometry/CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h b/Calorimeter/CaloTrackingGeometry/CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h
new file mode 100755
index 00000000000..f13ae7ed2fb
--- /dev/null
+++ b/Calorimeter/CaloTrackingGeometry/CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h
@@ -0,0 +1,145 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// CaloTrackingGeometryBuilderCond.hm (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef CALORIMETER_CALOTRACKINGGEOMETRYBUILDERCOND_H
+#define CALORIMETER_CALOTRACKINGGEOMETRYBUILDERCOND_H
+
+#include "CaloIdentifier/CaloCell_ID.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+// Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+#include "TrkDetDescrUtils/LayerIndexSampleMap.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+
+// STL
+#include <vector>
+
+namespace Trk {
+  class Material;
+  class Layer;
+  class MagneticFieldProperties;
+  class TrackingGeometry;
+  class ITrackingVolumeBuilder;
+  class ITrackingVolumeCreator;
+  class ITrackingVolumeHelper;
+  class ITrackingVolumeArrayCreator;
+  class IMagneticFieldTool;
+}
+
+class IEnvelopeDefSvc;
+class ICaloSurfaceHelper;
+
+namespace Calo {
+
+  /** @class CaloTrackingGeometryBuilderCond
+     
+    Retrieves the volume builders from Tile and LAr
+    and combines the given volumes to a calorimeter tracking
+    geometry.
+    
+    It also wraps an inner volume if provided though
+    the mehtod interface.
+  
+    @author Andreas.Salzburger@cern.ch
+    */
+   class CaloTrackingGeometryBuilderCond : public AthAlgTool,
+                                       virtual public Trk::IGeometryBuilderCond {
+    
+    
+    public:
+      /** Constructor */
+      CaloTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~CaloTrackingGeometryBuilderCond();
+        
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      
+      /** TrackingGeometry Interface methode */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::Calo; }
+    
+    private:
+      ToolHandle<Trk::ITrackingVolumeArrayCreator>  m_trackingVolumeArrayCreator;    //!< Helper Tool to create TrackingVolume Arrays
+
+      ToolHandle<Trk::ITrackingVolumeHelper>        m_trackingVolumeHelper;          //!< Helper Tool to create TrackingVolumes
+      
+      ToolHandle<Trk::ITrackingVolumeCreator>       m_trackingVolumeCreator;         //!< Second helper for volume creation
+
+      ToolHandle<Trk::ITrackingVolumeBuilder>       m_lArVolumeBuilder;              //!< Volume Builder for the Liquid Argon Calorimeter
+
+      ToolHandle<Trk::ITrackingVolumeBuilder>       m_tileVolumeBuilder;             //!< Volume Builder for the Tile Calorimeter
+
+      Trk::Material*                                m_caloMaterial;                  //!< Material properties
+      
+      double                                        m_caloEnvelope;                  //!< Envelope cover for Gap Layers
+      //enclosing endcap/cylindervolume
+      ServiceHandle<IEnvelopeDefSvc>                m_enclosingEnvelopeSvc;
+                                                                                     
+      mutable double                                m_caloDefaultRadius;             //!< the radius if not built from GeoModel
+      mutable double                                m_caloDefaultHalflengthZ;        //!< the halflength in z if not built from GeoModel
+                                                                                     
+      bool                                          m_indexStaticLayers;              //!< forces robust indexing for layers
+      
+      bool                                          m_recordLayerIndexCaloSampleMap;  //!< for deposition methods
+      std::string                                   m_layerIndexCaloSampleMapName;    //!< name to record it
+      
+      bool                                          m_buildMBTS;                      //!< MBTS like detectors
+      //int				                            m_mbstSurfaceShape;		          //!< MBTS like detectors
+      mutable std::vector<double>                   m_mbtsRadii;                      //!< MBTS like detectors
+      std::vector<double>                           m_mbtsRadiusGap;                  //!< MBTS like detectors
+      std::vector<int>                              m_mbtsPhiSegments;                //!< MBTS like detectors
+      std::vector<double>                           m_mbtsPhiGap;			          //!< MBTS like detectors
+      std::vector<double>                           m_mbtsPositionZ;                  //!< MBTS like detectors
+      std::vector<double>		                    m_mbtsStaggeringZ;		          //!< MBTS like detectors
+      
+      std::string                                   m_entryVolume;                    //!< name of the Calo entrance 
+      std::string                                   m_exitVolume;                     //!< name of the Calo container
+
+      mutable RZPairVector                          m_bpCutouts;
+
+      // MBTS layers
+      mutable std::vector<const Trk::Layer*>*       m_mbtsNegLayers;
+      mutable std::vector<const Trk::Layer*>*       m_mbtsPosLayers;  
+      //ToolHandle<ICaloSurfaceHelper>                m_caloSurfaceHelper;
+           
+      /** method to establish a link between the LayerIndex and the CaloCell_ID in an associative container */
+      void registerInLayerIndexCaloSampleMap(Trk::LayerIndexSampleMap& licsMAp,
+                                             std::vector<CaloCell_ID::CaloSample> ccid,
+                                             const Trk::TrackingVolume& vol,
+                                             int side = 1 ) const;
+
+      /** method to build enclosed beam pipe volumes */
+      std::pair<const Trk::TrackingVolume*, const Trk::TrackingVolume*> createBeamPipeVolumes(float ,float, std::string, float&) const;      
+
+      /** cleanup of material */
+      mutable std::map<const Trk::Material*, bool> m_materialGarbage;
+      void throwIntoGarbage(const Trk::Material* mat) const;
+      
+   };
+
+} // end of namespace
+
+
+inline void Calo::CaloTrackingGeometryBuilderCond::throwIntoGarbage(const Trk::Material* mat) const
+{ if (mat) m_materialGarbage[mat] = true; }
+
+#endif // CALORIMETER_CALOTRACKINGGEOMETRYBUILDERCOND_H
+
+
diff --git a/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilderCond.py b/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilderCond.py
new file mode 100644
index 00000000000..ccc3416c7cb
--- /dev/null
+++ b/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilderCond.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+######################################################
+# ConfiguredCaloTrackingGeometry module
+#
+# it inherits from CaloTrackingGeometryBuilder and performs 
+# standard configuration
+#
+######################################################
+
+# import the Extrapolator configurable
+from CaloTrackingGeometry.CaloTrackingGeometryConf import Calo__CaloTrackingGeometryBuilderCond
+
+# define the class
+class ConfiguredCaloTrackingGeometryBuilderCond( Calo__CaloTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'CaloTrackingGeometryBuilderCond'):
+        
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+                
+        from LArTrackingGeometry.ConfiguredLArVolumeBuilder import ConfiguredLArVolumeBuilder
+
+        # import the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc
+        if 'ToolSvc' not in dir() :
+            ToolSvc = ToolSvc()
+
+        ConfLArVolumeBuilder = ConfiguredLArVolumeBuilder()
+        ToolSvc += ConfLArVolumeBuilder
+
+        from TileTrackingGeometry.ConfiguredTileVolumeBuilder import ConfiguredTileVolumeBuilder
+
+        ConfTileVolumeBuilder = ConfiguredTileVolumeBuilder()
+        ToolSvc += ConfTileVolumeBuilder
+
+        # The volume helper
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeHelper
+        CaloTrackingVolumeHelper = Trk__TrackingVolumeHelper(name='TrackingVolumeHelper')
+        ToolSvc += CaloTrackingVolumeHelper         
+        
+        Calo__CaloTrackingGeometryBuilderCond.__init__(self,name,\
+                                                   LArVolumeBuilder = ConfLArVolumeBuilder,\
+                                                   TileVolumeBuilder = ConfTileVolumeBuilder,\
+                                                   TrackingVolumeHelper = CaloTrackingVolumeHelper,\
+                                                   GapLayerEnvelope    = TrkDetFlags.CaloEnvelopeCover(),\
+                                                   EntryVolumeName = TrkDetFlags.CaloEntryVolumeName(),\
+                                                   ExitVolumeName  = TrkDetFlags.CaloContainerName(),
+                                                   MagneticFieldMode = TrkDetFlags.MagneticFieldMode())
diff --git a/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx
index b5006daba4f..4fc2b86d5bd 100755
--- a/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx
+++ b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilder.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -319,6 +319,7 @@ const Trk::TrackingGeometry* Calo::CaloTrackingGeometryBuilder::trackingGeometry
   RZPairVector& bpDefs = m_enclosingEnvelopeSvc->getBeamPipeRZValues(0);
   
   ATH_MSG_VERBOSE( "BeamPipe envelope definition retrieved:" );   
+  m_bpCutouts.clear();
   for (unsigned int i=0; i<bpDefs.size(); i++) {
     ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< bpDefs[i].first<<","<<bpDefs[i].second );   
     // beam pipe within calo : pick 10. < R < 200;  envEnclosingVolumeHalfZ   =< z  <= msCutouts.back().second;
diff --git a/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilderCond.cxx b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilderCond.cxx
new file mode 100755
index 00000000000..b736599facf
--- /dev/null
+++ b/Calorimeter/CaloTrackingGeometry/src/CaloTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,1698 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// CaloTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+// Calo
+#include "CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h"
+#include "CaloTrackingGeometry/ICaloSurfaceHelper.h"
+// Trk
+#include "TrkDetDescrInterfaces/ITrackingVolumeBuilder.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ILayerArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+#include "TrkDetDescrInterfaces/IDynamicLayerCreator.h"
+//#include "TrkDetDescrInterfaces/IMaterialEffectsOnTrackProvider.h"
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkDetDescrUtils/BinnedArray1D1D.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/GlueVolumesDescriptor.h"
+#include "TrkGeometry/Material.h"
+#include "TrkGeometry/BinnedMaterial.h"
+#include "TrkGeometry/MaterialProperties.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkGeometry/HomogeneousLayerMaterial.h"
+#include "TrkGeometry/AlignableTrackingVolume.h"
+#include "TrkVolumes/VolumeBounds.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkSurfaces/DiscBounds.h"
+#include "TrkSurfaces/TrapezoidBounds.h"
+#include "TrkSurfaces/DiscSurface.h"
+#include "TrkSurfaces/PlaneSurface.h"
+#include "GaudiKernel/SystemOfUnits.h"
+#include <memory>
+// CLHEP
+//#include "CLHEP/Geometry/Transform3D.h"
+
+//using HepGeom::Transform3D;
+//using HepGeom::Translate3D;
+//using HepGeom::RotateZ3D;
+//using HepGeom::Vector3D;
+//using CLHEP::Hep3Vector;
+//using CLHEP::HepRotation;
+//using CLHEP::mm;
+//using CLHEP::radian;
+
+// constructor
+Calo::CaloTrackingGeometryBuilderCond::CaloTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_trackingVolumeArrayCreator("Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"),
+  m_trackingVolumeHelper("Trk::TrackingVolumeHelper/TrackingVolumeHelper"),
+  m_trackingVolumeCreator("Trk::CylinderVolumeCreator/TrackingVolumeCreator"),
+  m_lArVolumeBuilder("LAr::LArVolumeBuilder/LArVolumeBuilder"),
+  m_tileVolumeBuilder("Tile::TileVolumeBuilder/TileVolumeBuilder"),
+  m_caloMaterial(0),
+  m_caloEnvelope(25*Gaudi::Units::mm),
+  m_enclosingEnvelopeSvc("AtlasGeometry_EnvelopeDefSvc", n),
+  m_caloDefaultRadius(4250.),
+  m_caloDefaultHalflengthZ(6500.),
+  m_indexStaticLayers(true),
+  m_recordLayerIndexCaloSampleMap(false),
+  m_layerIndexCaloSampleMapName("LayerIndexCaloSampleMap"),
+  m_buildMBTS(true),
+  //m_mbstSurfaceShape(2),
+  m_entryVolume("Calo::Container::EntryVolume"),
+  m_exitVolume("Calo::Container"),
+  m_mbtsNegLayers(0),
+  m_mbtsPosLayers(0)
+  //m_caloSurfaceHelper("CaloSurfaceHelper/CaloSurfaceHelper")
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);
+  // declare the properties via Python
+  declareProperty("LArVolumeBuilder",                 m_lArVolumeBuilder);
+  declareProperty("TileVolumeBuilder",                m_tileVolumeBuilder);
+  declareProperty("TrackingVolumeArrayCreator",       m_trackingVolumeArrayCreator);
+  declareProperty("TrackingVolumeHelper",             m_trackingVolumeHelper);
+  declareProperty("TrackingVolumeCreator",            m_trackingVolumeCreator);
+  declareProperty("GapLayerEnvelope",                 m_caloEnvelope);
+  // envelope definition service
+  declareProperty("EnvelopeDefinitionSvc",            m_enclosingEnvelopeSvc );
+  // empty calorimeter to be built
+  declareProperty("CalorimeterRadius",                m_caloDefaultRadius);
+  declareProperty("CalorimeterHalflengthZ",           m_caloDefaultHalflengthZ);
+  // unique layer handling
+  declareProperty("IndexStaticLayers",                m_indexStaticLayers);
+  // for energy deposition
+  declareProperty("RecordLayerIndexCaloSampleMap",    m_recordLayerIndexCaloSampleMap);
+  declareProperty("LayerIndexCaloSampleMapName",      m_layerIndexCaloSampleMapName);
+  // MBTS like detectors 
+  declareProperty("BuildMBTS",                        m_buildMBTS);
+  //declareProperty("MBTS_SurfaceShape",                m_mbstSurfaceShape);
+  //declareProperty("MBTS_Radii",                       m_mbtsRadii);
+  //declareProperty("MBTS_RadiusGap",                   m_mbtsRadiusGap);
+  //declareProperty("MBTS_PhiSegments",                 m_mbtsPhiSegments);
+  //declareProperty("MBTS_PhiGap",                      m_mbtsPhiGap);
+  //declareProperty("MBTS_PositionZ",                   m_mbtsPositionZ);
+  //declareProperty("MBTS_StaggeringZ",                 m_mbtsStaggeringZ);
+  // calo entry volume & exit volume
+  declareProperty("EntryVolumeName",                  m_entryVolume);
+  declareProperty("ExitVolumeName",                   m_exitVolume);
+  
+}
+
+// destructor
+Calo::CaloTrackingGeometryBuilderCond::~CaloTrackingGeometryBuilderCond()
+{
+  delete m_caloMaterial;
+}
+
+// Athena standard methods
+// initialize
+StatusCode Calo::CaloTrackingGeometryBuilderCond::initialize()
+{
+  
+    // retrieve envelope definition service --------------------------------------------------
+    if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+      ATH_MSG_FATAL( "Could not retrieve EnvelopeDefinition service. Abort.");
+      return StatusCode::FAILURE;
+    }
+    
+    // Retrieve the tracking volume array creator   -------------------------------------------------    
+    if (m_trackingVolumeArrayCreator.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeArrayCreator );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+
+    // Retrieve the tracking volume helper   -------------------------------------------------    
+    if (m_trackingVolumeHelper.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeHelper );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeHelper );
+
+    // Retrieve the second volume creator
+    if (m_buildMBTS && m_trackingVolumeCreator.retrieve().isFailure()){
+        ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeCreator );
+        return StatusCode::FAILURE;
+    } else
+        ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeCreator );
+
+    // Retrieve the volume builders
+
+    // Retrieve the tracking volume array creator   -------------------------------------------------    
+    if (m_lArVolumeBuilder.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_lArVolumeBuilder );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_lArVolumeBuilder );
+
+    // Retrieve the tracking volume helper   -------------------------------------------------    
+    if (m_tileVolumeBuilder.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_tileVolumeBuilder );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_tileVolumeBuilder );
+
+    // Retrieve the calo surface helper (to load MBTS) -------------------------------------------------    
+#if 0
+    if (m_caloSurfaceHelper.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_caloSurfaceHelper );
+      return StatusCode::FAILURE;
+    } else
+      ATH_MSG_INFO( "Retrieved tool " << m_caloSurfaceHelper );
+#endif
+
+    // Dummy MaterialProerties
+    m_caloMaterial = new Trk::Material;
+
+    ATH_MSG_INFO( "initialize() succesful" );
+
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode Calo::CaloTrackingGeometryBuilderCond::finalize()
+{
+  // empty the material garbage 
+  std::map<const Trk::Material*, bool>::iterator garbageIter  = m_materialGarbage.begin();
+  std::map<const Trk::Material*, bool>::iterator garbageEnd   = m_materialGarbage.end();
+  
+  for ( ; garbageIter != garbageEnd; ++garbageIter ){
+    delete (garbageIter->first);
+  }
+
+  ATH_MSG_INFO( "finalize() successful" );
+  return StatusCode::SUCCESS;
+}
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Calo::CaloTrackingGeometryBuilderCond::trackingGeometry(const EventContext&, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const
+{
+
+  ATH_MSG_VERBOSE( "Starting to build CaloTrackingGeometry ..." );   
+  
+  // the return TG
+  const Trk::TrackingGeometry* caloTrackingGeometry = 0; 
+  const Trk::TrackingVolume*            calorimeter = 0;                     
+
+  // the key dimensions
+  RZPairVector keyDim; 
+
+  // the enclosed input volume (ID)
+  double enclosedInnerSectorHalflength = 0.;
+  double enclosedInnerSectorRadius = 0.;
+   
+   // dummy objects
+   const Trk::LayerArray* dummyLayers = 0;
+   const Trk::TrackingVolumeArray* dummyVolumes = 0;
+  
+  //TODO/FIXME: just passing on range, no Calo IOV range used
+  EventIDRange range;
+  const Trk::TrackingVolume* innerVol = nullptr;
+  if(tVolPair.second != nullptr){
+    range = tVolPair.first;
+    innerVol = tVolPair.second;
+  }
+  if (innerVol) {  
+    ATH_MSG_VERBOSE( "Got Inner Detector Volume: " << innerVol->volumeName() ); 
+    innerVol->screenDump(msg(MSG::VERBOSE)); 
+
+    // retrieve dimensions
+    const Trk::CylinderVolumeBounds* innerDetectorBounds 
+      = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(innerVol->volumeBounds()));
+    if (!innerDetectorBounds) std::abort();
+    
+    enclosedInnerSectorHalflength = innerDetectorBounds->halflengthZ();
+    enclosedInnerSectorRadius = innerDetectorBounds->outerRadius();
+
+    keyDim.push_back(RZPair(enclosedInnerSectorRadius, enclosedInnerSectorHalflength));
+  }   
+  // get the dimensions from the envelope service
+  RZPairVector& envelopeDefsIn = m_enclosingEnvelopeSvc->getCaloRZValues(0);
+  //RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getCaloRZValues(0);
+
+  // find the max,max pair
+  unsigned int ii=0;
+  for (unsigned int i=0; i<envelopeDefsIn.size(); i++) { 
+    if (envelopeDefsIn[i].second>envelopeDefsIn[ii].second) ii=i;
+    else if (envelopeDefsIn[i].second==envelopeDefsIn[ii].second && 
+	     envelopeDefsIn[i].first>envelopeDefsIn[ii].first) ii=i;
+  }  
+
+  // find the sense of rotation
+  int irot=1;
+  unsigned int inext=ii+1;
+  if (inext==envelopeDefsIn.size()) inext=0;
+  if (envelopeDefsIn[inext].second!=envelopeDefsIn[ii].second) {irot=-1; inext = ii>0 ? ii-1:envelopeDefsIn.size()-1 ;}
+  
+  // fill starting with upper low edge, end with upper high edge
+  RZPairVector envelopeDefs;
+  if (irot>0) {
+    for (unsigned int i=inext; i<envelopeDefsIn.size(); i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+    if (inext>0) for (unsigned int i=0; i<=inext-1; i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+  } else {
+    int i=inext;  while (i>=0) {envelopeDefs.push_back(envelopeDefsIn[i]); i=i-1;};
+    inext = envelopeDefsIn.size()-1; while (inext>=ii) {envelopeDefs.push_back(envelopeDefsIn[inext]); inext=inext-1;};
+  } 
+
+
+  double envEnclosingVolumeHalfZ = m_caloDefaultHalflengthZ; 
+
+  ATH_MSG_VERBOSE( "Calo envelope definition retrieved:" );  
+  RZPairVector msCutouts; 
+  for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< envelopeDefs[i].first<<","<<envelopeDefs[i].second );   
+    if (fabs(envelopeDefs[i].second) < envEnclosingVolumeHalfZ) envEnclosingVolumeHalfZ = fabs(envelopeDefs[i].second);
+    // ID dimensions : pick 1100 < R < 1200
+    if ( envelopeDefs[i].first > 1100. && envelopeDefs[i].first < 1200. && envelopeDefs[i].second > 0. ) {
+      // check that radial size of ID envelope fits
+      if ( enclosedInnerSectorRadius != envelopeDefs[i].first ) ATH_MSG_INFO( "Enclosed ID volume radius does not match ID envelope, adjusting Calo." );
+      envEnclosingVolumeHalfZ = envelopeDefs[i].second; 
+      if (!innerVol) {
+	enclosedInnerSectorRadius = envelopeDefs[i].first;
+	enclosedInnerSectorHalflength = envelopeDefs[i].second;
+      }
+    }
+    // collect outer cutouts, process those with |z| < 6785.mm ( this cut should be synchronized with MS default size,
+    //  MS builder would crash for a longer input volume ) 
+    if ( envelopeDefs[i].second > 0. && envelopeDefs[i].second < 6785. &&
+	 ( envelopeDefs[i].first > 1200. || envelopeDefs[i].second > envEnclosingVolumeHalfZ ) ) {
+      if ( !msCutouts.size() ) msCutouts.push_back( envelopeDefs[i] );
+      else {
+	RZPairVector::iterator envIter = msCutouts.begin();
+        while (envIter!= msCutouts.end() && (*envIter).second < envelopeDefs[i].second ) envIter++;
+        while (envIter!= msCutouts.end() && (*envIter).second == envelopeDefs[i].second && (*envIter).first  > envelopeDefs[i].first ) envIter++;
+	msCutouts.insert(envIter, envelopeDefs[i]);
+      }
+    }
+    // end outer (MS) cutouts
+  }
+  for (unsigned int i=0; i<msCutouts.size(); i++) ATH_MSG_VERBOSE( "MS cutouts to be processed by Calo:"<< i<<":"<< msCutouts[i].first<<","<<msCutouts[i].second );
+  // first member of msCutouts redefines the default central cylinder dimension     
+  if (msCutouts.size()>0) {
+    m_caloDefaultRadius = msCutouts[0].first;
+    m_caloDefaultHalflengthZ = msCutouts[0].second;
+    ATH_MSG_VERBOSE(" Calo central cylinder dimensions adjusted using EnvelopeSvc:"<<m_caloDefaultRadius<<","<< m_caloDefaultHalflengthZ );
+  }
+
+  // create dummy ID if not built already
+
+  if (!innerVol) {
+   Trk::CylinderVolumeBounds* idBounds = new Trk::CylinderVolumeBounds(enclosedInnerSectorRadius, enclosedInnerSectorHalflength);
+
+   Amg::Transform3D* idTr = new Amg::Transform3D(Trk::s_idTransform);
+
+   innerVol = new Trk::TrackingVolume(idTr, idBounds, *m_caloMaterial,
+				      dummyLayers, dummyVolumes,
+				      "Calo::GapVolumes::DummyID");
+
+   keyDim.push_back(RZPair(enclosedInnerSectorRadius, enclosedInnerSectorHalflength));
+  }
+ 
+  // BEAM PIPE
+  //std::cout <<"envelope svc : number of BeamPipe Volumes:"<< m_enclosingEnvelopeSvc->getBeamPipeNumVols()<< std::endl;  
+  RZPairVector& bpDefs = m_enclosingEnvelopeSvc->getBeamPipeRZValues(0);
+  
+  ATH_MSG_VERBOSE( "BeamPipe envelope definition retrieved:" );   
+  m_bpCutouts.clear();
+  for (unsigned int i=0; i<bpDefs.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< bpDefs[i].first<<","<<bpDefs[i].second );   
+    // beam pipe within calo : pick 10. < R < 200;  envEnclosingVolumeHalfZ   =< z  <= msCutouts.back().second;
+    if ( bpDefs[i].first > 10. && bpDefs[i].first < 200. && bpDefs[i].second>=envEnclosingVolumeHalfZ  && bpDefs[i].second <= msCutouts.back().second ) {
+      m_bpCutouts.push_back( bpDefs[i] );
+    }
+    if (i>0 && i<4) keyDim.push_back(bpDefs[i]);
+  }
+ 
+  // no beam pipe within ID
+  //if (m_bpCutouts[0].second == envEnclosingVolumeHalfZ && m_bpCutouts[0].first > 0 )  m_bpCutouts[0].first=0.;
+  // last not needed
+  if (m_bpCutouts.size()>1 && m_bpCutouts.back().second==m_bpCutouts[m_bpCutouts.size()-2].second) m_bpCutouts.erase(m_bpCutouts.end()-1);
+  // end beam pipe envelope within Calo
+  for (unsigned int i=0; i<m_bpCutouts.size(); i++) ATH_MSG_VERBOSE( "Beam pipe dimensions to be used by Calo:"<< i<<":"<< m_bpCutouts[i].first<<","<<m_bpCutouts[i].second );
+
+  keyDim.push_back(RZPair(m_caloDefaultRadius,m_caloDefaultHalflengthZ)); 
+
+   // get the dimensions from the envelope service
+   //std::cout <<"envelope svc : number of MS Volumes:"<< m_enclosingEnvelopeSvc->getMuonNumVols()<< std::endl;  
+   //RZPairVector& msDefs = m_enclosingEnvelopeSvc->getMuonRZValues(0);
+
+   //ATH_MSG_VERBOSE( "MS envelope definition retrieved:" );   
+   //for (unsigned int i=0; i<msDefs.size(); i++) ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< msDefs[i].first<<","<<msDefs[i].second );   
+
+
+   //////////// ---------------- BUILD FROM GEOMODEL ---------------------------- /////////////////////////////////
+
+    
+  // PART 1 : Liquid Argon Volumes ===========================================================================================
+  // get the Tracking Volumes from the LAr Builder 
+  const std::vector<const Trk::TrackingVolume*>* lArVolumes = m_lArVolumeBuilder->trackingVolumes();
+
+  ATH_MSG_INFO( lArVolumes->size() << " volumes retrieved from " << m_lArVolumeBuilder.name() );   
+  if (msgLvl(MSG::VERBOSE)){
+    ATH_MSG_VERBOSE( "--------------- detailed output ---------------------------------------------------------- " );
+    std::vector<const Trk::TrackingVolume*>::const_iterator lArVolIter    = lArVolumes->begin();
+    std::vector<const Trk::TrackingVolume*>::const_iterator lArVolIterEnd = lArVolumes->end();
+    for ( ; lArVolIter != lArVolIterEnd; ++lArVolIter)
+     if (*lArVolIter) (*lArVolIter)->screenDump(msg(MSG::VERBOSE)) ;
+  }           
+  
+  // LAr Barrel part  
+  const Trk::TrackingVolume* solenoid                   = (*lArVolumes)[0];
+  const Trk::TrackingVolume* solenoidlArPresamplerGap   = (*lArVolumes)[1];
+  const Trk::TrackingVolume* lArBarrelPresampler        = (*lArVolumes)[2];
+  const Trk::TrackingVolume* lArBarrel                  = (*lArVolumes)[3];
+
+  // LAr Positive Endcap part
+  const Trk::TrackingVolume* lArPositiveMBTS            = (*lArVolumes)[4];
+  const Trk::TrackingVolume* lArPositiveEndcap          = (*lArVolumes)[5];
+  const Trk::TrackingVolume* lArPositiveHec             = (*lArVolumes)[6];
+  const Trk::TrackingVolume* lArPositiveFcal            = (*lArVolumes)[7];
+  const Trk::TrackingVolume* lArPositiveHecFcalCover    = (*lArVolumes)[8];
+  // LAr Negative Endcap part
+  const Trk::TrackingVolume* lArNegativeMBTS            = (*lArVolumes)[9];
+  const Trk::TrackingVolume* lArNegativeEndcap          = (*lArVolumes)[10];
+  const Trk::TrackingVolume* lArNegativeHec             = (*lArVolumes)[11];
+  const Trk::TrackingVolume* lArNegativeFcal            = (*lArVolumes)[12];
+  const Trk::TrackingVolume* lArNegativeHecFcalCover    = (*lArVolumes)[13];
+  const Trk::TrackingVolume* lArPosECPresampler         = (*lArVolumes)[14];
+  const Trk::TrackingVolume* lArNegECPresampler         = (*lArVolumes)[15];
+
+
+  // PART 2 : Tile Volumes ===========================================================================================
+  // get the Tracking Volumes from the Tile Builder 
+  const std::vector<const Trk::TrackingVolume*>* tileVolumes = m_tileVolumeBuilder->trackingVolumes();
+
+  ATH_MSG_INFO( tileVolumes->size() << " volumes retrieved from " << m_tileVolumeBuilder.name() );   
+  if (msgLvl(MSG::INFO)){
+    ATH_MSG_INFO( "--------------- detailed output ---------------------------------------------------------- " );
+    std::vector<const Trk::TrackingVolume*>::const_iterator tileVolIter = tileVolumes->begin();
+    std::vector<const Trk::TrackingVolume*>::const_iterator tileVolIterEnd = tileVolumes->end();
+    for ( ; tileVolIter != tileVolIterEnd;  (*tileVolIter)->screenDump(msg(MSG::VERBOSE)), ++tileVolIter)
+      ;
+  }
+    
+  // Tile Barrel part
+  const Trk::TrackingVolume* tileCombined                  = (*tileVolumes)[0];
+  // Tile Positive Extended Part
+  const Trk::TrackingVolume* tilePositiveExtendedBarrel  = (*tileVolumes)[1];
+
+  const Trk::CylinderVolumeBounds* ebBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tilePositiveExtendedBarrel->volumeBounds()));
+
+  double rTileMin = ebBounds ? ebBounds->innerRadius() : 2288.;
+  double zTileMin = ebBounds ? tilePositiveExtendedBarrel->center().z()-ebBounds->halflengthZ() : 3559.5;
+
+  keyDim.push_back(RZPair(rTileMin,zTileMin));
+  for (unsigned int i=0; i<keyDim.size(); i++) {
+    ATH_MSG_VERBOSE( "key dimensions:"<< i<<":"<< keyDim[i].first<<","<<keyDim[i].second );   
+  }
+  
+  // The Bounds needed for the Gap Volume creation
+  const Trk::CylinderVolumeBounds* solenoidBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(solenoid->volumeBounds()));
+  if (!solenoidBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArBarrelBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArBarrel->volumeBounds()));
+  if (!lArBarrelBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArPositiveEndcapBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveEndcap->volumeBounds()));
+  if (!lArPositiveEndcapBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArNegativeEndcapBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArNegativeEndcap->volumeBounds()));
+  if (!lArNegativeEndcapBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArPositiveHecBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveHec->volumeBounds()));
+  if (!lArPositiveHecBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArPositiveFcalBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveFcal->volumeBounds()));
+  if (!lArPositiveFcalBounds) std::abort();
+  const Trk::CylinderVolumeBounds* lArNegativeFcalBounds 
+        = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArNegativeFcal->volumeBounds()));
+  if (!lArNegativeFcalBounds) std::abort();
+ 
+  const Trk::CylinderVolumeBounds* tileCombinedBounds 
+       = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tileCombined->volumeBounds()));
+  if (!tileCombinedBounds) std::abort();
+        
+   // Create the gap volumes ======================================================================
+   const Trk::TrackingVolume* lArTileCentralSectorGap    = 0;
+
+   //const Trk::TrackingVolume* tilePositiveSectorInnerGap = 0;
+   const Trk::TrackingVolume* lArPositiveSectorInnerGap  = 0;
+   //const Trk::TrackingVolume* lArTilePositiveSectorGap   = 0;
+   const Trk::TrackingVolume* lArPositiveSectorOuterGap  = 0;
+   const Trk::TrackingVolume* lArPositiveSectorOuterGap0  = 0;
+   const Trk::TrackingVolume* lArCentralPositiveGap      = 0;
+
+   //const Trk::TrackingVolume* tileNegativeSectorInnerGap = 0;
+   const Trk::TrackingVolume* lArNegativeSectorInnerGap  = 0;
+   //const Trk::TrackingVolume* lArTileNegativeSectorGap   = 0;
+   const Trk::TrackingVolume* lArNegativeSectorOuterGap  = 0;
+   const Trk::TrackingVolume* lArNegativeSectorOuterGap0  = 0;
+   const Trk::TrackingVolume* lArCentralNegativeGap      = 0;
+
+   const Trk::TrackingVolume* trtSolenoidGap         = 0;  
+
+   double caloPositiveOuterBoundary    =  tileCombinedBounds->halflengthZ();
+
+   double lArPositiveOuterBoundary     = lArPositiveFcal->center().z();
+          lArPositiveOuterBoundary    += lArPositiveFcalBounds->halflengthZ();
+
+   double lArNegativeOuterBoundary     = lArNegativeFcal->center().z();
+          lArNegativeOuterBoundary    -= lArNegativeFcalBounds->halflengthZ();
+
+   Trk::Material* mAr = new Trk::Material(140.036, 856.32, 39.948, 18., 0.0014);
+   Trk::Material* mAl = new Trk::Material(88.93, 388.62, 26.98, 13., 0.0027);
+   //Trk::Material* mFe = new Trk::Material(17.58, 169.68, 55.85, 26., 0.0079);
+   Trk::Material* mScint = new Trk::Material(424.35, 707.43, 11.16, 5.61, 0.001);  // from G4 definition
+   const Trk::Material* crackMaterial = new Trk::Material(424.35, 707.43, 11.16, 5.61, 0.001);  // Scintillator/Glue (G4 def.)
+
+   throwIntoGarbage(mAr);
+   throwIntoGarbage(mAl);
+   throwIntoGarbage(mScint);
+   throwIntoGarbage(crackMaterial);
+
+   // No. 1
+   // building dense volume here
+   Trk::Material tilePositiveSectorInnerGapMaterial = Trk::Material(58., 565., 30.7, 14.6, 0.0025);
+
+   // calo sensitive volume outer radius/z extent defined (for example) here
+   float caloVolsOuterRadius = tileCombinedBounds->outerRadius(); 
+   float caloVolsExtendZ = caloPositiveOuterBoundary; 
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   //  LAr InnerGap sector + beam pipe
+  
+   Trk::Material lArSectorInnerGapMaterial = Trk::Material(361., 1370., 14.5, 7., 0.0009);  // ???
+
+   // create beam pipe volumes for InnerGap/MBTS and return their outer radius 
+   float rInnerGapBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> innerGapBP = createBeamPipeVolumes(keyDim[0].second, 
+							//lArPositiveEndcap->center().z()-lArPositiveEndcapBounds->halflengthZ(),
+												       keyDim.back().second,
+												       "InnerGap", rInnerGapBP);
+
+   double z = 0.5*(keyDim.back().second+keyDim[0].second);
+
+   if (lArPositiveMBTS && lArNegativeMBTS) {
+     // Disc
+     const Trk::CylinderVolumeBounds* mbtsBounds 
+       = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPositiveMBTS->volumeBounds()));
+#if 0
+     if (mbtsBounds && m_caloSurfaceHelper) {     // pass ownership
+       Amg::Transform3D* mbtsNeg = new Amg::Transform3D(Amg::Translation3D(lArNegativeMBTS->center()));
+       Amg::Transform3D* mbtsPos = new Amg::Transform3D(Amg::Translation3D(lArPositiveMBTS->center()));
+       m_caloSurfaceHelper->LoadMBTSSurfaces(std::pair<const Trk::Surface*,const Trk::Surface*>
+					     (new Trk::DiscSurface(mbtsNeg,mbtsBounds->innerRadius(),mbtsBounds->outerRadius()),
+					      new Trk::DiscSurface(mbtsPos,mbtsBounds->innerRadius(),mbtsBounds->outerRadius())));
+     }
+#endif
+     if (mbtsBounds && m_buildMBTS) {
+       float rmin = mbtsBounds->innerRadius(); 
+       float rmax = mbtsBounds->outerRadius(); 
+       //float d = mbtsBounds->halflengthZ();
+       Trk::DiscBounds* dibo = new Trk::DiscBounds(rmin,rmax);
+       // MBTS positions
+       Amg::Transform3D* mbtsNegZpos = new Amg::Transform3D(Amg::Translation3D(lArNegativeMBTS->center()));
+       Amg::Transform3D* mbtsPosZpos = new Amg::Transform3D(Amg::Translation3D(lArPositiveMBTS->center()));
+       // create the two Layers ( TODO: add trd surface subarray )
+       Trk::DiscLayer* mbtsNegLayer = new Trk::DiscLayer(mbtsNegZpos,dibo,
+                                                         //mbtsNegLayerSurfArray,
+                                                         Trk::HomogeneousLayerMaterial(Trk::MaterialProperties(*m_caloMaterial,1.),1.),
+                                                         1.);
+       Trk::DiscLayer* mbtsPosLayer = new Trk::DiscLayer(mbtsPosZpos,dibo->clone(),
+                                                         //mbtsPosLayerSurfArray,
+                                                         Trk::HomogeneousLayerMaterial(Trk::MaterialProperties(*m_caloMaterial,1.),1.),
+                                                         1.*Gaudi::Units::mm);
+
+       m_mbtsNegLayers=new std::vector<const Trk::Layer*>;
+       m_mbtsPosLayers=new std::vector<const Trk::Layer*>;
+       m_mbtsNegLayers->push_back(mbtsNegLayer);
+       m_mbtsPosLayers->push_back(mbtsPosLayer);       
+     }
+   }
+      
+   // building inner gap
+   Trk::CylinderVolumeBounds* lArG1Bounds =
+     new Trk::CylinderVolumeBounds( rInnerGapBP,
+				    //lArPositiveEndcapBounds->outerRadius(),
+				    keyDim[0].first,
+				    0.5*(keyDim.back().second-keyDim[0].second));
+   
+   Amg::Transform3D* lArG1P =
+     new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+   lArPositiveSectorInnerGap  = new Trk::TrackingVolume(lArG1P,
+							lArG1Bounds,
+							lArSectorInnerGapMaterial, 
+							m_mbtsPosLayers, 
+							"Calo::GapVolumes::LAr::PositiveSectorInnerGap");
+
+   Amg::Transform3D* lArG1N =
+     new  Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   lArNegativeSectorInnerGap  = new Trk::TrackingVolume(lArG1N,
+							lArG1Bounds->clone(),
+							lArSectorInnerGapMaterial, 
+							m_mbtsNegLayers,
+							"Calo::GapVolumes::LAr::NegativeSectorInnerGap");
+
+   // glue InnerGap with beam pipe volumes
+   const Trk::TrackingVolume* positiveInnerGap = 0;
+   if (innerGapBP.first) {
+     std::vector<const Trk::TrackingVolume*> volsInnerGap;
+     volsInnerGap.push_back(innerGapBP.first);
+     volsInnerGap.push_back(lArPositiveSectorInnerGap);
+     positiveInnerGap = m_trackingVolumeCreator->createContainerTrackingVolume(volsInnerGap,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveInnerGap"); 
+   } else positiveInnerGap = lArPositiveSectorInnerGap;
+
+   const Trk::TrackingVolume* negativeInnerGap = 0;
+   if (innerGapBP.second) {
+     std::vector<const Trk::TrackingVolume*> volsInnerGap;
+     volsInnerGap.push_back(innerGapBP.second);
+     volsInnerGap.push_back(lArNegativeSectorInnerGap);
+     negativeInnerGap = m_trackingVolumeCreator->createContainerTrackingVolume(volsInnerGap,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeInnerGap"); 
+   } else negativeInnerGap = lArNegativeSectorInnerGap;
+
+   // glue MBTS volumes with ID
+   std::vector<const Trk::TrackingVolume*> inBufferVolumes;
+   inBufferVolumes.push_back(negativeInnerGap);     
+   inBufferVolumes.push_back(innerVol);     
+   inBufferVolumes.push_back(positiveInnerGap);     
+   
+   const Trk::TrackingVolume* inDetEnclosed = m_trackingVolumeCreator->createContainerTrackingVolume(inBufferVolumes,
+												     *m_caloMaterial,
+                                                                           "Calo::Container::EnclosedInnerDetector");
+
+
+   ATH_MSG_DEBUG( " Inner detector enclosed (MBTS volumes)" );   
+
+   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // LAr endcap sector including the beam pipe 
+
+   // create beam pipe volumes for Endcap and return their outer radius 
+   float rEndcapBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> endcapBP = createBeamPipeVolumes( 
+							  keyDim.back().second,
+							  lArPositiveEndcap->center().z()+lArPositiveEndcapBounds->halflengthZ(),
+							  "Endcap", rEndcapBP);
+
+   // build lAr vessel around EC Presampler
+   const Trk::CylinderVolumeBounds* ecpBounds 
+      = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(lArPosECPresampler->volumeBounds()));
+   if (!ecpBounds) std::abort();
+    
+   float ecpHz = ecpBounds->halflengthZ();
+   float ecpRmin = ecpBounds->innerRadius();
+   float ecpRmax = ecpBounds->outerRadius();
+
+   Amg::Transform3D* ecpPos=new Amg::Transform3D(lArPosECPresampler->transform());
+   Amg::Transform3D* ecpNeg=new Amg::Transform3D(lArNegECPresampler->transform());
+
+   Trk::CylinderVolumeBounds* ecpUpBounds = new Trk::CylinderVolumeBounds(ecpRmax, keyDim.back().first, ecpHz);
+   Trk::CylinderVolumeBounds* ecpDownBounds = new Trk::CylinderVolumeBounds(rEndcapBP, ecpRmin, ecpHz);
+
+   const Trk::TrackingVolume* ecPresamplerCoverPos = new Trk::TrackingVolume(ecpPos,ecpUpBounds, *mAl,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerCover");
+   const Trk::TrackingVolume* ecPresamplerCoverNeg = new Trk::TrackingVolume(ecpNeg,ecpUpBounds->clone(), *mAl,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerCover");
+   const Trk::TrackingVolume* ecPresamplerInnerPos = new Trk::TrackingVolume(new Amg::Transform3D(*ecpPos),ecpDownBounds, *mAl,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerInner");
+   const Trk::TrackingVolume* ecPresamplerInnerNeg = new Trk::TrackingVolume(new Amg::Transform3D(*ecpNeg),ecpDownBounds->clone(),
+									     *mAl, dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerInner");
+
+   // glue EC presampler radially
+   std::vector<const Trk::TrackingVolume*> volsECP;
+   volsECP.push_back(ecPresamplerInnerPos);
+   volsECP.push_back(lArPosECPresampler);
+   volsECP.push_back(ecPresamplerCoverPos);
+   const Trk::TrackingVolume* positiveECP = m_trackingVolumeCreator->createContainerTrackingVolume(volsECP,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveECPresamplerR"); 
+   std::vector<const Trk::TrackingVolume*> volsECN;
+   volsECN.push_back(ecPresamplerInnerNeg);
+   volsECN.push_back(lArNegECPresampler);
+   volsECN.push_back(ecPresamplerCoverNeg);
+   const Trk::TrackingVolume* negativeECP = m_trackingVolumeCreator->createContainerTrackingVolume(volsECN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeECPresamplerR"); 
+
+   // add surrounding buffers
+   z = lArPosECPresampler->center().z()-ecpHz;
+   float z1 = lArPosECPresampler->center().z()+ecpHz;
+   float z2 = lArPositiveEndcap->center().z()-lArPositiveEndcapBounds->halflengthZ();
+   Amg::Transform3D* ecIPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0., 0.5*(z+keyDim.back().second))));
+   Amg::Transform3D* ecINeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(z+keyDim.back().second))));
+   Trk::CylinderVolumeBounds* ecpIBounds = new Trk::CylinderVolumeBounds(rEndcapBP, keyDim.back().first,0.5*(z-keyDim.back().second));
+   Amg::Transform3D* ecOPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0., 0.5*(z1+z2))));
+   Amg::Transform3D* ecONeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(z1+z2))));
+   Trk::CylinderVolumeBounds* ecpOBounds = new Trk::CylinderVolumeBounds(rEndcapBP, keyDim.back().first,0.5*(z2-z1));
+
+   const Trk::TrackingVolume* ecPresamplerInPos = new Trk::TrackingVolume(ecIPos,ecpIBounds, *mAr,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerIn");
+   const Trk::TrackingVolume* ecPresamplerInNeg = new Trk::TrackingVolume(ecINeg,ecpIBounds->clone(), *mAr,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerIn");
+   const Trk::TrackingVolume* ecPresamplerOutPos = new Trk::TrackingVolume(ecOPos,ecpOBounds, *mAr,
+									     dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::PositiveECPresamplerOut");
+   const Trk::TrackingVolume* ecPresamplerOutNeg = new Trk::TrackingVolume(ecONeg,ecpOBounds->clone(),
+									     *mAr, dummyLayers, dummyVolumes,
+									     "Calo::GapVolumes::LAr::NegativeECPresamplerOut");
+
+   // glue EC presampler in z
+   std::vector<const Trk::TrackingVolume*> volECP;
+   volECP.push_back(ecPresamplerInPos);
+   volECP.push_back(positiveECP);
+   volECP.push_back(ecPresamplerOutPos);
+   const Trk::TrackingVolume* positiveEP = m_trackingVolumeCreator->createContainerTrackingVolume(volECP,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveECPresampler"); 
+   std::vector<const Trk::TrackingVolume*> volECN;
+   volECN.push_back(ecPresamplerOutNeg);
+   volECN.push_back(negativeECP);
+   volECN.push_back(ecPresamplerInNeg);
+   const Trk::TrackingVolume* negativeEP = m_trackingVolumeCreator->createContainerTrackingVolume(volECN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeECPresampler");
+
+   // build lAr vessel around EMEC
+   ecpHz = lArPositiveEndcapBounds->halflengthZ();
+   ecpRmin = lArPositiveEndcapBounds->innerRadius();
+   ecpRmax = lArPositiveEndcapBounds->outerRadius();
+
+   Amg::Transform3D* ecPos=new Amg::Transform3D(lArPositiveEndcap->transform());
+   Amg::Transform3D* ecNeg=new Amg::Transform3D(lArNegativeEndcap->transform());
+
+   Trk::CylinderVolumeBounds* ecUpBounds = new Trk::CylinderVolumeBounds(ecpRmax, keyDim.back().first, ecpHz);
+   Trk::CylinderVolumeBounds* ecDownBounds = new Trk::CylinderVolumeBounds(rEndcapBP, ecpRmin, ecpHz);
+
+   const Trk::TrackingVolume* ecCoverPos = new Trk::TrackingVolume(ecPos,ecUpBounds, *mAr,
+								   dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::PositiveEndcapCover");
+   const Trk::TrackingVolume* ecCoverNeg = new Trk::TrackingVolume(ecNeg,ecUpBounds->clone(), *mAr,
+								   dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::NegativeEndcapCover");
+   const Trk::TrackingVolume* ecInnerPos = new Trk::TrackingVolume(new Amg::Transform3D(*ecPos),ecDownBounds, *mAl,
+								   dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::PositiveEndcapInner");
+   const Trk::TrackingVolume* ecInnerNeg = new Trk::TrackingVolume(new Amg::Transform3D(*ecNeg),ecDownBounds->clone(),
+								   *mAl, dummyLayers, dummyVolumes,
+								   "Calo::GapVolumes::LAr::NegativeEndcapInner");
+
+   // glue EMEC radially
+   std::vector<const Trk::TrackingVolume*> volsEC;
+   volsEC.push_back(ecInnerPos);
+   volsEC.push_back(lArPositiveEndcap);
+   volsEC.push_back(ecCoverPos);
+   const Trk::TrackingVolume* positiveEC = m_trackingVolumeCreator->createContainerTrackingVolume(volsEC,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveEndcapR"); 
+   std::vector<const Trk::TrackingVolume*> volsEN;
+   volsEN.push_back(ecInnerNeg);
+   volsEN.push_back(lArNegativeEndcap);
+   volsEN.push_back(ecCoverNeg);
+   const Trk::TrackingVolume* negativeEC = m_trackingVolumeCreator->createContainerTrackingVolume(volsEN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeEndcapR"); 
+
+   // glue presampler with EMEC
+   std::vector<const Trk::TrackingVolume*> volEEP;
+   volEEP.push_back(positiveEP);
+   volEEP.push_back(positiveEC);
+   const Trk::TrackingVolume* positiveEEP = m_trackingVolumeCreator->createContainerTrackingVolume(volEEP,
+									       *m_caloMaterial,
+									       "Calo::Container::PositiveEMEC"); 
+   std::vector<const Trk::TrackingVolume*> volEEN;
+   volEEN.push_back(negativeEC);
+   volEEN.push_back(negativeEP);
+   const Trk::TrackingVolume* negativeEEP = m_trackingVolumeCreator->createContainerTrackingVolume(volEEN,
+									       *m_caloMaterial,
+									       "Calo::Container::NegativeEMEC");
+
+   // glue EMEC sector with beam pipe volumes
+
+   std::vector<const Trk::TrackingVolume*> volsEndcapPos;
+   if (endcapBP.first)  volsEndcapPos.push_back(endcapBP.first);
+   volsEndcapPos.push_back(positiveEEP);
+
+   std::unique_ptr<const Trk::TrackingVolume> positiveEndcap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsEndcapPos,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveEndcap")); 
+
+   std::vector<const Trk::TrackingVolume*> volsEndcapNeg;
+   if (endcapBP.second)  volsEndcapNeg.push_back(endcapBP.second);
+   volsEndcapNeg.push_back(negativeEEP);
+
+   std::unique_ptr<const Trk::TrackingVolume> negativeEndcap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsEndcapNeg,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeEndcap")); 
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Hec sector + beam pipe + lAr cover
+
+   // create beam pipe volumes for Hec and return their outer radius 
+   float rHecBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> hecBP = createBeamPipeVolumes( 
+							  lArPositiveHec->center().z()-lArPositiveHecBounds->halflengthZ(),
+							  lArPositiveHec->center().z()+lArPositiveHecBounds->halflengthZ(),
+												       "Hec", rHecBP);
+   // HecInnerGap (new gap volume )
+   Trk::Material lArHecInnerGapMaterial = Trk::Material(390., 1223., 18.,9., 0.0014);
+
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArHecInnerGapBounds = new Trk::CylinderVolumeBounds(rHecBP,
+										   lArPositiveHecBounds->innerRadius(),
+										   lArPositiveHecBounds->halflengthZ() );
+
+   Amg::Transform3D* lArHecPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArPositiveHec->center().z())));
+   Amg::Transform3D* lArHecNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArNegativeHec->center().z())));
+
+   const Trk::TrackingVolume* lArPositiveHecInnerGap = new Trk::TrackingVolume(lArHecPos,lArHecInnerGapBounds ,
+									       *mAl,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::PositiveHecInnerGap");
+
+   const Trk::TrackingVolume* lArNegativeHecInnerGap = new Trk::TrackingVolume(lArHecNeg,lArHecInnerGapBounds->clone() ,
+									       *mAl,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::NegativeHecInnerGap");
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArHecOuterGapBounds = new Trk::CylinderVolumeBounds(lArPositiveHecBounds->outerRadius(),
+										   keyDim.back().first,
+										   lArPositiveHecBounds->halflengthZ() );
+
+   const Trk::TrackingVolume* lArPositiveHecOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArHecPos),
+									       lArHecOuterGapBounds ,
+									       *mAr,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::PositiveHecOuterGap");
+
+   const Trk::TrackingVolume* lArNegativeHecOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArHecNeg),
+									       lArHecOuterGapBounds->clone() ,
+									       *mAr,
+									       dummyLayers, dummyVolumes,
+									       "Calo::GapVolumes::LAr::NegativeHecOuterGap");
+
+   // glue Hec sector with beam pipe volumes
+
+   std::vector<const Trk::TrackingVolume*> volsHecPos;
+   if (hecBP.first)  volsHecPos.push_back(hecBP.first);
+   volsHecPos.push_back(lArPositiveHecInnerGap);
+   volsHecPos.push_back(lArPositiveHec);
+   volsHecPos.push_back(lArPositiveHecOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> positiveHec
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsHecPos,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveHec"));
+
+   std::vector<const Trk::TrackingVolume*> volsHecNeg;
+   if (hecBP.second)  volsHecNeg.push_back(hecBP.second);
+   volsHecNeg.push_back(lArNegativeHecInnerGap);
+   volsHecNeg.push_back(lArNegativeHec);
+   volsHecNeg.push_back(lArNegativeHecOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> negativeHec
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsHecNeg,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeHec"));
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Fcal sector + beam pipe + lAr cover
+
+   // create beam pipe volumes for Fcal and return their outer radius 
+   float rFcalBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> fcalBP = createBeamPipeVolumes( 
+							  lArPositiveFcal->center().z()-lArPositiveFcalBounds->halflengthZ(),
+							  lArPositiveFcal->center().z()+lArPositiveFcalBounds->halflengthZ(),
+												       "Fcal", rFcalBP);
+   // FcalInnerGap (new gap volume )
+   //Trk::Material lArFcalInnerGapMaterial = Trk::Material(390., 1223., 40.,18., 0.0014);
+
+   
+   if ( rFcalBP > lArPositiveFcalBounds->innerRadius()) {
+     ATH_MSG_ERROR("PROBLEM : beam pipe collide with Fcal:"<< rFcalBP <<">" << lArPositiveFcalBounds->innerRadius()<<", abort" );  
+     // create dummy infinite IOV Range 
+     EventIDRange range;
+     return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range,0);
+     
+   }
+
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArFcalInnerGapBounds = new Trk::CylinderVolumeBounds(rFcalBP,
+										    lArPositiveFcalBounds->innerRadius(),
+										    lArPositiveFcalBounds->halflengthZ() );
+
+   Amg::Transform3D* lArFcalPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArPositiveFcal->center().z())));
+   Amg::Transform3D* lArFcalNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,lArNegativeFcal->center().z())));
+
+   const Trk::TrackingVolume* lArPositiveFcalInnerGap = new Trk::TrackingVolume(lArFcalPos,lArFcalInnerGapBounds ,
+										*mAl,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::PositiveFcalInnerGap");
+
+   const Trk::TrackingVolume* lArNegativeFcalInnerGap = new Trk::TrackingVolume(lArFcalNeg,lArFcalInnerGapBounds->clone() ,
+										*mAl,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::NegativeFcalInnerGap");
+
+
+   // create the Bounds
+   Trk::CylinderVolumeBounds* lArFcalOuterGapBounds = new Trk::CylinderVolumeBounds(lArPositiveHecBounds->outerRadius(),
+										    keyDim.back().first,
+										    lArPositiveFcalBounds->halflengthZ() );
+
+   const Trk::TrackingVolume* lArPositiveFcalOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArFcalPos),
+										lArFcalOuterGapBounds ,
+										*mAr,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::PositiveFcalOuterGap");
+
+   const Trk::TrackingVolume* lArNegativeFcalOuterGap = new Trk::TrackingVolume(new Amg::Transform3D(*lArFcalNeg),
+										lArFcalOuterGapBounds->clone() ,
+										*mAr,
+										dummyLayers, dummyVolumes,
+										"Calo::GapVolumes::LAr::NegativeFcalOuterGap");
+
+   // glue Fcal sector with beam pipe volumes
+
+   std::vector<const Trk::TrackingVolume*> volsFcalPos;
+   if (fcalBP.first)  volsFcalPos.push_back(fcalBP.first);
+   volsFcalPos.push_back(lArPositiveFcalInnerGap);
+   volsFcalPos.push_back(lArPositiveFcal);
+   volsFcalPos.push_back(lArPositiveHecFcalCover);
+   volsFcalPos.push_back(lArPositiveFcalOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> positiveFcal
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsFcalPos,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveFcal"));
+
+   std::vector<const Trk::TrackingVolume*> volsFcalNeg;
+   if (fcalBP.second)  volsFcalNeg.push_back(fcalBP.second);
+   volsFcalNeg.push_back(lArNegativeFcalInnerGap);
+   volsFcalNeg.push_back(lArNegativeFcal);
+   volsFcalNeg.push_back(lArNegativeHecFcalCover);
+   volsFcalNeg.push_back(lArNegativeFcalOuterGap);
+
+   std::unique_ptr<const Trk::TrackingVolume> negativeFcal
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsFcalNeg,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeFcal"));
+
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Outer endcap sector + beam pipe
+
+   // create beam pipe volumes for Outer sector and return their outer radius 
+   float rOutBP=0.;
+   std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> outBP = createBeamPipeVolumes( lArPositiveOuterBoundary, 
+												   caloPositiveOuterBoundary,
+												   "Outer", rOutBP);
+
+   Trk::Material lArSectorOuterGapMat = Trk::Material(20.5, 723., 64., 28., 0.0084);
+   
+   Trk::CylinderVolumeBounds* lArSectorOuterG0Bounds = new Trk::CylinderVolumeBounds( rOutBP, 430.,
+										      //lArPositiveEndcapBounds->outerRadius(),
+							   0.5*(caloPositiveOuterBoundary-lArPositiveOuterBoundary));
+
+   Trk::CylinderVolumeBounds* lArSectorOuterG1Bounds = new Trk::CylinderVolumeBounds( 430., keyDim.back().first,
+										      //lArPositiveEndcapBounds->outerRadius(),
+							   0.5*(caloPositiveOuterBoundary-lArPositiveOuterBoundary));
+   
+   z = 0.5*(caloPositiveOuterBoundary+lArPositiveOuterBoundary);
+
+   Amg::Transform3D* lArSecOutG1P = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+   Amg::Transform3D* lArSecOutG0P = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+
+   lArPositiveSectorOuterGap0   =  new Trk::TrackingVolume(lArSecOutG0P, lArSectorOuterG0Bounds,
+							  lArSectorOuterGapMat, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::PositiveSectorOuterGap0");
+
+   lArPositiveSectorOuterGap   =  new Trk::TrackingVolume(lArSecOutG1P, lArSectorOuterG1Bounds,
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::PositiveSectorOuterGap");
+
+   Amg::Transform3D* lArSecOutG1N = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   Amg::Transform3D* lArSecOutG0N = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+
+   lArNegativeSectorOuterGap0   =  new Trk::TrackingVolume(lArSecOutG0N, lArSectorOuterG0Bounds->clone(),
+							  lArSectorOuterGapMat, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::NegativeSectorOuterGap0");
+
+   lArNegativeSectorOuterGap   =  new Trk::TrackingVolume(lArSecOutG1N, lArSectorOuterG1Bounds->clone(),
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LAr::NegativeSectorOuterGap");
+
+   // glue OuterGap with beam pipe volumes
+   std::vector<const Trk::TrackingVolume*> volsOuterGapP;
+   if (outBP.first) volsOuterGapP.push_back(outBP.first);
+   volsOuterGapP.push_back(lArPositiveSectorOuterGap0);
+   volsOuterGapP.push_back(lArPositiveSectorOuterGap);
+   std::unique_ptr<const Trk::TrackingVolume> positiveOuterGap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsOuterGapP,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::PositiveOuterGap"));
+
+   std::vector<const Trk::TrackingVolume*> volsOuterGapN;
+   if (outBP.second) volsOuterGapN.push_back(outBP.second);
+   volsOuterGapN.push_back(lArNegativeSectorOuterGap0);
+   volsOuterGapN.push_back(lArNegativeSectorOuterGap);
+   std::unique_ptr<const Trk::TrackingVolume> negativeOuterGap
+     (m_trackingVolumeCreator->createContainerTrackingVolume(volsOuterGapN,
+                                                             *m_caloMaterial,
+                                                             "Calo::Container::NegativeOuterGap"));
+
+   ATH_MSG_DEBUG( "Endcap volumes ready" );
+
+   // ++ (ii) lArNegativeSector 
+   const Trk::TrackingVolume* lArNegativeSector           = 0;             
+   // +++ has 4 sub volumes in Z
+   std::vector<const Trk::TrackingVolume*> lArNegativeSectorVolumes;
+   // +++ (A) -> Outer sector 
+   lArNegativeSectorVolumes.push_back(negativeOuterGap.release());
+   // +++ (B) -> Fcal sector
+   lArNegativeSectorVolumes.push_back(negativeFcal.release());
+   // +++ (C) -> Hec sector
+   lArNegativeSectorVolumes.push_back(negativeHec.release());
+   // +++ (D) -> Endcap sector
+   lArNegativeSectorVolumes.push_back(negativeEndcap.release());
+   // +++ all exists : create super volume (ii)
+   lArNegativeSector = m_trackingVolumeCreator->createContainerTrackingVolume( lArNegativeSectorVolumes,
+									       *m_caloMaterial,
+									       "Calo::LAr::Container::NegativeSector");
+
+   // ++ (ii) lArPositiveSector 
+   const Trk::TrackingVolume* lArPositiveSector           = 0;             
+   // +++ has 4 sub volumes in Z
+   std::vector<const Trk::TrackingVolume*> lArPositiveSectorVolumes;
+   // +++ (A) -> Endcap sector
+   lArPositiveSectorVolumes.push_back(positiveEndcap.release());	 
+   // +++ (B) -> Hec sector
+   lArPositiveSectorVolumes.push_back(positiveHec.release());
+   // +++ (C) -> Fcal sector
+   lArPositiveSectorVolumes.push_back(positiveFcal.release());
+   // +++ (D) -> OuterGap
+   lArPositiveSectorVolumes.push_back(positiveOuterGap.release());
+   // +++ all exists : create super volume (ii)
+   lArPositiveSector = m_trackingVolumeCreator->createContainerTrackingVolume( lArPositiveSectorVolumes,
+									       *m_caloMaterial,
+									       "Calo::LAr::Container::PositiveSector");
+   
+   ////////////////////////////////////////////////////////////////////////////////////// 
+   // central LAr barrel
+   //
+   // solenoid gap 
+   Trk::CylinderVolumeBounds* trtSolGapBounds = new Trk::CylinderVolumeBounds(  keyDim[0].first,
+										solenoidBounds->innerRadius(),
+										solenoidBounds->halflengthZ());
+
+   // solenoid gap is not completely empty
+   Trk::Material solGapMat(535.,2871.,18.6,9.1,0.00038);
+   
+   
+   trtSolenoidGap = new Trk::TrackingVolume(0,
+					    trtSolGapBounds,
+					    solGapMat,
+					    dummyLayers, dummyVolumes, 
+					    "Calo::GapVolumes::SolenoidGap");
+
+   Trk::CylinderVolumeBounds* lArTileCentralG1Bounds = new Trk::CylinderVolumeBounds( lArBarrelBounds->outerRadius(),
+										      tileCombinedBounds->innerRadius(),
+										      lArBarrelBounds->halflengthZ());
+                                                 
+   
+
+   lArTileCentralSectorGap      = new Trk::TrackingVolume(0, lArTileCentralG1Bounds,
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LArTileCentralSectorGap");
+
+
+   const Trk::TrackingVolume* lArCentralBarrelSector    = 0;
+   // ++ has 6 sub volumes in R
+   std::vector<const Trk::TrackingVolume*> lArCentralBarrelSectorVolumes;
+   // ++++ (a) -> solenoid gap 
+   lArCentralBarrelSectorVolumes.push_back(trtSolenoidGap);
+   // ++++ (b) -> solenoid (exists already)
+   lArCentralBarrelSectorVolumes.push_back(solenoid);
+   // ++++ (c) -> solenoidlArPresamplerGap (exists already)
+   lArCentralBarrelSectorVolumes.push_back(solenoidlArPresamplerGap);
+   // ++++ (d) -> lArBarrelPresampler (exists already)
+   lArCentralBarrelSectorVolumes.push_back(lArBarrelPresampler);
+   // ++++ (e) -> lArBarrel (exists already)
+   lArCentralBarrelSectorVolumes.push_back(lArBarrel);
+   // ++++ (f) -> lArTile gap 
+   lArCentralBarrelSectorVolumes.push_back(lArTileCentralSectorGap);
+   // ++++ all sub volumes exist: build the super volume
+   lArCentralBarrelSector =  m_trackingVolumeCreator->createContainerTrackingVolume(
+										    lArCentralBarrelSectorVolumes,
+										    *m_caloMaterial,
+										    "Calo::Containers::LAr::CentralBarrelSector",
+										    false, true);
+   /////////////////////////////////////////////////////////////////////////////////////
+   // side buffers   
+   // the Tile Crack volume (TileGap3, enum 17) inserted here
+   // binned material for Crack : steering in binEta
+   // TODO turn into 2D binned array
+   std::vector<const Trk::IdentifiedMaterial*> matCrack;
+   // layer material can be adjusted here
+   int baseID = Trk::GeometrySignature(Trk::Calo)*1000 + 17;
+   matCrack.push_back(new std::pair<const Trk::Material*,int>(mScint,baseID));
+   matCrack.push_back(new std::pair<const Trk::Material*,int>(m_caloMaterial,-1));
+   matCrack.push_back(new std::pair<const Trk::Material*,int>(mAl,-1));
+   //
+   Trk::BinUtility* bun = new Trk::BinUtility(3,-1.8,-1.2,Trk::open,Trk::binEta);
+   Trk::BinUtility* bup = new Trk::BinUtility(3, 1.2,1.8,Trk::open,Trk::binEta);
+   // array of indices
+   std::vector<std::vector<size_t> > indexP;  
+   std::vector<std::vector<size_t> > indexN;  
+   // binned material for LAr : layer depth per eta bin
+   std::vector< Trk::BinUtility*> layDN(bun->bins());
+   std::vector< Trk::BinUtility*> layUP(bup->bins());
+   double crackZ1 = 3532.;
+   double crackZ2 = 3540.;
+   // construct bin utilities 
+   std::vector<float> steps;
+   for (unsigned int i=0; i< bup->bins(); i++) {
+     steps.clear();
+     std::vector<size_t> indx; indx.clear();
+     steps.push_back(crackZ1);
+     indx.push_back( i<2 ? 0 : 1);
+     steps.push_back(crackZ2);
+     indx.push_back(2);
+     steps.push_back(keyDim.back().second);
+     Trk::BinUtility* zBU = new Trk::BinUtility(steps, Trk::open, Trk::binZ);
+     layUP[i] = zBU;
+     indexP.push_back(indx);
+   } 
+
+   const Trk::BinnedMaterial* crackBinPos = new Trk::BinnedMaterial(crackMaterial,bup,layUP,indexP,matCrack);
+   
+   Amg::Transform3D* align=0;
+   
+   Trk::CylinderVolumeBounds* crackBoundsPos = new Trk::CylinderVolumeBounds( keyDim[0].first,
+									      tileCombinedBounds->innerRadius(),
+									      0.5*(keyDim.back().second-crackZ1));
+   z = 0.5*(keyDim.back().second+crackZ1);
+   Amg::Transform3D* crackPosTransform = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+   
+   const Trk::AlignableTrackingVolume* crackPos = new Trk::AlignableTrackingVolume(crackPosTransform,align,
+										   crackBoundsPos,
+										   crackBinPos,
+										   17,
+										   "Calo::Detectors::Tile::CrackPos");
+
+   for (unsigned int i=0; i< bun->bins(); i++) {
+     steps.clear();
+     std::vector<size_t> indx; indx.clear();
+     steps.push_back(-keyDim.back().second);
+     indx.push_back(2);
+     steps.push_back(-crackZ2);
+     indx.push_back( i>0 ? 0 : 1);
+     steps.push_back(-crackZ1);
+     Trk::BinUtility* zBU = new Trk::BinUtility(steps, Trk::open, Trk::binZ);
+     layDN[i] = zBU;
+     indexN.push_back(indx);
+   } 
+
+   const Trk::BinnedMaterial* crackBinNeg = new Trk::BinnedMaterial(crackMaterial,bun,layDN,indexN,matCrack);
+   
+   align=0;
+   
+   Amg::Transform3D* crackNegTransform = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   
+   const Trk::AlignableTrackingVolume* crackNeg = new Trk::AlignableTrackingVolume(crackNegTransform,align,
+										   crackBoundsPos->clone(),
+										   crackBinNeg,
+										   17,
+										   "Calo::Detectors::Tile::CrackNeg");
+    ////
+  
+   Trk::CylinderVolumeBounds* lArCentralG1Bounds = new Trk::CylinderVolumeBounds( keyDim[0].first,
+										  tileCombinedBounds->innerRadius(),
+										  0.5*(crackZ1-lArBarrelBounds->halflengthZ()));
+
+   z = 0.5*(crackZ1+lArBarrelBounds->halflengthZ());
+   Amg::Transform3D* lArCentralG1P = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,z)));
+
+   
+   lArCentralPositiveGap        = new Trk::TrackingVolume(lArCentralG1P, lArCentralG1Bounds,
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LArCentralPositiveGap");
+
+   Amg::Transform3D* lArCentralG1N = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-z)));
+   
+   lArCentralNegativeGap        = new Trk::TrackingVolume(lArCentralG1N, lArCentralG1Bounds->clone(),
+							  *mAr, 
+							  dummyLayers, dummyVolumes, 
+							  "Calo::GapVolumes::LArCentralNegativeGap");
+
+   // glue laterally
+   const Trk::TrackingVolume* lArCentralSector    = 0;
+   // ++ has 5 sub volumes in z
+   std::vector<const Trk::TrackingVolume*> lArCentralSectorVolumes;
+   // ++++ (a) -> negative crack
+   lArCentralSectorVolumes.push_back(crackNeg);
+   // ++++ (b) -> negative gap 
+   lArCentralSectorVolumes.push_back(lArCentralNegativeGap);
+   // ++++ (c) -> central barrel 
+   lArCentralSectorVolumes.push_back(lArCentralBarrelSector);
+   // ++++ (d) -> positive gap 
+   lArCentralSectorVolumes.push_back(lArCentralPositiveGap);
+   // ++++ (e) -> positive crack 
+   lArCentralSectorVolumes.push_back(crackPos);
+   // ++++ all sub volumes exist: build the super volume
+   lArCentralSector =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									     lArCentralSectorVolumes,
+									     *m_caloMaterial,
+									     "Calo::Containers::LAr::CentralSector");
+  
+   // glue with ID sector
+   const Trk::TrackingVolume* caloCentralSector    = 0;
+   // ++ has 2 sub volumes in R
+   std::vector<const Trk::TrackingVolume*> caloCentralSectorVolumes;
+   // ++++ (a) -> ID sector
+   caloCentralSectorVolumes.push_back(inDetEnclosed);
+   // ++++ (b) -> LAr sector 
+   caloCentralSectorVolumes.push_back(lArCentralSector);
+   // ++++ all sub volumes exist: build the super volume
+   caloCentralSector =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									  caloCentralSectorVolumes,
+									  *m_caloMaterial,
+									  "Calo::Containers::CaloCentralSector");
+
+   //std::cout <<"Combined LAr sector ready"<< std::endl;
+   //////////////////////////////////////////////////////////////////////
+
+
+   // glue laterally with endcaps
+   const Trk::TrackingVolume* lArCombined    = 0;
+   // ++ has 3 sub volumes in z
+   std::vector<const Trk::TrackingVolume*> lArCombinedVolumes;
+   // ++++ (a) -> negative endcap 
+   lArCombinedVolumes.push_back(lArNegativeSector);
+   // ++++ (b) -> barrel 
+   lArCombinedVolumes.push_back(caloCentralSector);
+   // ++++ (a) -> positive endcap 
+   lArCombinedVolumes.push_back(lArPositiveSector);
+   // ++++ all sub volumes exist: build the super volume
+   lArCombined =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									 lArCombinedVolumes,
+									 *m_caloMaterial,
+									 "Calo::Containers::LAr::Combined");
+ 
+   //std::cout <<"Combined LAr ready " << std::endl; 
+
+   // glue with LAr sector
+   const Trk::TrackingVolume* caloCombined    = 0;
+   // ++ has 2 sub volumes in R
+   std::vector<const Trk::TrackingVolume*> caloVolumes;
+   // ++++ (a) -> LAr sector
+   caloVolumes.push_back(lArCombined);
+   // ++++ (b) -> Tile sector 
+   caloVolumes.push_back(tileCombined);
+   // ++++ all sub volumes exist: build the super volume
+   caloCombined =  m_trackingVolumeCreator->createContainerTrackingVolume(
+									 caloVolumes,
+									 *m_caloMaterial,
+									 "Calo::Containers::CombinedCalo");
+
+   //std::cout <<"Combined Calo ready"<< std::endl;
+
+   ///////////////////////////////////////////////////////////////////////////////////////////////
+
+   // build the radial buffer volume to synchronize the radial envelope dimensions 
+   const Trk::TrackingVolume* centralBuffer = 0;
+   const Trk::TrackingVolume* ecPosBuffer = 0;
+   const Trk::TrackingVolume* ecNegBuffer = 0;
+    
+   if ( caloVolsOuterRadius >  m_caloDefaultRadius ) {
+     ATH_MSG_VERBOSE( "Calo volumes exceeds envelope radius: adjusting envelope (de-synchronizing...)" );
+     m_caloDefaultRadius = caloVolsOuterRadius;
+   }
+
+   if ( caloVolsOuterRadius <  m_caloDefaultRadius ) {
+     ATH_MSG_VERBOSE( "Build radial buffer to synchronize the boundaries in between R "<< caloVolsOuterRadius<<" and "<< m_caloDefaultRadius );
+     
+     Trk::CylinderVolumeBounds* centralSynBounds = new Trk::CylinderVolumeBounds(caloVolsOuterRadius,
+										 m_caloDefaultRadius,
+										 caloVolsExtendZ);
+     centralBuffer = new Trk::TrackingVolume(0, centralSynBounds,
+					     *m_caloMaterial,
+					     dummyLayers, dummyVolumes,
+					     "Calo::GapVolumes::EnvelopeBuffer");
+   }
+
+   if ( caloVolsExtendZ <  m_caloDefaultHalflengthZ ) {
+     ATH_MSG_VERBOSE( "Build longitudinal buffers to synchronize the boundaries in between Z "<< caloVolsExtendZ<<" and "<< m_caloDefaultHalflengthZ );
+     
+     Trk::CylinderVolumeBounds* endcapSynBounds = new Trk::CylinderVolumeBounds(0., m_caloDefaultRadius,
+										0.5*(m_caloDefaultHalflengthZ-caloVolsExtendZ));
+     // endcap buffers not empty 
+     Trk::Material ecBuffMat(53./0.38, 355./0.38, 20., 10., 0.0053*pow(0.38,3));
+     
+     float zPos = 0.5*(m_caloDefaultHalflengthZ+caloVolsExtendZ);
+     ecPosBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,zPos))),
+					   endcapSynBounds,
+					   *mAr,
+					   dummyLayers, dummyVolumes,
+					   "Calo::GapVolumes::PosECBuffer");
+
+     ecNegBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-zPos))),
+					   endcapSynBounds->clone(),
+					   *mAr,
+					   dummyLayers, dummyVolumes,
+					   "Calo::GapVolumes::NegECBuffer");
+   }
+   
+   ATH_MSG_VERBOSE( "All gap volumes for the Calorimeter created. Starting to build Volume Hiearchy." );   
+	
+   /////////////////////////////////////////////////////////////////////////////////////////////////
+   
+   ATH_MSG_VERBOSE( "Resolve MS cutouts:" );   
+   
+   // resolve number of additional cutout volumes
+   int nCutVol = 0;
+   std::vector<float> zCutStep;
+   std::vector<float> rCutStep;
+   if (msCutouts.size()>1) {
+     zCutStep.push_back(msCutouts[0].second); 
+     rCutStep.push_back(msCutouts[0].first); 
+     for (unsigned int i=1; i<msCutouts.size(); i++) {
+       if (msCutouts[i].second == zCutStep.back()) rCutStep.push_back(msCutouts[i].first);
+       else zCutStep.push_back(msCutouts[i].second);
+     }
+     nCutVol = zCutStep.size()-1;
+   }
+   if (nCutVol>0) ATH_MSG_VERBOSE( nCutVol << " MS cutout volume(s) required " );
+
+   std::vector<const Trk::TrackingVolume*> forwardCutoutVols;
+   std::vector<const Trk::TrackingVolume*> backwardCutoutVols;
+
+   // cutout region not empty 
+   std::vector<Trk::Material> cutOutMat;
+   cutOutMat.push_back(Trk::Material(19.9, 213., 50., 23., 0.0065));     // 3.5 Fe + 1 Ar : verify
+   cutOutMat.push_back(*m_caloMaterial);
+   //cutOutMat.push_back(Trk::Material(18.74, 200.9, 52.36, 24.09, 0.0069));
+   
+   if (nCutVol>0) {
+     // loop over zCutStep, rCutStep[0] gives the fixed outer radius, rCutStep[i] the cutout radius for ith volume
+     float rout = rCutStep[0];
+     float zlow = zCutStep[0];
+     for (unsigned int i=1; i<zCutStep.size(); i++) {
+       float zup  = zCutStep[i];
+       float rcut = rCutStep[i];
+       std::stringstream ss;
+       ss << i;
+       // get beam pipe volumes
+       float rCutOutBP = 0.;
+       std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> cutOutBP = createBeamPipeVolumes(zlow,zup,  
+												       "CutOuts"+ss.str(), rCutOutBP);
+
+       // build inner part ( -> Calo )
+       unsigned int mindex = i>1 ? 1 : i;
+       
+       Trk::CylinderVolumeBounds* cutInBounds = new Trk::CylinderVolumeBounds( rCutOutBP,rcut, 0.5*(zup-zlow));
+       const Trk::TrackingVolume* caloInPos = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zup+zlow)))),
+								      cutInBounds,
+								      cutOutMat[mindex],
+								      dummyLayers, dummyVolumes,
+								      "Calo::GapVolumes::CaloPositiveCutIn"+ss.str());
+       const Trk::TrackingVolume* caloInNeg = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(zup+zlow)))),
+								      cutInBounds->clone(),
+								      cutOutMat[mindex],
+								      dummyLayers, dummyVolumes,
+								      "Calo::GapVolumes::CaloNegativeCutIn"+ss.str());
+       // build cutout ( -> MS ) : geometry signature needs to be resolved later : follow naming convention 
+       Trk::CylinderVolumeBounds* cutOutBounds = new Trk::CylinderVolumeBounds( rcut, rout, 0.5*(zup-zlow));
+       const Trk::TrackingVolume* caloOutPos = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zup+zlow)))),
+								       cutOutBounds,
+								       *m_caloMaterial,
+								       dummyLayers, dummyVolumes,
+								       "Muon::GapVolumes::CaloPositiveCutOut"+ss.str());
+       const Trk::TrackingVolume* caloOutNeg = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(zup+zlow)))),
+								       cutOutBounds->clone(),
+								       *m_caloMaterial,
+								       dummyLayers, dummyVolumes,
+								       "Muon::GapVolumes::CaloNegativeCutOut"+ss.str());
+
+       // sign
+       caloOutPos->sign(Trk::MS);
+       caloOutNeg->sign(Trk::MS);
+   
+       // glue radially and save for final gluing
+       std::vector<const Trk::TrackingVolume*> cvPos;
+       cvPos.push_back(cutOutBP.first);
+       cvPos.push_back(caloInPos);
+       cvPos.push_back(caloOutPos);
+       const Trk::TrackingVolume* cutOutPos = m_trackingVolumeCreator->createContainerTrackingVolume(cvPos,
+												*m_caloMaterial,
+										"Calo::GapVolumes::CaloPositiveCutoutVolume"+ss.str());
+       forwardCutoutVols.push_back(cutOutPos);      
+       //
+       std::vector<const Trk::TrackingVolume*> cvNeg;
+       cvNeg.push_back(cutOutBP.second);
+       cvNeg.push_back(caloInNeg);
+       cvNeg.push_back(caloOutNeg);
+       const Trk::TrackingVolume* cutOutNeg = m_trackingVolumeCreator->createContainerTrackingVolume(cvNeg,
+												*m_caloMaterial,
+										"Calo::GapVolumes::CaloNegativeCutoutVolume"+ss.str());
+       backwardCutoutVols.insert(backwardCutoutVols.begin(),cutOutNeg);      
+  
+       zlow = zup;
+     }
+   }
+
+  /////////////////
+
+ 
+  if (!centralBuffer) {   //(XX)
+    // all volumes exist : create the super volume at top level
+    calorimeter = caloCombined;
+
+  } else {                //(X)
+
+    std::vector<const Trk::TrackingVolume*> envRVols;
+    envRVols.push_back(caloCombined);
+    envRVols.push_back(centralBuffer);
+    
+    // add cutouts - final step
+    if ( forwardCutoutVols.size()>0 || ecNegBuffer ) {
+      
+      const Trk::TrackingVolume* caloRVolume = m_trackingVolumeCreator->createContainerTrackingVolume(envRVols,
+												      *m_caloMaterial,
+												      "Calo::Containers::CombinedRCalo");
+      std::vector<const Trk::TrackingVolume*> envZVols;
+      for (unsigned int i=0; i<backwardCutoutVols.size(); i++) envZVols.push_back(backwardCutoutVols[i]);   
+      if (ecNegBuffer) envZVols.push_back(ecNegBuffer);
+      envZVols.push_back(caloRVolume);  
+      if (ecPosBuffer) envZVols.push_back(ecPosBuffer);
+      for (unsigned int i=0; i<forwardCutoutVols.size(); i++) envZVols.push_back(forwardCutoutVols[i]);
+      
+      calorimeter = m_trackingVolumeCreator->createContainerTrackingVolume(envZVols,
+									   *m_caloMaterial,
+									   m_exitVolume);
+      
+      
+      
+    } else { // if no cutouts or endcap buffers, this is the top calo volume  
+      
+      calorimeter = m_trackingVolumeCreator->createContainerTrackingVolume(envRVols,
+									   *m_caloMaterial,
+									   m_exitVolume);
+    }
+    
+  }
+
+  ATH_MSG_VERBOSE( "TrackingVolume 'Calorimeter' built successfully. Wrap it in TrackingGeometry." );
+
+  delete lArVolumes; lArVolumes = 0;
+  delete tileVolumes; tileVolumes = 0;
+  
+  caloTrackingGeometry = new Trk::TrackingGeometry(calorimeter);
+  
+  if (msgLvl(MSG::VERBOSE) && caloTrackingGeometry) 
+    caloTrackingGeometry->printVolumeHierarchy(msg(MSG::VERBOSE));   
+  
+  if (m_indexStaticLayers && caloTrackingGeometry)
+    caloTrackingGeometry->indexStaticLayers( geometrySignature() );   
+  
+//     /** enumeration of samplings (i.e.layers) separately for various sub calorimeters */
+//     enum CaloSample {
+//       PreSamplerB=0, EMB1, EMB2, EMB3,       // LAr barrel
+//       PreSamplerE, EME1, EME2, EME3,         // LAr EM endcap
+//       HEC0, HEC1, HEC2, HEC3,                // Hadronic end cap cal.
+//       TileBar0, TileBar1, TileBar2,          // Tile barrel
+//       TileGap1, TileGap2, TileGap3,          // Tile gap (ITC & scint)
+//       TileExt0, TileExt1, TileExt2,          // Tile extended barrel
+//       FCAL0, FCAL1, FCAL2,                   // Forward EM endcap
+//       Unknown
+//     };
+  // create dummy infinite IOV Range 
+  // return what you have ...
+  return std::make_pair(range, caloTrackingGeometry);
+}
+
+void Calo::CaloTrackingGeometryBuilderCond::registerInLayerIndexCaloSampleMap(
+                                             Trk::LayerIndexSampleMap& licsMap,
+                                             std::vector<CaloCell_ID::CaloSample> ccid,
+                                             const Trk::TrackingVolume& vol,
+                                             int side) const
+{
+
+  ATH_MSG_VERBOSE( "[+] Registering layers of TrackingVolume '" << vol.volumeName() << "' in LayerIndex/CaloCell_ID map" );   
+
+  // get the confined Layers from the TrackingVolume
+  const Trk::LayerArray* confinedLayers = vol.confinedLayers();
+  if (!confinedLayers) return;
+  
+  const std::vector<const Trk::Layer*>& layerObjects = confinedLayers->arrayObjects();
+  std::vector<const Trk::Layer*>::const_iterator layerObjIter = layerObjects.begin();
+  std::vector<const Trk::Layer*>::const_iterator layerObjEnd  = layerObjects.end();
+  
+  // now pick out the material layers (and skip the navigation ones)
+  std::vector<const Trk::Layer*> materialLayers;
+  for ( ; layerObjIter != layerObjEnd; ++layerObjIter)
+     if ((*layerObjIter)->layerMaterialProperties()) materialLayers.push_back((*layerObjIter));
+  
+  unsigned int matLaySize = materialLayers.size();
+  unsigned int ccidSize   = ccid.size();
+        
+  ATH_MSG_VERBOSE( "[+] Found " << matLaySize << " material layers ( " << ccidSize << " CaloSample ids )" );  
+  if ( matLaySize != ccidSize ) return;
+  
+  // everything's fine for side > 0
+  if (side > 0){
+     // match 1-to-1 
+     std::vector<const Trk::Layer*>::iterator layerIt             = materialLayers.begin();
+     std::vector<const Trk::Layer*>::iterator layerItEnd          = materialLayers.end();
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidIt    = ccid.begin();
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidItEnd = ccid.end();
+          
+     for ( ; layerIt != layerItEnd  && ccidIt != ccidItEnd; ++layerIt, ++ccidIt)
+         licsMap.insert(std::make_pair((*layerIt)->layerIndex(),int(*ccidIt)));
+       
+  } else {  
+    // the order needs to be reversed, because TG has z-ordering positive defined
+    
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidIt    = ccid.begin();
+     std::vector<CaloCell_ID::CaloSample>::iterator ccidItEnd = ccid.end();
+          
+     for ( ;ccidIt != ccidItEnd; ++ccidIt, --matLaySize)
+         licsMap.insert(std::make_pair((materialLayers[matLaySize-1])->layerIndex(),int(*ccidIt)));    
+  
+  }
+  
+}
+
+std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> Calo::CaloTrackingGeometryBuilderCond::createBeamPipeVolumes(float zmin, float zmax, 
+															  std::string name,float& outerRadius ) const
+{
+  outerRadius = 0.;
+
+  // dummy objects
+  const Trk::LayerArray* dummyLayers = 0;
+  const Trk::TrackingVolumeArray* dummyVolumes = 0;
+
+  // beam pipe thickness along the z distance
+  if (!m_bpCutouts.size()) {
+    return std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> (0,0);
+  }
+
+  RZPairVector dim; 
+  dim.push_back(RZPair(m_bpCutouts[0].first,zmin));
+  float rOut = m_bpCutouts[0].first;
+  for (unsigned int i=0; i<m_bpCutouts.size(); i++) {
+    if (m_bpCutouts[i].second<=dim[0].second) dim[0].first=m_bpCutouts[i].first;
+    else if ( m_bpCutouts[i].second<=zmax ) dim.push_back(m_bpCutouts[i]);
+    if ( m_bpCutouts[i].second<=zmax ) rOut = m_bpCutouts[i].first;
+  }
+  
+  if (dim.back().second < zmax) dim.push_back(RZPair(rOut,zmax));
+
+  if (dim.size()==2) {   // simple case
+    
+    outerRadius = dim[0].first;
+    
+    Trk::CylinderVolumeBounds* bpBounds = new Trk::CylinderVolumeBounds( 0., outerRadius,
+									 0.5*(zmax-zmin));
+    
+    Amg::Transform3D* bpPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zmin+zmax))));
+    
+    const Trk::TrackingVolume* bpVolPos = new Trk::TrackingVolume(bpPos, bpBounds,
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Positive"+name);
+
+    Amg::Transform3D* bpNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-0.5*(zmin+zmax))));
+    
+    const Trk::TrackingVolume* bpVolNeg = new Trk::TrackingVolume(bpNeg, bpBounds->clone(),
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Negative"+name);
+
+    // geometry signature 
+    bpVolPos->sign(Trk::BeamPipe);
+    bpVolNeg->sign(Trk::BeamPipe);
+    
+    return std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> (bpVolPos,bpVolNeg); 
+
+  }
+
+  // cutout included
+
+  outerRadius = dim[0].first;
+  
+  // find rMax
+  for (unsigned int i=1; i<dim.size(); i++) if (dim[i].first > outerRadius) outerRadius = dim[i].first;
+  
+  // loop over z sections, prepare volumes for gluing
+  std::vector<const Trk::TrackingVolume*> posVols;
+  
+  for (unsigned int i=0; i<dim.size()-1; i++) {
+    
+    if (dim[i].second == dim[i+1].second) continue;
+    
+    // beam pipe volume 
+    Trk::CylinderVolumeBounds* bpBounds = new Trk::CylinderVolumeBounds( 0., dim[i].first,
+									 0.5*(dim[i+1].second - dim[i].second));
+    
+    Amg::Transform3D* bpPos = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(dim[i+1].second + dim[i].second))));
+    
+    const Trk::TrackingVolume* bpVolPos = new Trk::TrackingVolume(bpPos, bpBounds,
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Positive"+name);
+    bpVolPos->sign(Trk::BeamPipe);
+    
+    const Trk::TrackingVolume* bpVolGap = 0;
+    if ( dim[i].first < outerRadius ) {
+
+      Trk::CylinderVolumeBounds* bpGB = new Trk::CylinderVolumeBounds( dim[i].first, outerRadius,
+								       0.5*(dim[i+1].second - dim[i].second));
+
+      Amg::Transform3D* bpPB = new Amg::Transform3D(*bpPos);
+
+      bpVolGap = new Trk::TrackingVolume(bpPB, bpGB,
+					 *m_caloMaterial, 
+					 dummyLayers, dummyVolumes, 
+					 "Calo::GapVolumes::Positive"+name); 
+    }
+    
+    const Trk::TrackingVolume* bpSector = bpVolPos;
+    
+    if (bpVolGap) {
+      std::vector<const Trk::TrackingVolume*> gapVols;
+      gapVols.push_back(bpVolPos);
+      gapVols.push_back(bpVolGap); 
+      bpSector = m_trackingVolumeCreator->createContainerTrackingVolume(gapVols,
+									*m_caloMaterial,
+									"Calo::Container::PositiveBPSector"+name);
+    }   
+    posVols.push_back(bpSector);
+  }
+
+  //std::cout <<" processing complex beam pipe sector +: gluing in Z:"<< std::endl;
+  //for (unsigned int i=0; i<posVols.size(); i++) std::cout <<i<<","<<posVols[i]->volumeName()<<","<<posVols[i]->center().z()<< std::endl;
+  
+  const Trk::TrackingVolume* bpPosSector = m_trackingVolumeCreator->createContainerTrackingVolume(posVols,
+												  *m_caloMaterial,
+												  "Calo::Container::PositiveBP"+name);
+
+  //const Trk::CylinderVolumeBounds* testBounds 
+  //    = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(bpPosSector->volumeBounds()));
+  
+  //if (testBounds) std::cout <<"positive BP sector created at z="<<bpPosSector->center().z()<<" and halfZ="<< testBounds->halflengthZ()<< std::endl;
+
+
+  // loop over z sections, prepare volumes for gluing
+  std::vector<const Trk::TrackingVolume*> negVols;
+  
+  for (unsigned int i=0; i<dim.size()-1; i++) {
+    
+    float zmax2 = -1.* (dim[i].second);
+    float zmin2 = -1.* (dim[i+1].second);
+
+    if (zmin2 == zmax2) continue;
+    
+    // beam pipe volume 
+    Trk::CylinderVolumeBounds* bpBounds = new Trk::CylinderVolumeBounds( 0., dim[i].first,
+									 0.5*(zmax2-zmin2));
+    
+    Amg::Transform3D* bpNeg = new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,0.5*(zmin2+zmax2))));
+    
+    const Trk::TrackingVolume* bpVolNeg = new Trk::TrackingVolume(bpNeg, bpBounds,
+								  *m_caloMaterial, 
+								  dummyLayers, dummyVolumes, 
+								  "BeamPipe::Negative"+name);
+    bpVolNeg->sign(Trk::BeamPipe);
+    
+    const Trk::TrackingVolume* bpVolGap = dim[i].first < outerRadius ?
+      new Trk::TrackingVolume(new Amg::Transform3D(*bpNeg),
+			      new Trk::CylinderVolumeBounds( dim[i].first, outerRadius,
+							     0.5*(zmax2 - zmin2)),
+			      *m_caloMaterial, 
+			      dummyLayers, dummyVolumes, 
+			      "Calo::GapVolumes::Negative"+name)  : 0 ;
+    
+    const Trk::TrackingVolume* bpSector = bpVolNeg;
+    
+    if (bpVolGap) {
+      std::vector<const Trk::TrackingVolume*> gapVols;
+      gapVols.push_back(bpVolNeg);
+      gapVols.push_back(bpVolGap); 
+      bpSector = m_trackingVolumeCreator->createContainerTrackingVolume(gapVols,
+									*m_caloMaterial,
+									"Calo::Container::NegativeBPSector"+name);
+    }   
+
+    if (!negVols.size()) negVols.push_back(bpSector);
+    else negVols.insert(negVols.begin(),bpSector);
+  }
+  
+  //std::cout <<" processing complex beam pipe sector -: gluing in Z:"<< std::endl;
+  //for (unsigned int i=0; i<negVols.size(); i++) std::cout <<i<<","<<negVols[i]->volumeName()<<","<<negVols[i]->center().z()<< std::endl;
+
+  const Trk::TrackingVolume* bpNegSector = m_trackingVolumeCreator->createContainerTrackingVolume(negVols,
+												  *m_caloMaterial,
+												  "Calo::Container::NegativeBP"+name);
+  
+  //testBounds 
+  //    = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(bpNegSector->volumeBounds()));
+  
+  //if (testBounds) std::cout <<"negative BP sector created at z="<<bpNegSector->center().z()<<" and halfZ="<< testBounds->halflengthZ()<< std::endl;
+  
+  return std::pair<const Trk::TrackingVolume*,const Trk::TrackingVolume*> (bpPosSector,bpNegSector);
+
+}
+
+
+
diff --git a/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx b/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx
index b3f13e36bc0..ea238193ceb 100644
--- a/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx
+++ b/Calorimeter/CaloTrackingGeometry/src/components/CaloTrackingGeometry_entries.cxx
@@ -2,9 +2,12 @@
 #include "CaloTrackingGeometry/CaloSurfaceBuilder.h"
 #include "CaloTrackingGeometry/CaloSurfaceHelper.h"
 
+#include "CaloTrackingGeometry/CaloTrackingGeometryBuilderCond.h"
+
 using namespace Calo;
 
 DECLARE_COMPONENT( CaloTrackingGeometryBuilder )
 DECLARE_COMPONENT( CaloSurfaceBuilder )
 DECLARE_COMPONENT( CaloSurfaceHelper )
 
+DECLARE_COMPONENT( CaloTrackingGeometryBuilderCond )
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/BeamPipeBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/BeamPipeBuilderCond.h
new file mode 100755
index 00000000000..9f4dc6b7b77
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/BeamPipeBuilderCond.h
@@ -0,0 +1,119 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// BeamPipeBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_BEAMPIPEBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_BEAMPIPEBUILDERCOND_H
+
+// Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+// Trk
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+// STL
+#include <vector>
+#include <utility>
+
+namespace Trk {
+  class CylinderLayer;
+  class DiscLayer;
+  class PlaneLayer;
+}
+
+class BeamPipeDetectorManager;
+
+namespace InDet {
+
+  /** @class BeamPipeBuilderCond
+      Simple LayerBuilder for the BeamPipe, 
+      can be configured through jobOptions:
+        - radius
+        - halflength
+        - thickness
+        - MaterialProperties
+        
+      later on the slight shift/rotation of the BeamPipe can be implemented
+      - make a binding to the database afterwards
+       
+      @author Andreas.Salzburger@cern.ch 
+    */
+  class BeamPipeBuilderCond : public AthAlgTool,
+                          virtual public Trk::ILayerBuilderCond {
+    
+                            
+    public:
+      /** AlgTool style constructor */
+      BeamPipeBuilderCond(const std::string&,const std::string&,const IInterface*);
+      /** Destructor */
+      virtual ~BeamPipeBuilderCond();
+      
+      /** AlgTool initialize method */
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+       
+      /** LayerBuilder interface method - returning Barrel-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > cylindricalLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Endcap-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >     discLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Planar-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >    planarLayers(const EventContext& ctx) const; 
+
+      /** Name identification */
+      const std::string& identification() const;      
+          
+    private:
+      
+      bool                                          m_beamPipeFromDb;    //!< steer beam pipe parameters from DataBase
+      const BeamPipeDetectorManager*                m_beamPipeMgr;       //!< the beam pipe manager
+      std::string                                   m_beamPipeMgrName;   //!< the name of the beam pipe manager to be configured
+      double                                        m_beamPipeEnvelope;  //!< radial envelope when taking the Top volume radius
+      
+      double                                        m_beamPipeOffsetX;    //!< beam pipe offset in x
+      double                                        m_beamPipeOffsetY;    //!< beam pipe offset in y        
+      double                                        m_beamPipeRadius;     //!< radius of the beam pipe
+      double                                        m_beamPipeHalflength; //!< halflength of the beampipe
+      double                                        m_beamPipeThickness;  //!< thickness of the beam pipe
+      double                                        m_beamPipeX0;         //!< X0 of the beam pipe
+      double                                        m_beamPipeL0;         //!< X0 of the beam pipe
+      //double                                        m_beamPipedEdX;       //!< dEdX of the beam pipe
+      double                                        m_beamPipeA;          //!< averageA of the beam pipe
+      double                                        m_beamPipeZ;          //!< averageZ of the beam pipe
+      double                                        m_beamPipeRho;        //!< averageRho of the beam pipe
+
+      unsigned int                                  m_beamPipeBinsZ;      //!< number of bins in the beam pipe
+
+      std::string                                   m_identification;     //!< string identification
+      
+      
+  };
+
+ inline std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >  BeamPipeBuilderCond::discLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >(range,0); 
+  }
+ 
+ inline std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* > BeamPipeBuilderCond::planarLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >(range, 0);
+  }
+ 
+ inline const std::string& BeamPipeBuilderCond::identification() const
+ { return m_identification; } 
+ 
+  
+} // end of namespace
+
+
+#endif // INDETTRACKINGGEOMETRY_BEAMPIPEBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h
new file mode 100755
index 00000000000..e92774b734c
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h
@@ -0,0 +1,138 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// RobustTrackingGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_ROBUSTTRACKINGGEOMETRYBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_ROBUSTTRACKINGGEOMETRYBUILDERCOND_H
+
+//Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/BinningType.h"
+#include "TrkGeometry/TrackingVolumeManipulator.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+// STL
+#include <vector>
+#include <string>
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSamller(cSmallest, cBiggest, test); takeBigger(cSmallest, cBiggest,test)
+#endif
+
+
+namespace Trk {
+ class TrackingGeometry;
+ class ILayerBuilderCond;
+ class ITrackingVolumeCreator;
+ class ILayerArrayCreator;
+ class IMagneticFieldTool;
+ class Layer;
+ class Material;
+ class MagneticFieldProperties;
+}
+ 
+class IEnvelopeDefSvc; 
+ 
+namespace InDet {
+     
+
+  /** @class RobustTrackingGeometryBuilderCond
+
+      New Geometry builder that adapts to different layer setups
+      
+      Only a few parameters are not automated:
+       - m_outwardsFraction: this defines how much you orient yourself on the next bigger layer
+                             if you wrap an outer volume around an inner 0.5 would lead to a boundary fully in bewteen
+                            1. at the outer boundary, 0. at the inner boundary
+      
+      @author Andreas.Salzburger@cern.ch
+    
+    */
+    
+  class RobustTrackingGeometryBuilderCond : public AthAlgTool, 
+                                        public Trk::TrackingVolumeManipulator,
+                                        virtual public Trk::IGeometryBuilderCond {
+    
+    
+    public:
+      /** Constructor */
+      RobustTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~RobustTrackingGeometryBuilderCond();
+        
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      /** TrackingGeometry Interface methode */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::ID; }
+      
+    private:
+        
+      /** Private method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap layers */
+      const Trk::TrackingVolume* packVolumeTriple(const std::vector<const Trk::Layer*>& negLayers,
+                                                  const std::vector<const Trk::Layer*>& centralLayers,
+                                                  const std::vector<const Trk::Layer*>& posLayers,
+                                                  double rMin, double rMax,
+                                                  double zMin, double zPosCentral,
+                                                  const std::string& baseName="UndefinedVolume",
+                                                  int colorCode = 21,
+                                                  Trk::BinningType bintype=Trk::arbitrary) const;      
+      
+      /** Private method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap volumes */
+      const Trk::TrackingVolume* packVolumeTriple(const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                                  const std::string& baseName="UndefinedVolume") const;
+
+      // helper tools for the geometry building
+      ToolHandle<Trk::ILayerBuilderCond>             m_beamPipeBuilder;          //!< BeamPipe builder (is different from layers)
+      ToolHandleArray<Trk::ILayerBuilderCond>        m_layerBuilders;            //!< Helper Tools for the Layer creation   
+      ToolHandle<Trk::ITrackingVolumeCreator>        m_trackingVolumeCreator;    //!< Helper Tool to create TrackingVolumes
+      ToolHandle<Trk::ILayerArrayCreator>            m_layerArrayCreator;        //!< Helper Tool to create BinnedArrays
+
+      // configurations for the layer builders
+      std::vector<int>                               m_layerBinningType;         //!< binning type for the provided layers      
+      std::vector<int>                               m_colorCodesConfig;         //!< Color codes    
+
+      // enclosing endcap/cylinder layer 
+      ServiceHandle<IEnvelopeDefSvc>                 m_enclosingEnvelopeSvc;                //!< the service to provide the ID envelope size
+      std::vector<double>                            m_enclosingCylinderRadius;             //!< the cylinder layer inside the enclosing volume
+      std::vector<double>                            m_enclosingDiscPositionZ;              //!< the disc position inside the enclosing volume
+      
+      double                                         m_layerEnvelopeCover;       //!< innermost - outermost 
+      bool                                           m_buildBoundaryLayers;      //!< create boundary layers 
+      bool                                           m_replaceJointBoundaries;   //!< run with replacement of all joint boundaries 
+      
+      // magnetic & material field configuration
+      mutable Trk::Material*                         m_materialProperties;       //!< overal material properties of the ID
+      mutable Trk::MagneticFieldProperties*          m_magneticFieldProperties;  //!< overal mag field properties of the ID
+      // outer envelope        
+      double                                         m_outwardsFraction;         //!< defines how much you orient yourself in an outwards way (see above)                                    
+      // robust layer indexing                                                   
+      bool                                           m_indexStaticLayers;        //!< forces robust indexing for layers
+      // naming schema                                                           
+      std::string                                    m_namespace;                //!< identificaton namespace 
+      // ID container                                                            
+      std::string                                    m_exitVolume;                //!< the final ID container             
+      bool                                           m_isSLHC;                   //!< changes volume boundary calculation for SLHC layouts      
+  };
+
+} // end of namespace
+
+#endif //INDETTRACKINGGEOMETRY_ROBUSTTRACKINGGEOMETRYBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/SiLayerBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/SiLayerBuilderCond.h
new file mode 100755
index 00000000000..62869355d35
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/SiLayerBuilderCond.h
@@ -0,0 +1,162 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// SiLayerBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_SILAYERBUILDERNCOND_H
+#define INDETTRACKINGGEOMETRY_SILAYERBUILDERNCOND_H
+
+// Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+// STL
+#include <vector>
+#include <utility> //for std::pair
+
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+
+class PixelID;
+class SCT_ID;
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSmaller(cSmallest, test); takeBigger(cBiggest, test)
+#endif
+
+namespace InDetDD {
+  class SiDetectorManager;
+}
+
+namespace Trk {
+  class Surface;
+  class CylinderLayer;
+  class DiscLayer;
+  class PlaneLayer;
+  class LayerMaterialProperties;
+  typedef std::pair< SharedObject<const Surface>, Amg::Vector3D > SurfaceOrderPosition;
+}
+
+namespace InDet {
+ 
+  /** @class SiLayerBuilderCond
+  
+     The SiLayerBuilderCond parses the senstive detector elments and orders them onto a
+     Layer surface.
+  
+     It also uses the SiNumerology to construct the BinUtility and then orders the representing
+     detector surfaces on the layers.
+     
+     It performs an automated detector if an equidistant or non-equidistant binning
+     is to be used for the barrel case.
+     
+     There is an option to run in split mode for multiple pixel systems of different 
+     layer / endcap dimensions. In such a case, a cache is filled at the first time 
+     running for the pixel system of greater dimensions and just return in the second pass.
+
+     @author Andreas.Salzburger@cern.ch
+    */
+  class SiLayerBuilderCond : public AthAlgTool, virtual public Trk::ILayerBuilderCond {
+    
+    public:
+    
+      /** AlgTool style constructor */
+      SiLayerBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~SiLayerBuilderCond();
+      
+      /** AlgTool initialize method */
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+       
+      /** LayerBuilder interface method - returning Barrel-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > cylindricalLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Endcap-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >    discLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilder interface method - returning Planar-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >   planarLayers(const EventContext& ctx) const; 
+             
+      /** Name identification */
+      const std::string& identification() const;      
+        
+    private:
+      std::vector< const Trk::CylinderLayer* >* dressCylinderLayers(const std::vector< const Trk::CylinderLayer* >& dLayers) const;
+      
+      /** create the disc layers, if no vector is given, then it's the first pass, else it's the DBM for the Pixels */
+      std::pair<EventIDRange, std::vector< const Trk::DiscLayer* >* > createDiscLayers(const EventContext& ctx, std::vector<const Trk::DiscLayer* >* dLayers = nullptr) const;
+        
+      const Trk::LayerMaterialProperties* barrelLayerMaterial(double r, double hz) const;  //!< helper method to construct barrel material
+      const Trk::LayerMaterialProperties* endcapLayerMaterial(double rMin, double rMax) const; //!< helper method to construct endcap material
+        
+      void registerSurfacesToLayer(const std::vector<const Trk::Surface*>& surfaces, const Trk::Layer& layer) const; //!< layer association
+
+      bool                                           m_pixelCase;                      //!< flag for pixel/sct
+                                                     
+      const InDetDD::SiDetectorManager*              m_siMgr;                          //!< the Si Detector Manager
+      std::string                                    m_siMgrLocation;                  //!< the location of the Pixel Manager
+      const PixelID*                                 m_pixIdHelper;                    //!< pixel Id Helper 
+      const SCT_ID*                                  m_sctIdHelper;                    //!< sct Id Helper
+                                                     
+      bool                                           m_setLayerAssociation;            //!< Set Layer Association
+                                                     
+      // barrel layer section                        
+      std::vector<double>                            m_barrelAdditionalLayerR;         //!< Create an additional layer at these radii
+      std::vector<int>                               m_barrelAdditionalLayerType;      //!< material layer 1 - navigation layer 0 
+      size_t                                         m_barrelLayerBinsZ;               //!< Barrel bins for the material in z 
+      size_t                                         m_barrelLayerBinsPhi;             //!< Barrel bins for the material in phi
+      double                                         m_barrelEnvelope;                 //!< envelope around rMin/rMax
+      double                                         m_barrelEdbTolerance;             //!< tolerance in percent how much the bin sizes can change
+
+      bool                                           m_endcapRingLayout;               //!< will not synchronise the rMin/rMax
+      std::vector<double>                            m_endcapAdditionalLayerPosZ;      //!< Create additional endcaps at these z positions
+      std::vector<int>                               m_endcapAdditionalLayerType;      //!< material layer 1 - navigation layer 0 ( for volume adjustment )
+      size_t                                         m_endcapLayerBinsR;               //!< Barrel bins for the material in r
+      size_t                                         m_endcapLayerBinsPhi;             //!< Barrel bins for the material in phi
+      double                                         m_endcapEnvelope;                 //!< envelope around rMin/rMax
+      bool                                           m_endcapComplexRingBinning;       //!< make std::vector<R> rings, could be different for layers
+                                                     
+      std::string                                    m_identification;                  //!< string identification  
+      
+      int                                            m_splitMode;                       //!< Check for the split mode : -1 | 0 | 1 
+      double                                         m_splitTolerance;                  //!< difference in layer half length to provoke the split
+
+      static double                                  s_splitRadius;                     //!< Split radius for multiple pixel systems
+      static std::vector<const Trk::CylinderLayer*>  s_splitCylinderLayers;             //!< cached SLHC/split cylinder layers for projective layout
+      static std::vector<const Trk::DiscLayer*>      s_splitDiscLayers;                 //!< cached SLHC/split disc layers for projective layout
+      static EventIDRange                            s_splitIOVRange;                      //!< store range of splitLayers
+                                                     
+      bool                                           m_runGeometryValidation;           //!< run the validation of the geometry ( no empty bins)
+      SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_SCT_ReadKey{this, "SCT_ReadKey", "SCT_DetectorElementCollection", "Key of output SiDetectorElementCollection for SCT"};
+      SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_PixelReadKey{this, "PixelReadKey", "PixelDetectorElementCollection", "Key of output SiDetectorElementCollection for Pixel"};
+            
+                      
+  };
+
+ inline std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* > SiLayerBuilderCond::planarLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >(range, 0);
+  }
+ 
+ inline const std::string& SiLayerBuilderCond::identification() const
+ { return m_identification; }
+   
+} // end of namespace
+
+
+#endif // INDETTRACKINGGEOMETRY_SILAYERBUILDERNCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h
new file mode 100755
index 00000000000..7eeddeb3a88
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h
@@ -0,0 +1,255 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// StagedTrackingGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_STAGEDTRACKINGGEOMETRYBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_STAGEDTRACKINGGEOMETRYBUILDERCOND_H
+
+//Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/BinningType.h"
+#include "TrkGeometry/TrackingVolumeManipulator.h"
+//InDet
+#include "StagedTrackingGeometryBuilder.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+// STL
+#include <vector>
+#include <string>
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSmaller(cSmallest, test); takeBigger(cBiggest, test)
+#endif
+
+
+namespace Trk {
+ class TrackingGeometry;
+ class ILayerProviderCond;
+ class ITrackingVolumeCreator;
+ class ILayerArrayCreator;
+ class IMagneticFieldTool;
+ class Layer;
+ class Material;
+ class MagneticFieldProperties;
+}
+ 
+class IEnvelopeDefSvc; 
+ 
+namespace InDet {
+     
+  /** @struct LayerSetup 
+       - helps understanding how to pack the layers into a volume compound
+   */
+// implemented in StagedTrackingGeometrybuilder.h (without "Cond")  
+//  struct LayerSetup {
+//
+//    // the layer cache
+//    std::vector<const Trk::Layer*> negativeLayers;
+//    std::vector<const Trk::Layer*> centralLayers;
+//    std::vector<const Trk::Layer*> positiveLayers;
+//        
+//    // center information  
+//    double minRadiusCenter;
+//    double maxRadiusCenter;  
+//    double zExtendCenter;
+//    int    binningCenter;
+//    
+//    // endcap information
+//    bool buildEndcap;
+//    double minRadiusEndcap;
+//    double maxRadiusEndcap;  
+//    double minZextendEndcap;
+//    double maxZextendEndcap;
+//    int binningEndcap;
+//    
+//    // full setup information
+//    double zSector;
+//    double rMin;
+//    double rMax;
+//    double zMax;
+//    
+//    std::string identification;
+//    int         colorCode;
+//    
+//    LayerSetup(const std::string& idName,
+//               int cCode,
+//               const std::vector<const Trk::Layer*>& negLayers,
+//               const std::vector<const Trk::Layer*>& cenLayers,
+//               const std::vector<const Trk::Layer*>& posLayers,
+//               double minRc, double maxRc, double zC, int binC,
+//               bool bec=false, double minRe=0., double maxRe=0., double zMinE=0., double zMaxE=0., int binE = 0) :
+//      negativeLayers(negLayers),
+//      centralLayers(cenLayers),
+//      positiveLayers(posLayers),
+//      minRadiusCenter(minRc),
+//      maxRadiusCenter(maxRc),
+//      zExtendCenter(zC),
+//      binningCenter(binC),
+//      buildEndcap(bec),            
+//      minRadiusEndcap(minRe),   
+//      maxRadiusEndcap(maxRe),
+//      minZextendEndcap(zMinE),
+//      maxZextendEndcap(zMaxE),
+//      binningEndcap(binE),
+//      identification(idName),
+//      colorCode(cCode)
+//    {
+//        rMin     = minRadiusCenter < minRadiusEndcap ? minRadiusCenter : minRadiusEndcap;
+//        rMax     = maxRadiusCenter > maxRadiusEndcap ? maxRadiusCenter : maxRadiusEndcap;
+//        zMax     = zExtendCenter > maxZextendEndcap ? zExtendCenter : maxZextendEndcap;
+//        zSector  = buildEndcap ? 0.5*(zExtendCenter+minZextendEndcap) : zExtendCenter;
+//        
+//    }
+//             
+//  };
+
+
+  /** @class StagedTrackingGeometryBuilderCond
+
+      New Geometry builder that adapts to different layer setups
+      
+      Only a few parameters are not automated:
+       - m_outwardsFraction: this defines how much you orient yourself on the next bigger layer
+                             if you wrap an outer volume around an inner 0.5 would lead to a boundary fully in bewteen
+                            1. at the outer boundary, 0. at the inner boundary
+      
+      @author Andreas.Salzburger@cern.ch
+    
+    */
+    
+  class StagedTrackingGeometryBuilderCond : public AthAlgTool, 
+                                        public Trk::TrackingVolumeManipulator,
+                                        virtual public Trk::IGeometryBuilderCond {
+    
+    
+    public:
+      /** Constructor */
+      StagedTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      
+      /** Destructor */
+      virtual ~StagedTrackingGeometryBuilderCond();
+        
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      /** TrackingGeometry Interface methode */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::ID; }
+      
+    private:
+      /** Private helper method, estimates the overal dimensions */
+      LayerSetup estimateLayerSetup(const std::string& idName, size_t ils,
+                                    const std::vector<const Trk::Layer*>& negLayers,
+                                    const std::vector<const Trk::Layer*>& centralLayers,
+                                    const std::vector<const Trk::Layer*>& posLayers,
+                                    double maxR, double maxZ) const;
+                                    
+      /** Private helper method to estimate the layer dimensions */
+      void estimateLayerDimensions(const std::vector<const Trk::Layer*>& layers,
+                                   double& rMin, double& rMax, double& zMin, double& zMax) const;
+                                   
+      /** Private helper method to check if a sector is compatible with the cache */
+      bool setupFitsCache(LayerSetup& layerSetup, std::vector<InDet::LayerSetup>& layerSetupCache) const;
+                                   
+                                   
+      /** Private helper method to flush the cache into the id volumes - return volume is the one to be provided */
+      const Trk::TrackingVolume* createFlushVolume(std::vector<InDet::LayerSetup>& layerSetupCache,
+                                                   double innerRadius, double& outerRadius, double extendZ) const;                                                         
+        
+      /** Private helper method, creates a TrackingVolume - and checks if configured - for Ring Layout 
+            - in case a ring layout is given, it creates the corresponding sub-volumes and updates the radius                                       
+            */
+      const Trk::TrackingVolume* createTrackingVolume(const std::vector<const Trk::Layer*>& layers, 
+                                                      double innerRadius, double& outerRadius,
+                                                      double zMin, double zMax,
+                                                      const std::string& volumeName,
+                                                      Trk::BinningType btype,
+						      bool doAdjustOuterRadius = true) const;                                                  
+        
+      /** Private helper method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap layers
+          - in case of a ring layout the subvolumes are created and the rMax is adapted                                             
+         */
+      const Trk::TrackingVolume* packVolumeTriple(const LayerSetup& layerSetup,
+                                                  double rMin, double& rMax,
+                                                  double zMin, double zPosCentral) const;      
+      
+      /** Private helper method, creates and packs a triple containing of NegEndcap-Barrel-PosEndcap volumes */
+      const Trk::TrackingVolume* packVolumeTriple(const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                                  const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                                  const std::string& baseName="UndefinedVolume") const;
+                                                  
+      /** Private helper method for detection of Ring layout */
+      bool ringLayout(const std::vector<const Trk::Layer*>& layers, std::vector<double>& rmins, std::vector<double>& rmaxs) const;                                              
+
+      /** helper method needed for the Ring layout */
+      void checkForInsert(std::vector<double>& radii, double radius) const;
+
+      // helper tools for the geometry building
+      ToolHandleArray<Trk::ILayerProviderCond>           m_layerProviders;          //!< Helper Tools for the Layer creation, includes beam pipe builder   
+      ToolHandle<Trk::ITrackingVolumeCreator>        m_trackingVolumeCreator;   //!< Helper Tool to create TrackingVolumes
+      ToolHandle<Trk::ILayerArrayCreator>            m_layerArrayCreator;       //!< Helper Tool to create BinnedArrays
+
+      // configurations for the layer builders
+      std::vector<int>                               m_layerBinningTypeCenter;  //!< binning type for the provided layers      
+      std::vector<int>                               m_layerBinningTypeEndcap;  //!< binning type for the provided layers      
+      std::vector<int>                               m_colorCodesConfig;        //!< Color codes    
+
+      // enclosing endcap/cylinder layer 
+      ServiceHandle<IEnvelopeDefSvc>                 m_enclosingEnvelopeSvc;     //!< the service to provide the ID envelope size
+      std::vector<double>                            m_enclosingCylinderRadius;  //!< the cylinder layer inside the enclosing volume
+      std::vector<double>                            m_enclosingDiscPositionZ;   //!< the disc position inside the enclosing volume
+      
+      double                                         m_layerEnvelopeCover;       //!< innermost - outermost 
+      bool                                           m_buildBoundaryLayers;      //!< create boundary layers 
+      bool                                           m_replaceJointBoundaries;   //!< run with replacement of all joint boundaries 
+      
+      // magnetic & material field configuration
+      mutable Trk::Material*                         m_materialProperties;       //!< overal material properties of the ID
+      mutable Trk::MagneticFieldProperties*          m_magneticFieldProperties;  //!< overal mag field properties of the ID
+                    
+      // robust layer indexing                                                   
+      bool                                           m_indexStaticLayers;        //!< forces robust indexing for layers
+      
+      // check for endcap ring layout
+      bool                                           m_checkForRingLayout;        //!< this is to check for the endcap ring layout
+      double                                         m_ringTolerance;            //!< the ring tolerance 
+      
+      // naming schema                                                           
+      std::string                                    m_namespace;                //!< identificaton namespace 
+      // ID container                                                            
+      std::string                                    m_exitVolume;                //!< the final ID container             
+  };
+
+  inline void StagedTrackingGeometryBuilderCond::checkForInsert(std::vector<double>& radii, double radius) const {
+      bool exists = false;
+      // loop and check
+      for (auto& checkr : radii) {
+          if ( (checkr-radius)*(checkr-radius) < m_ringTolerance*m_ringTolerance ){
+              exists = true; break;
+          }
+      }
+      // insert 
+      if (!exists) radii.push_back(radius);
+      // re-sort
+      std::sort(radii.begin(),radii.end());   
+  }
+
+
+} // end of namespace
+
+#endif //INDETTRACKINGGEOMETRY_STAGEDTRACKINGGEOMETRYBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/TRT_LayerBuilderCond.h b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/TRT_LayerBuilderCond.h
new file mode 100755
index 00000000000..19a6395a072
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/InDetTrackingGeometry/TRT_LayerBuilderCond.h
@@ -0,0 +1,117 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// TRT_LayerBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef INDETTRACKINGGEOMETRY_TRT_LAYERBUILDERCOND_H
+#define INDETTRACKINGGEOMETRY_TRT_LAYERBUILDERCOND_H
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+// Trk
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+// STL
+#include <vector>
+
+#ifndef TRKDETDESCR_TAKESMALLERBIGGER
+#define TRKDETDESCR_TAKESMALLERBIGGER
+#define takeSmaller(current,test) current = current < test ? current : test
+#define takeBigger(current,test)  current = current > test ? current : test
+#define takeSmallerBigger(cSmallest, cBiggest, test) takeSmaller(cSmallest, test); takeBigger(cBiggest, test)
+#endif
+
+namespace InDetDD {
+  class TRT_DetectorManager;
+}
+
+namespace Trk {
+  class Surface;
+  class Layer;
+  class CylinderLayer;
+  class DiscLayer;
+  class ExtendedMaterialProperties;
+  typedef std::pair< SharedObject<const Surface>, Amg::Vector3D > SurfaceOrderPosition;
+}
+
+namespace InDet {
+ 
+  /** @class TRT_LayerBuilderCond
+     
+     @author Andreas.Salzburger@cern.ch
+    */
+  class TRT_LayerBuilderCond : public AthAlgTool,
+                           virtual public Trk::ILayerBuilderCond {
+    
+    /** Declare the TRT_VolumeBuilder as friend */
+    friend class TRT_VolumeBuilder;
+    
+    public:
+    
+      /** AlgTool style constructor */
+      TRT_LayerBuilderCond(const std::string&,const std::string&,const IInterface*);
+      /** Destructor */
+      virtual ~TRT_LayerBuilderCond();
+      
+      /** AlgTool initialize method */
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+       
+      /** LayerBuilderCond interface method - returning Barrel-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > cylindricalLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilderCond interface method - returning Endcap-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* >     discLayers(const EventContext& ctx) const; 
+      
+      /** LayerBuilderCond interface method - returning Planar-like layers */
+      std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >    planarLayers(const EventContext& ctx) const; 
+            
+      /** Name identification */
+      const std::string& identification() const;      
+      
+    private:
+      const InDetDD::TRT_DetectorManager*           m_trtMgr;                   //!< the TRT Manager
+      std::string                                   m_trtMgrLocation;           //!< the location of the TRT Manager     
+                   
+      double                                        m_layerStrawRadius;         //!< straw radius                                                                            
+      double                                        m_layerThickness;           //!< modelled layer thickness
+      bool                                          m_modelGeometry;            //!< Build the geometry with model layers      
+      unsigned int                                  m_modelBarrelLayers;        //!< model barrel layers with material
+      unsigned int                                  m_modelEndcapLayers;        //!< model endcap layers with material
+                                                                                
+      unsigned int                                  m_barrelLayerBinsZ;         //!< Bins for the Barrel material - in z
+      unsigned int                                  m_barrelLayerBinsPhi;       //!< Bins for the Barrel material - in phi
+      unsigned int                                  m_endcapLayerBinsR;         //!< Bins for the Endcap material - in r
+      unsigned int                                  m_endcapLayerBinsPhi;       //!< Bins for the Endcap material - in phi
+      bool                                          m_endcapConly;              //!< Only build the endcapC
+                                                                                
+      bool                                          m_registerStraws;           //!< register the straws
+      int                                           m_barrelSectorAtPiBoundary; //!< this is the barrel Sector where +pi/-pi is within
+      
+      std::string                                   m_identification;           //!< string identification                        
+      
+      
+  };
+
+ inline std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* > TRT_LayerBuilderCond::planarLayers(const EventContext&) const
+  {
+  //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector< const Trk::PlaneLayer* >* >(range, 0);
+  }
+ 
+ inline const std::string& TRT_LayerBuilderCond::identification() const
+ { return m_identification; }
+   
+} // end of namespace
+
+
+#endif // INDETTRACKINGGEOMETRY_TRT_LAYERBUILDERCOND_H
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilderCond.py b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilderCond.py
new file mode 100644
index 00000000000..f592e04e99d
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilderCond.py
@@ -0,0 +1,201 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+######################################################
+# ConfiguredInDetTrackingGeometry module
+#
+# it inherits from RobustTrackingGeometryBuilderConf and performs 
+# standard configuration
+#
+######################################################
+
+# import the Extrapolator configurable
+from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__RobustTrackingGeometryBuilderCond
+from AthenaCommon.DetFlags import DetFlags
+
+# define the class
+class ConfiguredInDetTrackingGeometryBuilderCond( InDet__RobustTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'InDetTrackingGeometryBuilderCond',
+                      namePrefix = '',
+                      setLayerAssociation = True,
+                      buildTrtStrawLayers = False):
+
+        # get the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc, ServiceMgr           
+       
+        # the Detector flags to be imported
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+        
+        # beampipe        
+        from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__BeamPipeBuilderCond
+        BeamPipeBuilder = InDet__BeamPipeBuilderCond(name=namePrefix+'BeamPipeBuilderCond')
+        BeamPipeBuilder.BeamPipeRadius 	        = TrkDetFlags.BeamPipeRadius()
+        BeamPipeBuilder.BeamPipeThickness       = TrkDetFlags.BeamPipeThickness() 
+        BeamPipeBuilder.BeamPipeMaterialBinsZ   = TrkDetFlags.BeamPipeLayerMaterialBinsZ()
+        BeamPipeBuilder.OutputLevel             = TrkDetFlags.InDetBuildingOutputLevel()
+        ToolSvc += BeamPipeBuilder
+                
+        # the layer builders
+        layerbuilders = []
+        binnings      = []
+        colors        = []
+                        
+        # @TODO put DetFlags isOn here, but make sure that this is really when the detector is not built        
+        
+        # PIXEL building
+        if DetFlags.pixel_on():
+          from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__SiLayerBuilderCond
+          PixelLayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'PixelLayerBuilderCond')
+          PixelLayerBuilder.PixelCase 	       = True
+          PixelLayerBuilder.Identification       = 'Pixel'
+          PixelLayerBuilder.SiDetManagerLocation = 'Pixel'
+          # additionall layers - handle with care !
+          PixelLayerBuilder.BarrelAdditionalLayerRadii      = [ 130 ]   # The PST
+          PixelLayerBuilder.BarrelAdditionalLayerType       = [ 0 ]     # -- will shift volume boundary to PST
+          PixelLayerBuilder.EndcapAdditionalLayerPositionsZ = [ -1900. , 1900. ] # DBM
+          PixelLayerBuilder.EndcapAdditionalLayerType       = [  1 , 1 ] # DBM
+          # Pixel barrel specifications
+          PixelLayerBuilder.BarrelLayerBinsZ     = TrkDetFlags.PixelBarrelLayerMaterialBinsZ()
+          PixelLayerBuilder.BarrelLayerBinsPhi   = TrkDetFlags.PixelBarrelLayerMaterialBinsPhi()
+          PixelLayerBuilder.EndcapLayerBinsR     = TrkDetFlags.PixelEndcapLayerMaterialBinsR()
+          PixelLayerBuilder.EndcapLayerBinsPhi   = TrkDetFlags.PixelEndcapLayerMaterialBinsPhi()
+          
+          # set the layer association
+          PixelLayerBuilder.SetLayerAssociation  = setLayerAssociation
+          # output level
+          PixelLayerBuilder.OutputLevel         = TrkDetFlags.PixelBuildingOutputLevel()
+          # the binning type of the layers   
+          PixelLayerBinning = 2
+          # add it to tool service
+          ToolSvc += PixelLayerBuilder
+          # put them to the caches
+          layerbuilders += [ PixelLayerBuilder ]
+          binnings      += [ PixelLayerBinning ]
+          colors        += [ 3 ]
+       
+        if DetFlags.SCT_on():
+          # SCT building
+          from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__SiLayerBuilderCond
+          SCT_LayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'SCT_LayerBuilderCond')
+          SCT_LayerBuilder.PixelCase                       = False
+          SCT_LayerBuilder.Identification                  = 'SCT'
+          SCT_LayerBuilder.SiDetManagerLocation            = 'SCT'
+          # additionall layers - handle with care !
+          SCT_LayerBuilder.EndcapAdditionalLayerPositionsZ = [ -2850 , 2850 ] 
+          SCT_LayerBuilder.EndcapAdditionalLayerType       = [  0 , 0 ] 
+          # SCT barrel specifications
+          SCT_LayerBuilder.BarrelLayerBinsZ                = TrkDetFlags.SCT_BarrelLayerMaterialBinsZ()
+          SCT_LayerBuilder.BarrelLayerBinsPhi              = TrkDetFlags.SCT_BarrelLayerMaterialBinsPhi()
+          # SCT endcap specifications                          
+          SCT_LayerBuilder.EndcapLayerBinsR                = TrkDetFlags.SCT_EndcapLayerMaterialBinsR()
+          SCT_LayerBuilder.EndcapLayerBinsPhi              = TrkDetFlags.SCT_EndcapLayerMaterialBinsPhi()
+          SCT_LayerBuilder.EndcapComplexRingBinning        = TrkDetFlags.SCT_EndcapLayerDynamicRings()
+          # set the layer association                   
+          SCT_LayerBuilder.SetLayerAssociation             = setLayerAssociation        
+          # output level                                 
+          SCT_LayerBuilder.OutputLevel                     = TrkDetFlags.SCT_BuildingOutputLevel()
+          # the binning type of the layer     
+          SCT_LayerBinning = 2
+          # SCT -> ToolSvc                             
+          ToolSvc += SCT_LayerBuilder                       
+          # put them to the caches
+          layerbuilders += [ SCT_LayerBuilder ]
+          binnings      += [ SCT_LayerBinning ]
+          colors        += [ 4 ]
+        
+        if DetFlags.TRT_on():                                                      
+          from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__TRT_LayerBuilderCond
+          TRT_LayerBuilder = InDet__TRT_LayerBuilderCond(name=namePrefix+'TRT_LayerBuilderCond')
+          # TRT barrel specifications
+          TRT_LayerBuilder.ModelBarrelLayers  = TrkDetFlags.TRT_BarrelModelLayers()
+          TRT_LayerBuilder.BarrelLayerBinsZ   = TrkDetFlags.TRT_BarrelLayerMaterialBinsZ()
+          TRT_LayerBuilder.BarrelLayerBinsPhi = TrkDetFlags.TRT_BarrelLayerMaterialBinsPhi()
+          # SCT endcap specifications                     
+          TRT_LayerBuilder.ModelEndcapLayers  = TrkDetFlags.TRT_EndcapModelLayers()
+          TRT_LayerBuilder.EndcapLayerBinsR   = TrkDetFlags.TRT_EndcapLayerMaterialBinsR()
+          TRT_LayerBuilder.EndcapLayerBinsPhi = TrkDetFlags.TRT_EndcapLayerMaterialBinsPhi()                
+          # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
+          TRT_LayerBinning = 1        
+          if buildTrtStrawLayers or TrkDetFlags.TRT_BuildStrawLayers() :
+             TRT_LayerBinning = 2
+             TRT_LayerBuilder.ModelLayersOnly = False
+          # output level
+          TRT_LayerBuilder.OutputLevel        = TrkDetFlags.TRT_BuildingOutputLevel()
+          # TRT -> ToolSvc                      
+          ToolSvc += TRT_LayerBuilder
+          # put them to the caches
+          layerbuilders += [ TRT_LayerBuilder ]
+          binnings      += [ TRT_LayerBinning ]
+          colors        += [ 5 ]
+        
+        
+        # helpers for the InDetTrackingGeometry Builder : layer array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerArrayCreator
+        InDetLayerArrayCreator = Trk__LayerArrayCreator(name = 'InDetLayerArrayCreator')
+        InDetLayerArrayCreator.EmptyLayerMode           = 2 # deletes empty material layers from arrays
+        InDetLayerArrayCreator.OutputLevel              = TrkDetFlags.InDetBuildingOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetLayerArrayCreator
+
+        # helpers for the InDetTrackingGeometry Builder : volume array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeArrayCreator
+        InDetTrackingVolumeArrayCreator                       = Trk__TrackingVolumeArrayCreator(name = 'InDetTrackingVolumeArrayCreator')
+        InDetTrackingVolumeArrayCreator.OutputLevel           = TrkDetFlags.InDetBuildingOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeArrayCreator
+        
+        # helpers for the InDetTrackingGeometry Builder : tracking voluem helper for glueing
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeHelper
+        InDetTrackingVolumeHelper                             = Trk__TrackingVolumeHelper(name ='InDetTrackingVolumeHelper')
+        InDetTrackingVolumeHelper.OutputLevel                 = TrkDetFlags.InDetBuildingOutputLevel()
+        # the material bins 
+        InDetTrackingVolumeHelper.BarrelLayerBinsZ            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.BarrelLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        InDetTrackingVolumeHelper.EndcapLayerBinsR            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.EndcapLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeHelper
+        
+        # helpers for the InDetTrackingGeometry Builder : cylinder volume creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__CylinderVolumeCreator
+        InDetCylinderVolumeCreator = Trk__CylinderVolumeCreator(name = 'InDetCylinderVolumeCreator')
+        # give him the layer array creator
+        InDetCylinderVolumeCreator.LayerArrayCreator          = InDetLayerArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeArrayCreator = InDetTrackingVolumeArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeHelper       = InDetTrackingVolumeHelper
+        # specifiy the binning, passive layers, entry layers
+        InDetCylinderVolumeCreator.PassiveLayerThickness      = TrkDetFlags.InDetPassiveLayerThickness()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsPhi        = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsRZ         = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()  
+        # output level                                       
+        InDetCylinderVolumeCreator.OutputLevel                = TrkDetFlags.InDetBuildingOutputLevel()        
+        # add to ToolSvc
+        ToolSvc += InDetCylinderVolumeCreator        
+        
+        # the envelope definition service
+        from SubDetectorEnvelopes.SubDetectorEnvelopesConf import DetDescrDBEnvelopeSvc
+        AtlasEnvelopeSvc = DetDescrDBEnvelopeSvc('AtlasEnvelopeSvcDefinitionSvc')
+        # set the output level for the Envelope service
+        AtlasEnvelopeSvc.OutputLevel      = TrkDetFlags.InDetBuildingOutputLevel()  
+        # add to SvcMgr
+        ServiceMgr += AtlasEnvelopeSvc
+        
+        # the tracking geometry builder
+        InDet__RobustTrackingGeometryBuilderCond.__init__(self,namePrefix+name,\
+                                                      BeamPipeBuilder   = BeamPipeBuilder,\
+                                                      LayerBuilders     = layerbuilders,
+                                                      LayerBinningType  = binnings,
+                                                      ColorCodes        = colors,
+                                                      BarrelEntryLayers = [ 2, 2, 2 ],
+                                                      EndcapEntryLayers = [ 1, 0, 1 ],
+                                                      EnvelopeDefinitionSvc = AtlasEnvelopeSvc,
+                                                      VolumeEnclosureDiscPositions = [ 3000., 3450. ],
+                                                      TrackingVolumeCreator     = InDetCylinderVolumeCreator,
+                                                      LayerArrayCreator         = InDetLayerArrayCreator,
+                                                      BuildBoundaryLayers       = TrkDetFlags.InDetBuildMaterialBoundaries(),
+                                                      ReplaceAllJointBoundaries = TrkDetFlags.InDetBuildJointBoundaries(),
+                                                      OutputLevel               = TrkDetFlags.InDetBuildingOutputLevel(),
+                                                      ExitVolumeName            = TrkDetFlags.InDetContainerName(),
+                                                      MagneticFieldMode         = TrkDetFlags.MagneticFieldMode())
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredStagedTrackingGeometryBuilderCond.py b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredStagedTrackingGeometryBuilderCond.py
new file mode 100644
index 00000000000..07abdcbba39
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredStagedTrackingGeometryBuilderCond.py
@@ -0,0 +1,223 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+######################################################
+# ConfiguredStagedTrackingGeometry module
+#
+# it inherits from RobustTrackingGeometryBuilderConf and performs 
+# standard configuration
+#
+######################################################
+
+# import the Extrapolator configurable
+from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__StagedTrackingGeometryBuilderCond
+
+# define the class
+class ConfiguredStagedTrackingGeometryBuilderCond( InDet__StagedTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'InDetTrackingGeometryBuilderCond',
+                      namePrefix = '',
+                      setLayerAssociation = True,
+                      buildTrtStrawLayers = False):
+
+        # get the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc, ServiceMgr
+        from AthenaCommon.DetFlags import DetFlags
+       
+        # the Detector flags to be imported
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+        
+        # beampipe
+        from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__BeamPipeBuilderCond
+        BeamPipeBuilder = InDet__BeamPipeBuilderCond(name=namePrefix+'BeamPipeBuilderCond')
+        BeamPipeBuilder.BeamPipeRadius 	        = TrkDetFlags.BeamPipeRadius()
+        BeamPipeBuilder.BeamPipeThickness       = TrkDetFlags.BeamPipeThickness() 
+        BeamPipeBuilder.BeamPipeMaterialBinsZ   = TrkDetFlags.BeamPipeLayerMaterialBinsZ()
+        BeamPipeBuilder.OutputLevel             = TrkDetFlags.BeamPipeBuildingOutputLevel()
+        ToolSvc += BeamPipeBuilder
+
+        # the layer providers
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerProviderCond
+        BeamPipeProvider = Trk__LayerProviderCond(name=namePrefix+'BeamPipeProviderCond')
+        BeamPipeProvider.LayerBuilder = BeamPipeBuilder
+        ToolSvc += BeamPipeProvider
+
+        # binning of the beam pipe
+        BeamPipeBinning = 2
+                
+        # the layer builders
+        layerProviders  = [ BeamPipeProvider ]
+        binningsCenter  = [ BeamPipeBinning ]
+        binningsEndcap  = [ BeamPipeBinning ]
+        colors          = [ 2 ]
+                                
+        # PIXEL building
+        if DetFlags.pixel_on() :
+            from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__SiLayerBuilderCond
+            PixelLayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'PixelLayerBuilderCond')
+            PixelLayerBuilder.PixelCase 	       = True
+            PixelLayerBuilder.Identification       = 'Pixel'
+            PixelLayerBuilder.SiDetManagerLocation = 'Pixel'
+            # Pixel barrel specifications
+            PixelLayerBuilder.BarrelLayerBinsZ     = TrkDetFlags.PixelBarrelLayerMaterialBinsZ()
+            PixelLayerBuilder.BarrelLayerBinsPhi   = TrkDetFlags.PixelBarrelLayerMaterialBinsPhi()
+            PixelLayerBuilder.EndcapLayerBinsR     = TrkDetFlags.PixelEndcapLayerMaterialBinsR()
+            PixelLayerBuilder.EndcapLayerBinsPhi   = TrkDetFlags.PixelEndcapLayerMaterialBinsPhi()
+            PixelLayerBuilder.EndcapRingLayout     = TrkDetFlags.PixelRingLayout()
+            # set the layer association
+            PixelLayerBuilder.SetLayerAssociation  = setLayerAssociation
+            # output level
+            PixelLayerBuilder.OutputLevel         = TrkDetFlags.PixelBuildingOutputLevel()
+            # the binning type of the layers   
+            PixelLayerBinning = 2
+            # add it to tool service
+            ToolSvc += PixelLayerBuilder
+            
+            # the layer providers
+            PixelLayerProvider = Trk__LayerProviderCond(name=namePrefix+'PixelLayerProviderCond')
+            PixelLayerProvider.LayerBuilder = PixelLayerBuilder
+            ToolSvc += PixelLayerProvider
+            layerProviders  += [ PixelLayerProvider ]
+            binningsCenter  += [ PixelLayerBinning ]
+            binningsEndcap  += [ PixelLayerBinning ]
+            colors          += [ 3 ]
+        
+        # SCT building
+        if DetFlags.SCT_on() :
+            SCT_LayerBuilder = InDet__SiLayerBuilderCond(name=namePrefix+'SCT_LayerBuilderCond')
+            SCT_LayerBuilder.PixelCase                       = False
+            SCT_LayerBuilder.Identification                  = 'SCT'
+            SCT_LayerBuilder.SiDetManagerLocation            = 'SCT'
+            # additionall layers - handle with care !
+            SCT_LayerBuilder.EndcapAdditionalLayerPositionsZ = [ -2850 , 2850 ] 
+            SCT_LayerBuilder.EndcapAdditionalLayerType       = [  0 , 0 ] 
+            # SCT barrel specifications
+            SCT_LayerBuilder.BarrelLayerBinsZ                = TrkDetFlags.SCT_BarrelLayerMaterialBinsZ()
+            SCT_LayerBuilder.BarrelLayerBinsPhi              = TrkDetFlags.SCT_BarrelLayerMaterialBinsPhi()
+            # SCT endcap specifications                          
+            SCT_LayerBuilder.EndcapLayerBinsR                = TrkDetFlags.SCT_EndcapLayerMaterialBinsR()
+            SCT_LayerBuilder.EndcapLayerBinsPhi              = TrkDetFlags.SCT_EndcapLayerMaterialBinsPhi()
+            SCT_LayerBuilder.EndcapComplexRingBinning        = TrkDetFlags.SCT_EndcapLayerDynamicRings()
+            # set the layer association                   
+            SCT_LayerBuilder.SetLayerAssociation             = setLayerAssociation        
+            # output level                                 
+            SCT_LayerBuilder.OutputLevel                     = TrkDetFlags.SCT_BuildingOutputLevel()
+            # the binning type of the layer     
+            SCT_LayerBinning = 2
+            # SCT -> ToolSvc                             
+            ToolSvc += SCT_LayerBuilder     
+            
+            # the layer providers
+            SCT_LayerProvider = Trk__LayerProviderCond(name=namePrefix+'SCT_LayerProviderCond')
+            SCT_LayerProvider.LayerBuilder = SCT_LayerBuilder
+            ToolSvc += SCT_LayerProvider
+                              
+            # put them to the caches
+            layerProviders  += [ SCT_LayerProvider ]
+            binningsCenter  += [ SCT_LayerBinning ]
+            binningsEndcap  += [ SCT_LayerBinning ]
+            colors          += [ 4 ]
+
+        # TRT building
+        if DetFlags.TRT_on() :
+            from InDetTrackingGeometry.InDetTrackingGeometryConf import InDet__TRT_LayerBuilderCond
+            TRT_LayerBuilder = InDet__TRT_LayerBuilderCond(name=namePrefix+'TRT_LayerBuilderCond')
+            # TRT barrel specifications
+            TRT_LayerBuilder.ModelBarrelLayers  = TrkDetFlags.TRT_BarrelModelLayers()
+            TRT_LayerBuilder.BarrelLayerBinsZ   = TrkDetFlags.TRT_BarrelLayerMaterialBinsZ()
+            TRT_LayerBuilder.BarrelLayerBinsPhi = TrkDetFlags.TRT_BarrelLayerMaterialBinsPhi()
+            # SCT endcap specifications                     
+            TRT_LayerBuilder.ModelEndcapLayers  = TrkDetFlags.TRT_EndcapModelLayers()
+            TRT_LayerBuilder.EndcapLayerBinsR   = TrkDetFlags.TRT_EndcapLayerMaterialBinsR()
+            TRT_LayerBuilder.EndcapLayerBinsPhi = TrkDetFlags.TRT_EndcapLayerMaterialBinsPhi()                
+            # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
+            TRT_LayerBinning = 1        
+            if buildTrtStrawLayers or TrkDetFlags.TRT_BuildStrawLayers() :
+               TRT_LayerBinning = 2
+               TRT_LayerBuilder.ModelLayersOnly = False
+            # output level
+            TRT_LayerBuilder.OutputLevel        = TrkDetFlags.TRT_BuildingOutputLevel()
+            # TRT -> ToolSvc
+            ToolSvc += TRT_LayerBuilder
+            
+            
+            # the layer providers
+            TRT_LayerProvider = Trk__LayerProviderCond(name=namePrefix+'TRT_LayerProviderCond')
+            TRT_LayerProvider.LayerBuilder = TRT_LayerBuilder
+            ToolSvc += TRT_LayerProvider
+                              
+            # put them to the caches
+            layerProviders  += [ TRT_LayerProvider ]
+            binningsCenter  += [ TRT_LayerBinning ]
+            binningsEndcap  += [ TRT_LayerBinning ]
+            colors          += [ 5 ]
+        
+        
+        # helpers for the InDetTrackingGeometry Builder : layer array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerArrayCreator
+        InDetLayerArrayCreator = Trk__LayerArrayCreator(name = 'InDetLayerArrayCreator')
+        InDetLayerArrayCreator.EmptyLayerMode           = 2 # deletes empty material layers from arrays
+        InDetLayerArrayCreator.OutputLevel              = TrkDetFlags.InDetBuildingHelperOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetLayerArrayCreator
+
+        # helpers for the InDetTrackingGeometry Builder : volume array creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeArrayCreator
+        InDetTrackingVolumeArrayCreator                       = Trk__TrackingVolumeArrayCreator(name = 'InDetTrackingVolumeArrayCreator')
+        InDetTrackingVolumeArrayCreator.OutputLevel           = TrkDetFlags.InDetBuildingOutputLevel()
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeArrayCreator
+        
+        # helpers for the InDetTrackingGeometry Builder : tracking voluem helper for glueing
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeHelper
+        InDetTrackingVolumeHelper                             = Trk__TrackingVolumeHelper(name ='InDetTrackingVolumeHelper')
+        InDetTrackingVolumeHelper.OutputLevel                 = TrkDetFlags.InDetBuildingHelperOutputLevel()
+        # the material bins 
+        InDetTrackingVolumeHelper.BarrelLayerBinsZ            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.BarrelLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        InDetTrackingVolumeHelper.EndcapLayerBinsR            = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()
+        InDetTrackingVolumeHelper.EndcapLayerBinsPhi          = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi() 
+        # add to ToolSvc
+        ToolSvc += InDetTrackingVolumeHelper
+        
+        # helpers for the InDetTrackingGeometry Builder : cylinder volume creator
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__CylinderVolumeCreator
+        InDetCylinderVolumeCreator = Trk__CylinderVolumeCreator(name = 'InDetCylinderVolumeCreator')
+        # give him the layer array creator
+        InDetCylinderVolumeCreator.LayerArrayCreator          = InDetLayerArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeArrayCreator = InDetTrackingVolumeArrayCreator
+        InDetCylinderVolumeCreator.TrackingVolumeHelper       = InDetTrackingVolumeHelper
+        # specifiy the binning, passive layers, entry layers
+        InDetCylinderVolumeCreator.PassiveLayerThickness      = TrkDetFlags.InDetPassiveLayerThickness()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsPhi        = TrkDetFlags.InDetPassiveLayerMaterialBinsPhi()  
+        InDetCylinderVolumeCreator.PassiveLayerBinsRZ         = TrkDetFlags.InDetPassiveLayerMaterialBinsRz()  
+        # output level                                       
+        InDetCylinderVolumeCreator.OutputLevel                = TrkDetFlags.InDetBuildingHelperOutputLevel()        
+        # add to ToolSvc
+        ToolSvc += InDetCylinderVolumeCreator        
+        
+        # the envelope definition service
+        from SubDetectorEnvelopes.SubDetectorEnvelopesConf import DetDescrDBEnvelopeSvc
+        AtlasEnvelopeSvc = DetDescrDBEnvelopeSvc('AtlasEnvelopeSvcDefinitionSvc')
+        # set the output level for the Envelope service
+        AtlasEnvelopeSvc.OutputLevel      = TrkDetFlags.InDetBuildingHelperOutputLevel()  
+        # add to SvcMgr
+        ServiceMgr += AtlasEnvelopeSvc
+        
+        # the tracking geometry builder
+        InDet__StagedTrackingGeometryBuilderCond.__init__(self,namePrefix+name,\
+                                                      LayerBuilders                 = layerProviders,
+                                                      LayerBinningTypeCenter        = binningsCenter,
+                                                      LayerBinningTypeEndcap        = binningsEndcap,
+                                                      ColorCodes                    = colors,
+                                                      EnvelopeDefinitionSvc         = AtlasEnvelopeSvc,
+                                                      VolumeEnclosureDiscPositions  = [ 3000., 3450. ],
+                                                      TrackingVolumeCreator         = InDetCylinderVolumeCreator,
+                                                      LayerArrayCreator             = InDetLayerArrayCreator,
+                                                      CheckForRingLayout            = True,
+                                                      BuildBoundaryLayers           = TrkDetFlags.InDetBuildMaterialBoundaries(),
+                                                      ReplaceAllJointBoundaries     = TrkDetFlags.InDetBuildJointBoundaries(),
+                                                      OutputLevel                   = TrkDetFlags.InDetBuildingOutputLevel(),
+                                                      ExitVolumeName                = TrkDetFlags.InDetContainerName(),
+                                                      MagneticFieldMode             = TrkDetFlags.MagneticFieldMode())
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilderCond.cxx
new file mode 100755
index 00000000000..b76e58c2528
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/BeamPipeBuilderCond.cxx
@@ -0,0 +1,170 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// BeamPipeBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#include "InDetTrackingGeometry/BeamPipeBuilderCond.h"
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk inlcude
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrGeoModelCnv/GeoShapeConverter.h"
+#include "TrkGeometry/MaterialProperties.h"
+#include "TrkGeometry/LayerMaterialProperties.h"
+#include "TrkGeometry/BinnedLayerMaterial.h"
+#include "TrkGeometry/HomogeneousLayerMaterial.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkSurfaces/CylinderBounds.h"
+// GeoModel include
+#include "BeamPipeGeoModel/BeamPipeDetectorManager.h"
+#include "GeoModelKernel/GeoTube.h"
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+// constructor
+InDet::BeamPipeBuilderCond::BeamPipeBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_beamPipeFromDb(true),
+  m_beamPipeMgr(0),
+  m_beamPipeMgrName("BeamPipe"),
+  m_beamPipeEnvelope(1.*Gaudi::Units::mm),
+  m_beamPipeOffsetX(0.*Gaudi::Units::mm),
+  m_beamPipeOffsetY(0.*Gaudi::Units::mm),
+  m_beamPipeRadius(33.1*Gaudi::Units::mm),
+  m_beamPipeHalflength(2.7*Gaudi::Units::m),
+  m_beamPipeThickness(1.*Gaudi::Units::mm),
+  m_beamPipeX0(352.8*Gaudi::Units::mm),
+  m_beamPipeL0(407.*Gaudi::Units::mm),
+  //m_beamPipedEdX(0.2945*Gaudi::Units::MeV/Gaudi::Units::mm),
+  m_beamPipeA(9.012),
+  m_beamPipeZ(4.),
+  m_beamPipeRho(1.848e-3),
+  m_beamPipeBinsZ(1),
+  m_identification("BeamPipe")
+{
+  declareInterface<Trk::ILayerBuilderCond>(this);
+  declareProperty("BeamPipeFromGeoModel" , m_beamPipeFromDb);
+  declareProperty("BeamPipeManager"      , m_beamPipeMgrName);
+  declareProperty("BeamPipeEnvelope"     , m_beamPipeEnvelope);
+  // --------------------- by hand properties of the beam pipe itself -- //
+  declareProperty("BeamPipeOffsetX"      , m_beamPipeOffsetX);
+  declareProperty("BeamPipeOffsetY"      , m_beamPipeOffsetY);
+  declareProperty("BeamPipeRadius"       , m_beamPipeRadius);
+  declareProperty("BeamPipeHalflength"   , m_beamPipeHalflength);
+  declareProperty("BeamPipeThickness"    , m_beamPipeThickness);
+  // --------------------- by hand material properties ---------------- //
+  declareProperty("BeamPipeX0"           , m_beamPipeX0);
+  declareProperty("BeamPipeAverageA"     , m_beamPipeA);
+  declareProperty("BeamPipeAverageZ"     , m_beamPipeZ);
+  declareProperty("BeamPipeAverageRho"   , m_beamPipeRho);
+  // Material bins 
+  declareProperty("BeamPipeMaterialBinsZ", m_beamPipeBinsZ);
+  // identification 
+  declareProperty("Identification"       , m_identification);
+}
+
+// destructor
+InDet::BeamPipeBuilderCond::~BeamPipeBuilderCond()
+{}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::BeamPipeBuilderCond::initialize()
+{
+  if (m_beamPipeFromDb && detStore()->retrieve(m_beamPipeMgr,m_beamPipeMgrName).isFailure()){
+      ATH_MSG_ERROR("Could not retrieve BeamPipe detector manager '" << m_beamPipeMgrName << "'." );
+      return StatusCode::FAILURE;
+  } else if (m_beamPipeFromDb)
+      ATH_MSG_DEBUG("Successfully retrieved BeamPipe detector manager '" << m_beamPipeMgrName << "'." );
+  
+  ATH_MSG_DEBUG( "initialize()" );
+  return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode InDet::BeamPipeBuilderCond::finalize()
+{
+    ATH_MSG_DEBUG( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+/** LayerBuilder interface method - returning Barrel-like layers */
+//TODO: context is not used, beamPipe retrieved from manager. range is infinite
+std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >*>  InDet::BeamPipeBuilderCond::cylindricalLayers(const EventContext&) const
+{
+  
+  std::vector<const Trk::CylinderLayer*>* beamPipe = new std::vector<const Trk::CylinderLayer*>;
+  
+  // the geometry
+  Amg::Transform3D* beamPipeTransform =  new Amg::Transform3D;
+  beamPipeTransform->setIdentity();
+
+  double beamPipeRadius = m_beamPipeRadius;
+  
+  if (m_beamPipeMgr){
+        // get the central top volume
+        PVConstLink beamPipeTopVolume =  m_beamPipeMgr->getTreeTop(0);
+        (*beamPipeTransform) = Amg::Translation3D(beamPipeTopVolume->getX().translation().x(),
+                                                  beamPipeTopVolume->getX().translation().y(),
+                                                  beamPipeTopVolume->getX().translation().z());
+        const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
+        const GeoTube* beamPipeTube = 0;
+        if (beamPipeLogVolume){
+            // get the geoShape and translate
+            Trk::GeoShapeConverter geoShaper;
+            beamPipeTube = dynamic_cast<const GeoTube*>(beamPipeLogVolume->getShape());
+            if (beamPipeTube)
+                beamPipeRadius = beamPipeTube->getRMax()-m_beamPipeEnvelope;
+        }
+        ATH_MSG_VERBOSE("BeamPipe constructed from Database: translation (yes) - radius "<< ( beamPipeTube ? "(yes)" : "(no)") << " - r = " << beamPipeRadius );        
+  } else 
+      (*beamPipeTransform) = Amg::Translation3D(m_beamPipeOffsetX, m_beamPipeOffsetY, 0.);
+
+  ATH_MSG_VERBOSE("BeamPipe shift estimated as    : " 
+      <<  beamPipeTransform->translation().x() << ", "
+      <<  beamPipeTransform->translation().y() << ","
+      <<  beamPipeTransform->translation().y());
+  
+  Trk::CylinderBounds* beamPipeBounds    = new Trk::CylinderBounds(beamPipeRadius, m_beamPipeHalflength);
+  ATH_MSG_VERBOSE("BeamPipe bounds constructed as : " << (*beamPipeBounds) );
+
+  // the material
+  Trk::MaterialProperties beamPipeMaterial(m_beamPipeThickness,
+					   m_beamPipeX0,
+                                           m_beamPipeL0,
+					   m_beamPipeA,
+					   m_beamPipeZ,
+					   m_beamPipeRho);
+  
+  // binned layer material for the beam pipe possible
+  Trk::LayerMaterialProperties* beamPipeLayerMaterial=0;
+  if (  m_beamPipeBinsZ == 1) 
+     beamPipeLayerMaterial = new Trk::HomogeneousLayerMaterial(beamPipeMaterial, 1.0);
+  else { 
+      Trk::BinUtility layerBinUtility(m_beamPipeBinsZ, -m_beamPipeHalflength, m_beamPipeHalflength, Trk::open, Trk::binZ );
+      beamPipeLayerMaterial = new Trk::BinnedLayerMaterial(layerBinUtility);  
+  }
+  
+  ATH_MSG_DEBUG( "BeamPipe constructed with material-properties: " << beamPipeMaterial ); 
+                                                                                    
+  beamPipe->push_back(new Trk::CylinderLayer(beamPipeTransform,
+                                             beamPipeBounds,
+                                             *beamPipeLayerMaterial,
+                                             m_beamPipeThickness));
+  //delete beamPipeLayerMaterial; 
+  
+  //create dummy infinite range
+  EventIDRange range;
+  return std::make_pair(range,beamPipe);
+  
+} 
+      
+
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/RobustTrackingGeometryBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/RobustTrackingGeometryBuilderCond.cxx
new file mode 100755
index 00000000000..42134152779
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/RobustTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,771 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+////////////////////////////////////////////////////////////////////
+// RobustTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// InDet
+#include "InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+// Trk interfaces
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ILayerArrayCreator.h"
+// Trk Geometry stuff
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkVolumes/VolumeBounds.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/MagneticFieldProperties.h"
+#include "TrkGeometry/Material.h"
+#include "TrkGeometry/Layer.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkSurfaces/DiscBounds.h"
+//Gaudi
+#include "GaudiKernel/SystemOfUnits.h"
+#include "GaudiKernel/MsgStream.h"
+
+// constructor
+InDet::RobustTrackingGeometryBuilderCond::RobustTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  Trk::TrackingVolumeManipulator(),
+  m_beamPipeBuilder("InDet::BeamPipeBuilder/AtlasBeamPipeBuilder"),
+  m_trackingVolumeCreator("Trk::CylinderVolumeCreator/CylinderVolumeCreator"),  
+  m_layerArrayCreator("Trk::LayerArrayCreator/LayerArrayCreator"),
+  m_enclosingEnvelopeSvc("AtlasEnvelopeDefSvc", n),
+  m_layerEnvelopeCover(2*Gaudi::Units::mm),
+  m_buildBoundaryLayers(true),
+  m_replaceJointBoundaries(true),
+  m_materialProperties(0),
+  m_magneticFieldProperties(0),
+  m_outwardsFraction(0.75),
+  m_indexStaticLayers(true),
+  m_namespace("InDet::"),
+  m_exitVolume("InDet::Containers::InnerDetector")
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);  
+  // layer builders and their configurations
+  declareProperty("BeamPipeBuilder",                  m_beamPipeBuilder);
+  declareProperty("LayerBuilders",                    m_layerBuilders);
+  declareProperty("LayerBinningType",                 m_layerBinningType);
+  declareProperty("ColorCodes",                       m_colorCodesConfig);  
+  // envelope definition service
+  declareProperty("EnvelopeDefinitionSvc",            m_enclosingEnvelopeSvc );
+  declareProperty("VolumeEnclosureCylinderRadii",     m_enclosingCylinderRadius);
+  declareProperty("VolumeEnclosureDiscPositions",     m_enclosingDiscPositionZ);
+  // helper tools  
+  declareProperty("TrackingVolumeCreator",            m_trackingVolumeCreator);
+  declareProperty("LayerArrayCreator",                m_layerArrayCreator);  
+  // build the Boundary Layers
+  declareProperty("EnvelopeCover",                    m_layerEnvelopeCover);
+  declareProperty("BuildBoundaryLayers",              m_buildBoundaryLayers);
+  declareProperty("ReplaceAllJointBoundaries",        m_replaceJointBoundaries);
+  // outer envelope to
+  declareProperty("OutwardsFraction",                 m_outwardsFraction); 
+  // force robust layer indexing  
+  declareProperty("IndexStaticLayers",                m_indexStaticLayers);
+  // volume namespace & contaienr name
+  declareProperty("VolumeNamespace",                  m_namespace); 
+  declareProperty("ExitVolumeName",                   m_exitVolume);
+  declareProperty("isSLHC",                           m_isSLHC=false);
+}
+
+// destructor
+InDet::RobustTrackingGeometryBuilderCond::~RobustTrackingGeometryBuilderCond()
+{
+  delete m_materialProperties;
+  delete m_magneticFieldProperties;
+}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::RobustTrackingGeometryBuilderCond::initialize()
+{
+  
+   // retrieve envelope definition service --------------------------------------------------
+   if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+     ATH_MSG_FATAL( "Could not retrieve EnvelopeDefinition service. Abort.");
+     return StatusCode::FAILURE;
+   }
+  
+   // Retrieve the beampipe builders --------------------------------------------------------  
+   if (m_beamPipeBuilder.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool(s) " << m_beamPipeBuilder );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_beamPipeBuilder );
+           
+   // Retrieve the layer builders -----------------------------------------------------------
+   if (m_layerBuilders.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool(s) " << m_layerBuilders );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_layerBuilders );
+
+   // Retrieve the tracking volume creator  -------------------------------------------------
+   if (m_trackingVolumeCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_trackingVolumeCreator );
+      
+   // Retrieve the layer array creator  ----------------------------------------------------
+   if (m_layerArrayCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_layerArrayCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_INFO( "Retrieved tool " << m_layerArrayCreator );      
+
+    // Dummy MaterialProerties
+    m_materialProperties = new Trk::Material;
+
+    ATH_MSG_INFO( "initialize() succesful" );
+    
+  return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> InDet::RobustTrackingGeometryBuilderCond::trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*>) const
+{
+   // only one assumption: 
+   // layer builders are ordered in increasing r
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////    
+   // The Overall Geometry
+
+   Trk::TrackingGeometry* trackingGeometry = 0;   
+
+   // retrieve all the layers and sort them
+   unsigned int numLayBuilders = m_layerBuilders.size();
+
+   // central sector extend
+   double centralExtendZ  = 0.;
+   // endcap extends
+   double endcapMaxExtend = 0.;
+   double endcapMinExtend = 10e10;  
+   // and the overallExtend(s)
+   double overallExtendZ  = 0.;   
+   double overallRmin     = 10e10;
+   double overallRmax     = 0.;
+      
+   // cylinder layers at growing radii
+   std::vector< std::vector< const Trk::Layer*> > providedCylinderLayers;
+   providedCylinderLayers.reserve(numLayBuilders);
+   std::vector< double > cylinderInnerRadii(numLayBuilders,10e10);
+   std::vector< double > cylinderOuterRadii(numLayBuilders,0.);
+   std::vector< double > cylinderExtendsInZ(numLayBuilders,0.);
+   
+   // negative disc layers and positive disc layers
+   std::vector< std::vector< const Trk::Layer*> > providedDiscLayersNeg;   
+   std::vector< std::vector< const Trk::Layer*> > providedDiscLayersPos;
+   providedDiscLayersNeg.reserve(numLayBuilders);
+   providedDiscLayersPos.reserve(numLayBuilders);   
+   std::vector< double > discInnerRadii(numLayBuilders,10e10);
+   std::vector< double > discOuterRadii(numLayBuilders,0.);
+   std::vector< double > discMinZ(numLayBuilders,10e10);
+   std::vector< double > discMaxZ(numLayBuilders,0.);
+
+   //Start with a range covering 0 - inf, then narrow down
+   EventIDRange range;
+   
+   // (I) PARSE THE LAYERS FOR OVERALL DIMENSIONS -------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 1 ] : Parse the provided layers for the dimensions." );
+   // fill the layers into the vectors
+   for ( unsigned int ilb = 0; ilb < m_layerBuilders.size(); ++ilb){
+       
+       Trk::BinningType binningType = (m_layerBinningType.size() == m_layerBuilders.size()) ? 
+                                      (Trk::BinningType)m_layerBinningType[ilb] : Trk::arbitrary; 
+       
+       // retrieve the cylinder and disc layers
+       ATH_MSG_DEBUG( "[ LayerBuilder : '" << m_layerBuilders[ilb]->identification() << "' ] being processed. " );
+       // (a) cylinder           
+       std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*> cylinderLayersPair = m_layerBuilders[ilb]->cylindricalLayers(ctx);
+       auto cylinderLayers = cylinderLayersPair.second;
+       // (a)
+       std::vector<const Trk::Layer*> cylinderVolumeLayers;     
+       if (cylinderLayers && cylinderLayers->size()){
+           range=EventIDRange::intersect(range,cylinderLayersPair.first);
+           // screen output
+           ATH_MSG_DEBUG(  "          Processing CylinderLayers : " );         
+           // the ones to be filled into the double-vector
+           for (auto& cylIter : *cylinderLayers){
+               // get the CylinderBounds
+               const Trk::CylinderBounds& cylBounds = (cylIter)->surfaceRepresentation().bounds();               
+               double currentR = cylBounds.r();
+               // rmin/rmax with thicknes in mind
+               double currentRmin = binningType!=Trk::biequidistant ? 
+                   currentR - 0.5*(cylIter)->thickness()-m_layerEnvelopeCover : currentR + 0.5*(cylIter)->thickness()-m_layerEnvelopeCover;               
+               double currentRmax = currentR + 0.5*(cylIter)->thickness() + m_layerEnvelopeCover;
+               // safe  
+               double extendZ  = cylIter->surfaceRepresentation().center().z() < 0. ?
+                                 fabs(cylIter->surfaceRepresentation().center().z() - cylBounds.halflengthZ())-m_layerEnvelopeCover:
+                                 cylIter->surfaceRepresentation().center().z() + cylBounds.halflengthZ() + m_layerEnvelopeCover;
+               // note the dimension
+               takeSmaller(cylinderInnerRadii[ilb],currentRmin); takeBigger(cylinderOuterRadii[ilb],currentRmax);
+               takeBigger(cylinderExtendsInZ[ilb],extendZ);
+               // push it into the vector
+               cylinderVolumeLayers.push_back(cylIter); 
+               // overall dimensions
+               takeSmaller(overallRmin,currentRmin); takeBigger(overallRmax,currentRmax);               
+               takeBigger(centralExtendZ, extendZ);
+               // in case no disc layers are provided
+               takeBigger(overallExtendZ,centralExtendZ);
+           }
+           // special treatment for bi-equidistant binning - a navigation layer will be added before and after the layers
+           if (binningType==Trk::biequidistant){
+               double rStep = (cylinderOuterRadii[ilb]-cylinderInnerRadii[ilb])/(cylinderLayers->size()-1);
+               ATH_MSG_VERBOSE( "           -> bi-equidistant : rStep estimated as " << rStep);
+               cylinderInnerRadii[ilb] -= rStep; cylinderOuterRadii[ilb] += rStep;
+               takeBigger(overallRmax,cylinderOuterRadii[ilb]);
+           }
+           ATH_MSG_VERBOSE(  "           -> yield (rMin/rMax/halflengthZ) = " 
+                 << cylinderInnerRadii[ilb] << " / " << cylinderOuterRadii[ilb] << " / " << cylinderExtendsInZ[ilb] ); 
+             
+       } else 
+         ATH_MSG_DEBUG(  "          No cylindrical layers processed." );        
+ 
+       providedCylinderLayers.push_back(cylinderVolumeLayers);       
+       // if after parsing of cylinder layers the maximal extend of cylinders is bigger than the minmal of discs
+       // reset the disc min extend (tiple will be swallowed)!
+       endcapMinExtend =  ( centralExtendZ > endcapMinExtend) ? 10e10 : endcapMinExtend; 
+       
+       // (b) discs       
+       std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*> discLayersPair = m_layerBuilders[ilb]->discLayers(ctx);
+       auto discLayers = discLayersPair.second;
+       std::vector<const Trk::Layer*> discVolumeLayersNeg;
+       std::vector<const Trk::Layer*> discVolumeLayersPos;                        
+       if (discLayers && discLayers->size()){
+         range=EventIDRange::intersect(range,discLayersPair.first);
+         // screen output
+         ATH_MSG_DEBUG(  "          Processing DiscLayers : " );            
+         for (auto& discIter : *discLayers){
+               // get the DiscBounds
+               const Trk::DiscBounds* discBounds = dynamic_cast<const Trk::DiscBounds*>
+                                                               (&(discIter->surfaceRepresentation().bounds()));               
+               // get the current Z min/max
+               double discZ = discIter->surfaceRepresentation().center().z();
+               double currentZmin = binningType!=Trk::biequidistant ? (discZ-0.5*discIter->thickness()) : (discZ+0.5*discIter->thickness());
+               double currentZmax = discZ+0.5*discIter->thickness();
+               // force it to be symmetrized
+               if (currentZmax > 0.){
+                 takeSmaller(discMinZ[ilb],currentZmin); takeBigger(discMaxZ[ilb], currentZmax);
+                 // push it into the vector
+                 discVolumeLayersPos.push_back(discIter);                            
+               } else {
+                // in symmetrized setup only interested in total numbers
+                 double negMinZ = fabs(currentZmax);
+                 double negMaxZ = fabs(currentZmin);
+                 takeSmaller(discMinZ[ilb],negMinZ); takeBigger(discMaxZ[ilb],negMaxZ);
+                 // push it into the vector
+                 discVolumeLayersNeg.push_back(discIter);                            
+               }
+               
+               // radial dimensions               
+               if (discBounds){
+                 double currentRmin = discBounds->rMin();                 
+                 double currentRmax = discBounds->rMax();                   
+                  // note the dimension
+                 takeSmaller(discInnerRadii[ilb], currentRmin); takeBigger(discOuterRadii[ilb],currentRmax);
+                 // overall dimensions
+                 takeSmaller(overallRmin, currentRmin); takeBigger(overallRmax, currentRmax);
+               }
+              // min/max extend of the discs
+              takeSmaller(endcapMinExtend, discMinZ[ilb]); takeBigger(endcapMaxExtend, discMaxZ[ilb]);
+              takeBigger(overallExtendZ, endcapMaxExtend);
+         }       
+         // special treatment for bi-equidistant binning - a navigation layer will be added before and after the layers
+         if (binningType==Trk::biequidistant){
+             double zStep = (discMaxZ[ilb]-discMinZ[ilb])/(discLayers->size()/2-1);
+             discMinZ[ilb] -= zStep;
+             discMaxZ[ilb] += zStep;
+             takeBigger(overallExtendZ,discMaxZ[ilb]);
+         }
+         
+         ATH_MSG_VERBOSE(  "           -> yield (rMin/rMax/zMin/zMax) = "
+                  << discInnerRadii[ilb] << " / " << discOuterRadii[ilb] << " / " << discMinZ[ilb] << " / " << discMaxZ[ilb] ); 
+         
+       } else 
+         ATH_MSG_DEBUG(  "          No disk-like layers processed." );   
+ 
+
+       // fill the layers into the double-vector
+       providedDiscLayersNeg.push_back(discVolumeLayersNeg);
+       providedDiscLayersPos.push_back(discVolumeLayersPos);
+                
+       // memory cleanup
+       delete discLayers;
+       delete cylinderLayers;  
+       
+       if (msgLvl(MSG::VERBOSE)){
+         // summary after this step
+         ATH_MSG_VERBOSE( "[ Summary STEP 1  ---------------------------------------- ]  " );
+         ATH_MSG_VERBOSE( "                      overall minimum r : " << overallRmin      );       
+         ATH_MSG_VERBOSE( "                      overall maximum r : " << overallRmax      );       
+         ATH_MSG_VERBOSE( "                       overall z extend : " << overallExtendZ   );       
+         ATH_MSG_VERBOSE( "                central sector z extend : " << centralExtendZ   );
+         ATH_MSG_VERBOSE( "                maximum endcap z extend : " << endcapMaxExtend  );
+         ATH_MSG_VERBOSE( "                minimum endcap z extend : " << endcapMinExtend  );
+       }
+              
+   }
+  
+    
+   // (II) update the positions ------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 2 ] : Closing the gaps from the parsed original dimensions." );   
+   // i.e. close the gap
+   double oldCeZ   = centralExtendZ;
+   centralExtendZ  = 0.5*(endcapMinExtend+oldCeZ);
+   endcapMinExtend = centralExtendZ;
+      
+   ATH_MSG_DEBUG( "             central sector extend in z recalculated to be " << centralExtendZ << " (was " << oldCeZ << ")" );
+ 
+   // (III) create the sub volumes -------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 3 ] : Create the sub volumes." );   
+   
+   std::vector<const Trk::TrackingVolume*> centralSectorVolumes;
+   std::vector<const Trk::TrackingVolume*> negativeSectorVolumes;
+   std::vector<const Trk::TrackingVolume*> positiveSectorVolumes;
+   
+   // --------------------------------------------------------------------------------------------------
+   // first the beampipe volume
+   Trk::TrackingVolume* beamPipeVolume = 0;
+   // the Volume Bounds
+   Trk::CylinderVolumeBounds* beamPipeBounds = new Trk::CylinderVolumeBounds(overallRmin,overallExtendZ); 
+   // BinnedArray needed
+   Trk::BinnedArray<Trk::Layer>* beamPipeLayerArray = 0;
+   std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer*>*> beamPipeVecPair = m_beamPipeBuilder->cylindricalLayers(ctx);
+   auto beamPipeVec = beamPipeVecPair.second;
+   if (beamPipeVec->size()){
+       range=EventIDRange::intersect(range,beamPipeVecPair.first);
+       beamPipeLayerArray = m_layerArrayCreator->cylinderLayerArray(*beamPipeVec,0.,beamPipeBounds->outerRadius(),Trk::arbitrary);
+   }
+   delete beamPipeVec;
+   // create the TrackingVolume
+   beamPipeVolume = new Trk::TrackingVolume(0,
+                                            beamPipeBounds,
+                                            *m_materialProperties,
+                                            beamPipeLayerArray,
+                                            0,
+                                            "InDet::BeamPipe");
+    // set the color code
+    beamPipeVolume->registerColorCode(46);
+   
+   // beampipe + detectors / prepared                                                                   
+   std::vector<const Trk::TrackingVolume*> idVolumes;
+   idVolumes.push_back(beamPipeVolume);     
+   
+   // --------------------------------------------------------------------------------------------------   
+   double lastCentralOuterR    = beamPipeBounds->outerRadius();
+   double lastNegEndcapOuterR  = beamPipeBounds->outerRadius();
+   double lastPosEndcapOuterR  = beamPipeBounds->outerRadius();
+   
+   // loop over double-vectors, access the dimensions from the parsing
+   auto pclIter  = providedCylinderLayers.begin();
+   auto pclEnd   = providedCylinderLayers.end();   
+   auto pndlIter = providedDiscLayersNeg.begin();
+   auto pndlEnd  = providedDiscLayersNeg.end();
+   auto ppdlIter = providedDiscLayersPos.begin();
+   auto ppdlEnd  = providedDiscLayersPos.end();
+   
+   // the number of layer builders
+   unsigned int numLayerBuilders = m_layerBuilders.size();
+   
+   // loop over the prepared volumes
+   for ( unsigned int ilb=0 ; pclIter != pclEnd && pndlIter != pndlEnd && ppdlIter != ppdlEnd; 
+        ++pclIter, ++pndlIter, ++ppdlIter, ++ilb)
+   {          
+       // color code configuration (from jobOptions/declareProperty interface)
+       int colorCode = (m_colorCodesConfig.size() == numLayerBuilders) ? m_colorCodesConfig[ilb] : 21;
+       
+       Trk::BinningType binningType = (m_layerBinningType.size() == numLayerBuilders) ? 
+                                      (Trk::BinningType)m_layerBinningType[ilb] : Trk::arbitrary; 
+       
+       // volume name base
+       std::string baseName = m_layerBuilders[ilb]->identification();
+       ATH_MSG_DEBUG( "[ Volume Creation : '" << baseName << "'] carried out." ); 
+       ATH_MSG_DEBUG( "       + color code                     : " << colorCode        );
+                  
+       // maxmmal z extend for volume set & endcap inner z
+       double currentSetExtendZ    =  ( (*pndlIter).size() || (*ppdlIter).size() ) ? discMaxZ[ilb] : cylinderExtendsInZ[ilb];
+       double currentEndcapInnerZ  =  ( (*pndlIter).size() || (*ppdlIter).size() ) ? discMinZ[ilb] : currentSetExtendZ;
+
+       // radii for the sectors 
+       double currentCentralOuterR  = 0.;
+       double currentEndcapOuterR   = 0.;
+       
+       if (m_isSLHC){
+	       double NextInnerRadii = ((ilb!=cylinderOuterRadii.size()-1) && cylinderInnerRadii[ilb+1]<discInnerRadii[ilb+1]) ? cylinderInnerRadii[ilb+1] : discInnerRadii[ilb+1]; 
+	       currentCentralOuterR = (ilb!=cylinderOuterRadii.size()-1) ? 0.5*(NextInnerRadii+cylinderOuterRadii[ilb]) : overallRmax;
+	       currentEndcapOuterR = (ilb!=discOuterRadii.size()-1) ? 0.5*(NextInnerRadii+discOuterRadii[ilb]) : overallRmax;
+       } else{
+           // we build from inside to outside, don't take middle position, but tend towards outer extend 
+	       currentCentralOuterR = (ilb!=cylinderOuterRadii.size()-1) ? (m_outwardsFraction*cylinderInnerRadii[ilb+1]+(1.-m_outwardsFraction)*cylinderOuterRadii[ilb]) : overallRmax;
+           currentEndcapOuterR = (ilb!=discOuterRadii.size()-1) ? (m_outwardsFraction*discInnerRadii[ilb+1]+(1.-m_outwardsFraction)*discOuterRadii[ilb]) : overallRmax;
+	            
+       }
+
+       ATH_MSG_VERBOSE( "       + checking the sector boundaries : " );        
+       ATH_MSG_VERBOSE( "         central sector ext. z (boundary)  = "  << currentSetExtendZ
+           << " ("  << centralExtendZ << ")" );        
+       ATH_MSG_VERBOSE( "       + current volume radii rMax (c/d)   = "  << currentCentralOuterR       
+           << " / " << currentEndcapOuterR );
+       // estimate the case
+       // cases are :
+       enum PackCase { contained, radial, central, split };  
+       //   0 - both cylinders and disc are contained in the central sector
+       //   1 - radial packing, volumes can't be put in in central / ec sectors
+       //   2 - only central sector exists
+       //   3 - standard ecn / central / ecp sectors split
+       bool endcapsExist =  (*pndlIter).size()  && (*ppdlIter).size() ;
+       // case flag set 
+       PackCase caseFlag = (currentSetExtendZ < centralExtendZ && endcapsExist) ? contained : split;       
+       if (currentSetExtendZ > centralExtendZ && currentEndcapInnerZ < centralExtendZ && endcapsExist) caseFlag = radial;
+       if (!endcapsExist) caseFlag = central;
+       
+       // case 0 and 1 can be handled together : 
+       if ( caseFlag == contained || caseFlag == radial ){
+          // create the volume sizes for the compact volume
+          double currentCentralExtendZ = 0.5*(cylinderExtendsInZ[ilb]+discMinZ[ilb]);
+          double currentExtendZ = contained ? centralExtendZ : overallExtendZ;
+          // in the radial wrapping case : take the smaller radius, assumes that packing is possible               
+          double currentOuterR = currentCentralOuterR < currentEndcapOuterR ? currentCentralOuterR : currentEndcapOuterR;
+          // create the tiple container
+          const Trk::TrackingVolume* tripleContainer = packVolumeTriple((*pndlIter),
+                                                                        (*pclIter),
+                                                                        (*ppdlIter),
+                                                                        lastCentralOuterR, currentOuterR,
+                                                                        currentExtendZ,currentCentralExtendZ,
+                                                                        baseName,
+                                                                        colorCode,
+                                                                        binningType);
+
+
+          // cache the last central / ec outer radius       
+          lastCentralOuterR = currentOuterR;
+          if (contained){                     
+              ATH_MSG_VERBOSE( "       + case I   : provided cylinder and disc layers are entirely contained in central sector." );                                                          
+              // and push the centralSectorVolumes
+              centralSectorVolumes.push_back(tripleContainer);
+           } else {
+              ATH_MSG_VERBOSE( "       + case II  : split into negative - central - positive sectors doesn't work, radial wrapping" ); 
+              // cache the laster endcap radii  (need to be equal since this is radially wrapped)
+              lastNegEndcapOuterR = currentOuterR;
+              lastPosEndcapOuterR = currentOuterR;
+              // the triple goes into the radial packing volumes
+              idVolumes.push_back(tripleContainer);     
+           }
+       // case 2 and 3        
+       } else {       
+          // output for case 3 and 4          
+          if (!endcapsExist)   
+            ATH_MSG_VERBOSE( "       + case III : only central sector." );        
+          else 
+            ATH_MSG_VERBOSE( "       + case IV  : split into negative - central - positive sectors." ); 
+          // build the name
+          std::string volumeBase = m_namespace+"Detectors::"+baseName;          
+          // cylinder layers exist -------------------------------
+          if ((*pclIter).size()){
+            
+            ATH_MSG_VERBOSE( "       -> central sector is being build." ); 
+            // create the cylinder barrel 
+            const Trk::TrackingVolume* barrel    = 
+                m_trackingVolumeCreator->createTrackingVolume((*pclIter),
+                                                              *m_materialProperties,
+                                                              lastCentralOuterR,currentCentralOuterR,
+                                                              -centralExtendZ,centralExtendZ,
+                                                              volumeBase+"::Barrel",
+                                                              binningType);
+            // register the color code
+            barrel->registerColorCode(colorCode);                
+            // cache the last ones
+            lastCentralOuterR = currentCentralOuterR;
+            // and push the centralSectorVolumes
+            centralSectorVolumes.push_back(barrel);          
+          } 
+
+          // negative disc layers exist ------------------------------
+          if ((*pndlIter).size()){
+          
+            ATH_MSG_VERBOSE( "       -> negative endcap is being build." );       
+            // create the cylinder barrel 
+            const Trk::TrackingVolume* negEndcap    = 
+                m_trackingVolumeCreator->createTrackingVolume((*pndlIter),
+                                                              *m_materialProperties,
+                                                              lastNegEndcapOuterR,currentEndcapOuterR,
+                                                              -overallExtendZ, -endcapMinExtend,
+                                                              volumeBase+"::NegativeEndcap",
+                                                              binningType);                
+            // register the color code
+            negEndcap->registerColorCode(colorCode);                
+            // cache the last ones
+            lastNegEndcapOuterR = currentEndcapOuterR;
+            // and push the negativeSectorVolumes
+            negativeSectorVolumes.push_back(negEndcap);                    
+          }
+          // positive disc layers exist --------------------------------
+          if ((*ppdlIter).size()){
+          
+            ATH_MSG_VERBOSE( "       -> positive endcap is being build." );          
+            // create the cylinder barrel 
+            const Trk::TrackingVolume* posEndcap    = 
+                m_trackingVolumeCreator->createTrackingVolume((*ppdlIter),
+                                                              *m_materialProperties,
+                                                              lastPosEndcapOuterR,currentEndcapOuterR,
+                                                              endcapMinExtend,overallExtendZ,
+                                                              volumeBase+"::PositiveEndcap",
+                                                              binningType);                
+            // register the color code
+            posEndcap->registerColorCode(colorCode);                
+            // cache the last ones
+            lastPosEndcapOuterR = currentEndcapOuterR;
+            // and push the positiveSectorVolumes
+            positiveSectorVolumes.push_back(posEndcap);                    
+          }                      
+       }   
+   }      
+   
+   // (IV) create the container ---------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 4 ] : Create the container volume" );   
+   
+   bool enclose = (!m_enclosingEnvelopeSvc.empty());
+ 
+   const Trk::TrackingVolume* detectorContainer = packVolumeTriple(negativeSectorVolumes,
+                                                                   centralSectorVolumes,
+                                                                   positiveSectorVolumes,
+                                                                   "Container");
+                                                                   
+   // get the dimensions from the envelope service 
+   RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getInDetRZValues();
+   ATH_MSG_VERBOSE("       -> retrieved Inner Detector envelope definitions at size " << envelopeDefs.size());
+   double enclosingVolumeRadius = envelopeDefs[1].first;
+   double enclosingVolumeHalfZ  = fabs(envelopeDefs[1].second);
+                                                                   
+   // central enclosure volume
+   const Trk::TrackingVolume* centralEnclosure =  enclose ?
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           overallRmax, enclosingVolumeRadius,
+                                                                           -overallExtendZ, overallExtendZ,
+                                                                           1, true,
+                                                                           m_namespace+"Gaps::CentralEnclosure") : 0;
+   
+   // push the detector container into the ID volumes                                                              
+   idVolumes.push_back(detectorContainer);
+   if (centralEnclosure) idVolumes.push_back(centralEnclosure);
+   
+   std::string volumeName = enclose ? "InDet::Detectors::BpPixSctTrt" : m_exitVolume;
+
+   ATH_MSG_VERBOSE("       -> inserting beam pipe into detectors." ); 
+
+   const Trk::TrackingVolume* detectorWithBp = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(idVolumes,
+                                                                *m_materialProperties,
+                                                                volumeName,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+  
+   // if packing is needed ------------------------------------------------------------------
+   const Trk::TrackingVolume* highestIdVolume = 0;
+   if (enclose){
+    
+     // negative positions
+     std::vector<double> negDiscPositionZ(m_enclosingDiscPositionZ);
+     for (std::vector<double>::iterator posIter = negDiscPositionZ.begin();
+         posIter != negDiscPositionZ.end(); ++posIter) (*posIter) *= -1;
+        
+     
+     const Trk::TrackingVolume* negativeEnclosure =  negDiscPositionZ.size() ?
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           0., enclosingVolumeRadius,
+                                                                           -enclosingVolumeHalfZ, -overallExtendZ,
+                                                                           negDiscPositionZ, false,
+                                                                           m_namespace+"Gaps::NegativeEnclosure") :      
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                            0., enclosingVolumeRadius,
+                                                                            -enclosingVolumeHalfZ, -overallExtendZ,
+                                                                            1, false,
+                                                                            m_namespace+"Gaps::NegativeEnclosure");
+  
+     const Trk::TrackingVolume* positiveEnclosure = m_enclosingDiscPositionZ.size() ? 
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           0., enclosingVolumeRadius,
+                                                                           overallExtendZ, enclosingVolumeHalfZ,
+                                                                           m_enclosingDiscPositionZ, false,
+                                                                           m_namespace+"Gaps::PositiveEnclosure") :
+                           m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                            0., enclosingVolumeRadius,
+                                                                            overallExtendZ,enclosingVolumeHalfZ,
+                                                                            1, false,
+                                                                            m_namespace+"Gaps::PositiveEnclosure");
+  
+      std::vector<const Trk::TrackingVolume*> enclosedVolumes;
+        enclosedVolumes.push_back(negativeEnclosure);
+        enclosedVolumes.push_back(detectorWithBp);
+        enclosedVolumes.push_back(positiveEnclosure);
+   
+     const Trk::TrackingVolume* enclosedDetector = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(enclosedVolumes,
+                                                                *m_materialProperties,
+                                                                 m_exitVolume,
+                                                                 m_buildBoundaryLayers,
+                                                                 m_replaceJointBoundaries);
+                                                                          
+      highestIdVolume = enclosedDetector;                                                                       
+    } else  
+      highestIdVolume = detectorWithBp;
+      
+  // (V) create the TrackingGeometry ------------------------------------------------------  
+  trackingGeometry = new Trk::TrackingGeometry(highestIdVolume);
+ 
+ if (m_indexStaticLayers) {
+      ATH_MSG_VERBOSE("Re-index the static layers ...");
+      // ST temporary hack till layer numbering resolved
+      //trackingGeometry->indexStaticLayers(geometrySignature());   
+      trackingGeometry->indexStaticLayers(Trk::Global);   
+   }
+
+
+   return std::make_pair(range, trackingGeometry);
+}
+
+// finalize
+StatusCode InDet::RobustTrackingGeometryBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+const Trk::TrackingVolume* InDet::RobustTrackingGeometryBuilderCond::packVolumeTriple(
+                                     const std::vector<const Trk::Layer*>& negLayers,
+                                     const std::vector<const Trk::Layer*>& centralLayers,
+                                     const std::vector<const Trk::Layer*>& posLayers,
+                                     double rMin, double rMax,
+                                     double zMax, double zPosCentral,
+                                     const std::string& baseName,
+                                     int colorCode,
+                                     Trk::BinningType bintyp) const
+{
+
+
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Layers from '" << baseName << "' triple into a container volume. " );
+  
+  // create the strings
+  std::string volumeBase = m_namespace+"Detectors::"+baseName;
+  
+  const Trk::TrackingVolume* negativeVolume = 
+       m_trackingVolumeCreator->createTrackingVolume(negLayers,
+                                                     *m_materialProperties,
+                                                     rMin,rMax,
+                                                     -zMax,-zPosCentral,
+                                                     volumeBase+"::NegativeEndcap",
+                                                     bintyp);
+                                                                
+  const Trk::TrackingVolume* centralVolume = 
+         m_trackingVolumeCreator->createTrackingVolume(centralLayers,
+                                                       *m_materialProperties,
+                                                       rMin,rMax,
+                                                       -zPosCentral,zPosCentral,
+                                                       volumeBase+"::Barrel",
+                                                       bintyp);
+                                                       
+   const Trk::TrackingVolume* positiveVolume = 
+         m_trackingVolumeCreator->createTrackingVolume(posLayers,
+                                                       *m_materialProperties,
+                                                       rMin,rMax,
+                                                       zPosCentral,zMax,
+                                                       volumeBase+"::PositiveEndcap",
+                                                       bintyp);
+   
+   // the base volumes have been created
+   ATH_MSG_VERBOSE('\t' << '\t'<< "Volumes have been created, now pack them into a triple.");
+   // registerColorCode                                                   
+   negativeVolume->registerColorCode(colorCode);   
+   centralVolume->registerColorCode(colorCode);
+   positiveVolume->registerColorCode(colorCode);
+                                                         
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   tripleVolumes.push_back(negativeVolume);
+   tripleVolumes.push_back(centralVolume);
+   tripleVolumes.push_back(positiveVolume);
+   
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+                                                                
+   ATH_MSG_VERBOSE( '\t' << '\t'<< "Created container volume with bounds: " << tripleContainer->volumeBounds() );
+                                                                
+   return tripleContainer;
+}
+
+const Trk::TrackingVolume* InDet::RobustTrackingGeometryBuilderCond::packVolumeTriple(
+                                     const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                     const std::string& baseName) const
+{
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Volumes from '" << baseName << "' triple into a container volume. " );
+
+  unsigned int negVolSize = negVolumes.size();
+  unsigned int cenVolSize = centralVolumes.size();
+  unsigned int posVolSize = posVolumes.size();
+  
+  
+  
+    // create the strings
+  std::string volumeBase = m_namespace+"Containers::"+baseName;
+  
+  const Trk::TrackingVolume* negativeVolume = (negVolSize > 1) ?
+       m_trackingVolumeCreator->createContainerTrackingVolume(negVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::NegativeSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                             (negVolSize ? negVolumes[0] : 0);
+  const Trk::TrackingVolume* centralVolume = (cenVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(centralVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::CentralSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) :
+                                              (cenVolSize ? centralVolumes[0] : 0) ;
+                                              
+   const Trk::TrackingVolume* positiveVolume = ( posVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(posVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::PositiveSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                               (posVolSize ? posVolumes[0] : 0);
+   
+   if (!negativeVolume && !positiveVolume){
+       ATH_MSG_DEBUG( "No negative/positive sector given - no packing needed, returning central container!" );
+       return centralVolume;
+   }
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   if (negativeVolume) tripleVolumes.push_back(negativeVolume);
+   if (centralVolume) tripleVolumes.push_back(centralVolume);
+   if (positiveVolume) tripleVolumes.push_back(positiveVolume);
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+   return tripleContainer;
+}
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/SiLayerBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/SiLayerBuilderCond.cxx
new file mode 100755
index 00000000000..6aadedafbdf
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/SiLayerBuilderCond.cxx
@@ -0,0 +1,1178 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// SiLayerBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#include "InDetTrackingGeometry/SiLayerBuilderCond.h"
+#include "InDetTrackingGeometry/PixelOverlapDescriptor.h"
+#include "InDetTrackingGeometry/SCT_OverlapDescriptor.h"
+#include "InDetTrackingGeometry/DiscOverlapDescriptor.h"
+//InDet include
+#include "PixelReadoutGeometry/PixelDetectorManager.h"
+#include "SCT_ReadoutGeometry/SCT_DetectorManager.h"
+#include "InDetReadoutGeometry/SiDetectorElement.h"
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+#include "InDetIdentifier/SCT_ID.h" 
+#include "InDetIdentifier/PixelID.h" 
+// Trk inlcude
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/BinnedArray1D1D.h"
+#include "TrkDetDescrUtils/BinnedArray2D.h"
+#include "TrkDetDescrUtils/BinnedArray1D.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkGeometry/LayerMaterialProperties.h"
+#include "TrkGeometry/BinnedLayerMaterial.h"
+#include "TrkGeometry/HomogeneousLayerMaterial.h"
+#include "TrkGeometry/MaterialProperties.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkGeometry/PlaneLayer.h"
+#include "TrkSurfaces/Surface.h"
+#include "TrkSurfaces/CylinderBounds.h"
+#include "TrkSurfaces/DiscBounds.h"
+// GeoModel
+#include "GeoModelKernel/GeoLogVol.h"
+#include "GeoModelKernel/GeoVFullPhysVol.h"
+#include "GeoModelKernel/GeoMaterial.h"
+// Gaudi
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/SystemOfUnits.h"
+#include "GaudiKernel/SmartDataPtr.h"
+// STL
+#include <map>
+
+std::vector<const Trk::CylinderLayer*> InDet::SiLayerBuilderCond::s_splitCylinderLayers;
+std::vector<const Trk::DiscLayer*>     InDet::SiLayerBuilderCond::s_splitDiscLayers;
+EventIDRange                           InDet::SiLayerBuilderCond::s_splitIOVRange;
+double InDet::SiLayerBuilderCond::s_splitRadius = 0.;
+    
+// constructor
+InDet::SiLayerBuilderCond::SiLayerBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_pixelCase(true),
+  m_siMgr(0),
+  m_siMgrLocation("Pixel"),
+  m_pixIdHelper(0),
+  m_sctIdHelper(0),
+  m_setLayerAssociation(true),
+  m_barrelLayerBinsZ(100),
+  m_barrelLayerBinsPhi(1),
+  m_barrelEnvelope(0.1),
+  m_barrelEdbTolerance(0.05),
+  m_endcapRingLayout(false),
+  m_endcapLayerBinsR(100),
+  m_endcapLayerBinsPhi(1),
+  m_endcapEnvelope(0.1),
+  m_endcapComplexRingBinning(true),
+  m_identification("Pixel"),
+  m_splitMode(0),
+  m_splitTolerance(10.),   
+  m_runGeometryValidation(true)
+{
+  declareInterface<Trk::ILayerBuilderCond>(this);
+  // general steering
+  declareProperty("PixelCase"                        , m_pixelCase);
+  declareProperty("SiDetManagerLocation"             , m_siMgrLocation);
+  declareProperty("SetLayerAssociation"              , m_setLayerAssociation);
+  // For the Active Barrel Material
+  declareProperty("BarrelAdditionalLayerRadii"       , m_barrelAdditionalLayerR);
+  declareProperty("BarrelAdditionalLayerType"        , m_barrelAdditionalLayerType);
+  declareProperty("BarrelLayerBinsZ"                 , m_barrelLayerBinsZ);
+  declareProperty("BarrelLayerBinsPhi"               , m_barrelLayerBinsPhi);
+  declareProperty("BarrelEnvelope"                   , m_barrelEnvelope);
+  declareProperty("BarrelEdbTolerance"               , m_barrelEdbTolerance);
+  // For the Active Endcap Material
+  declareProperty("EndcapRingLayout"                 , m_endcapRingLayout);
+  declareProperty("EndcapAdditionalLayerPositionsZ"  , m_endcapAdditionalLayerPosZ);
+  declareProperty("EndcapAdditionalLayerType"        , m_endcapAdditionalLayerType);
+  declareProperty("EndcapLayerBinsR"                 , m_endcapLayerBinsR);
+  declareProperty("EndcapLayerBinsPhi"               , m_endcapLayerBinsPhi);
+  declareProperty("EndcapEnvelope"                   , m_endcapEnvelope);
+  declareProperty("EndcapComplexRingBinning"         , m_endcapComplexRingBinning);
+  // identification
+  declareProperty("Identification"                   , m_identification);
+  // split mode for multiple pixel systems (upgrade)
+  declareProperty("SplitMode"                        , m_splitMode);
+  declareProperty("SplitTolerance"                   , m_splitTolerance);      
+  // Validation
+  declareProperty("GeometryValidation"               , m_runGeometryValidation);
+}
+
+// destructor
+InDet::SiLayerBuilderCond::~SiLayerBuilderCond()
+{}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::SiLayerBuilderCond::initialize()
+{
+
+    ATH_MSG_DEBUG( "initialize()" );
+    // get Pixel Detector Description Manager
+    if (m_pixelCase){
+        const InDetDD::PixelDetectorManager* pixMgr = 0;
+        if ((detStore()->retrieve(pixMgr, m_siMgrLocation)).isFailure()) {
+            ATH_MSG_ERROR( "Could not get PixelDetectorManager '" << m_siMgrLocation << "', no layers for Pixel Detector will be built. " );
+        } else {
+            ATH_MSG_VERBOSE( "PixelDetectorManager retrieved with key '" << m_siMgrLocation <<"'." );
+            // assign the detector manager to the silicon manager
+            m_siMgr = pixMgr;
+            if (detStore()->retrieve(m_pixIdHelper, "PixelID").isFailure())
+                ATH_MSG_ERROR("Could not get Pixel ID helper");
+        }
+        ATH_CHECK(m_PixelReadKey.initialize());
+    } else {
+        const InDetDD::SCT_DetectorManager* sctMgr = 0;
+        if ((detStore()->retrieve(sctMgr, m_siMgrLocation)).isFailure()) {
+            ATH_MSG_ERROR( "Could not get SCT_DetectorManager '" << m_siMgrLocation << "', no layers for SCT Detector will be built. " );
+        } else {
+            ATH_MSG_VERBOSE( "SCT_DetectorManager retrieved with key '" << m_siMgrLocation <<"'." );
+            // assign the detector manager to the silicon manager
+            m_siMgr = sctMgr;
+            if (detStore()->retrieve(m_sctIdHelper, "SCT_ID").isFailure())
+                ATH_MSG_ERROR("Could not get SCT ID helper");
+        }
+        
+        ATH_CHECK(m_SCT_ReadKey.initialize());
+        ATH_CHECK(m_PixelReadKey.initialize());
+
+    }
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode InDet::SiLayerBuilderCond::finalize()
+{
+    ATH_MSG_DEBUG( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+/** LayerBuilder interface method - returning Barrel-like layers */
+std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*> InDet::SiLayerBuilderCond::cylindricalLayers(const EventContext& ctx) const
+{
+
+  // split mode 2nd part return the already built layers 
+  if (m_splitMode && s_splitCylinderLayers.size() ){
+      ATH_MSG_DEBUG( "[ Split mode/ Part 2 ] Returning " << s_splitCylinderLayers.size() << " cylinder layers." );
+      ATH_MSG_VERBOSE( "                       Split radius was set to " << s_splitRadius );
+      std::vector<const Trk::CylinderLayer*>* splitCylinderLayers = dressCylinderLayers(s_splitCylinderLayers);
+      s_splitCylinderLayers.clear();
+      return std::make_pair(s_splitIOVRange, splitCylinderLayers); 
+  } else if (m_splitMode){
+      ATH_MSG_DEBUG( "[ Split mode/ Part 1 ] Initializing." );
+      s_splitRadius = m_splitMode < 0 ? 10e10 : 0.;
+  }
+  
+
+  // sanity check for ID Helper
+  if (!m_pixIdHelper && !m_sctIdHelper){
+    ATH_MSG_ERROR("Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
+    //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*>(range,nullptr);
+  }
+
+  // take the numerlogoy
+  const InDetDD::SiNumerology& siNumerology = m_siMgr->numerology();     
+    
+  // pre-set parameters for the run
+  size_t barrelLayers = 0;
+  // save way to estimate the number of barrel layers : they can be deactivated hence the useLayer(i) check
+  for (int i = 0; i < siNumerology.numLayers(); i++)
+       if (siNumerology.useLayer(i)) barrelLayers++;
+  
+
+  // screen output
+  ATH_MSG_DEBUG( "Configured to build " << barrelLayers << " (active) barrel layers (out of " << siNumerology.numLayers() << " )" );
+  if (m_barrelAdditionalLayerR.size())
+      ATH_MSG_DEBUG( "Additionally " <<  m_barrelAdditionalLayerR.size() << " material layers will be built.");  
+      
+  // split mode for SLHC setup
+  if (m_splitMode)
+      ATH_MSG_DEBUG( "[ Split mode ] Some layers may be cached." );
+        
+  // for barrels (the statistics for ordering the modules)
+  std::vector<double>                                               layerRadius(barrelLayers,0.);
+  std::vector<double>                                               layerRmin(barrelLayers,10e10);
+  std::vector<double>                                               layerRmax(barrelLayers,0.);
+  std::vector<double>                                               layerThickness(barrelLayers,0.);
+  std::vector<double>                                               layerMinZ(barrelLayers,0.);
+  std::vector<double>                                               layerMaxZ(barrelLayers,0.);
+  std::vector<double>                                               layerHalfLength(barrelLayers,0.);
+  std::vector<double>                                               layerMinPhi(barrelLayers,0.);
+  std::vector<double>                                               layerMaxPhi(barrelLayers,0.);
+  std::vector<size_t>                                               layerPhiSectors(barrelLayers,0);
+  std::vector<size_t>                                               layerZsectors(barrelLayers,0);
+  std::vector< std::vector<float> >                                 layerZboundaries(barrelLayers, std::vector<float>());
+  std::vector< std::vector< Trk::SurfaceOrderPosition > >           layerSurfaces(barrelLayers, std::vector< Trk::SurfaceOrderPosition >());
+ 
+  // cache needed
+  double minHalflengthZ         = 10e10;
+  double maxHalflengthZ         = 0;
+  size_t sumCheckBarrelModules  = 0;
+  size_t barrelModules          = 0;
+ 
+  // [-A-] ------------------------ LOOP over Detector Elements of sensitive layers -----------------------------------
+  // iterate over the detector elements for layer dimension, etc.   
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection>* readHandle;
+  if(m_pixelCase){
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_PixelReadKey, ctx);
+  }else{
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_SCT_ReadKey, ctx);
+  }
+  const InDetDD::SiDetectorElementCollection* readCdo{**readHandle};
+  InDetDD::SiDetectorElementCollection::const_iterator sidetIter = readCdo->begin();    
+  for (; sidetIter != readCdo->end(); sidetIter++){
+     // Barrel check
+     if ((*sidetIter) && (*sidetIter)->isBarrel()){
+       // unit test
+       ++barrelModules;
+       // get the identifier
+       Identifier    currentId((*sidetIter)->identify());
+       int currentlayer = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
+       //skip the layer if it is chosen to be switched off
+       if ( !m_siMgr->numerology().useLayer(currentlayer) ) continue;
+       // (A) Determination of phi / eta sectors  ---------------------------------------------------
+       // only do the exercise if it hasn't been done already 
+       if (layerPhiSectors[currentlayer] == 0){                        
+          ATH_MSG_VERBOSE("Pre-processing Elements from Layer (id from idHelper): " << currentlayer );      
+          // set number of phiSectors
+          layerPhiSectors[currentlayer] = m_siMgr->numerology().numPhiModulesForLayer(currentlayer);
+          // set number of etaSectors
+          layerZsectors[currentlayer] = m_siMgr->numerology().numEtaModulesForLayer(currentlayer);
+          // get the HalfLength of the Layer
+          const InDetDD::SiDetectorElement* countPtr = (*sidetIter);
+          // needed for the complex z binning if activated
+          double lastModuleZ = 0.; 
+          std::vector<float> zboundaries; 
+          zboundaries.reserve(layerZsectors[currentlayer]+1);               
+          // walk all along to negative eta
+          while ((countPtr->prevInEta()))
+                 countPtr = countPtr->prevInEta();
+           layerMinZ[currentlayer] = countPtr->center().z() - 0.5*fabs(countPtr->length());
+           zboundaries.push_back(layerMinZ[currentlayer]);
+           lastModuleZ   = countPtr->center().z();
+           // register the layer minZ into the zboundaries         
+           // now walk all along to positive eta
+           while ((countPtr->nextInEta())) {
+                  countPtr = countPtr->nextInEta();
+                  // for complex binning
+                  double currentModuleZ   = countPtr->center().z();
+                  double currentZboundary = 0.5*(lastModuleZ+currentModuleZ);
+                  zboundaries.push_back(currentZboundary);
+                  lastModuleZ   = currentModuleZ;
+           }
+           layerMaxZ[currentlayer] = fabs(countPtr->center().z()) + 0.5*fabs(countPtr->length());
+           zboundaries.push_back(layerMaxZ[currentlayer]);
+           
+           // complex z binning mode
+           layerZboundaries[currentlayer] = zboundaries;
+           // chose which one to register for the split mode (SLHC)
+           layerHalfLength[currentlayer] =  layerMinZ[currentlayer]*layerMinZ[currentlayer] > layerMaxZ[currentlayer]*layerMaxZ[currentlayer] ?
+               fabs(layerMinZ[currentlayer]) : layerMaxZ[currentlayer];
+           // get the haflength of the layer
+           takeSmaller( minHalflengthZ, layerHalfLength[currentlayer]);
+           takeBigger( maxHalflengthZ, layerHalfLength[currentlayer]);
+           ATH_MSG_VERBOSE("      -> Determined Layer z range with  : " << layerMinZ[currentlayer] << " / " << layerMaxZ[currentlayer] );
+           ATH_MSG_VERBOSE("      -> Symmetric half length taken    : " << layerHalfLength[currentlayer]);
+       }
+                    
+       // (B) Determination of the radius ------------------------------------------------
+       // getting inner module
+       const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();
+       // take the maximum layer radius 
+       double currentR    = (*sidetIter)->center().perp(); 
+       double currentRmax = (*sidetIter)->rMax();
+       double currentRmin = (*sidetIter)->rMin();
+       layerRadius[currentlayer]  = (currentR > layerRadius[currentlayer]) ? currentR : layerRadius[currentlayer];
+       if (otherSide){
+           takeBigger( currentRmax, (otherSide)->rMax() );
+           takeSmaller( currentRmin, (otherSide)->rMin() );
+       }
+       takeSmaller( layerRmin[currentlayer], currentRmin );
+       takeBigger(  layerRmax[currentlayer], currentRmax );
+
+       // handle the split mode
+       if (m_splitMode > 0) takeBigger(s_splitRadius, layerRadius[currentlayer]);
+       else if (m_splitMode < 0) takeSmaller (s_splitRadius, layerRadius[currentlayer]);
+           
+       // fill the Surface vector
+       Amg::Vector3D orderPosition((*sidetIter)->center());
+       double currentPhi = orderPosition.phi();
+	   takeSmaller( layerMinPhi[currentlayer], currentPhi);
+       takeBigger( layerMaxPhi[currentlayer], currentPhi);
+       
+       // decide which one to register on the Radius: always the one with smaller radius
+       bool takeIt =  (!otherSide || (*sidetIter)->center().perp() < otherSide->center().perp() );
+       const Trk::Surface* moduleSurface = takeIt ? (&((*sidetIter)->surface())) : (&(otherSide->surface()));
+  
+       // register the module surface
+       Trk::SharedObject<const Trk::Surface> sharedSurface(moduleSurface, Trk::do_not_delete<const Trk::Surface>);
+  
+       Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
+       if (takeIt) (layerSurfaces[currentlayer]).push_back(surfaceOrder);
+     
+     } else if (!(*sidetIter)) // barrel chek and screen output
+        ATH_MSG_WARNING("NULL pointer to Barrel module given by SiDetectorManager! Please check db & dict.xml");
+  
+  } // SiDet Loop
+
+  // --------------------------- enf of LOOP over Detector Elements of sensitive layers ----------------------------------
+   
+  // [-B-] ------------------------ Construction of the layers -----------------------------------          
+  // [-B-1] construct the detection layers
+  std::vector< const Trk::CylinderLayer* > cylinderDetectionLayers;
+  int layerCounter          = 0;
+  double currentLayerExtend = 0.;
+  
+  // construct detection layers
+  for (auto& layerRadiusIter : layerRadius) {
+                  
+      Trk::CylinderLayer* activeLayer   = 0;
+      double currentLayerRadius         = 10e10;
+      bool splitDone                    = false;
+      // non-equidistant binning used ? auto-detection 
+      bool nonEquidistantBinning = false;
+      {
+          // calculate the average bin size
+          const double averageBinSize = (layerMaxZ[layerCounter]-layerMinZ[layerCounter])/(layerZsectors[layerCounter]);
+          const double inv_averageBinSize2 = 1. / (averageBinSize*averageBinSize);
+          // loop over the boundaries and check if theyare outside the tolerance
+          auto bIter  = layerZboundaries[layerCounter].begin();
+          auto bIterE = layerZboundaries[layerCounter].end();
+          for ( ++bIter; bIter != bIterE; ++bIter ){
+              float cZ = (*bIter);
+              float pZ = (*(bIter-1));
+              nonEquidistantBinning =  (cZ-pZ)*(cZ-pZ)*inv_averageBinSize2 < (1.-m_barrelEdbTolerance) *(1.-m_barrelEdbTolerance);
+              if (nonEquidistantBinning){
+                  ATH_MSG_VERBOSE("Non-equidistant binning for (Silicon) Surfaces on this layer with radius " << layerRadiusIter << " detected. ");
+                  ATH_MSG_VERBOSE("Difference " << (cZ-pZ)/averageBinSize << " at a allowed tolerance of : " << m_barrelEdbTolerance );
+                  break;
+              }
+          }
+      }
+      
+      //(1) the detecting layer : sensitive modules --------------------------------------------------------------------
+      // create the BinKeyUtility - the phi binning is identical
+      double halfPhiStep = M_PI/layerPhiSectors[layerCounter];
+      // protection in case phi value was fluctuating around 0 or M_PI in parsing
+      if (fabs(layerMinPhi[layerCounter]+layerMaxPhi[layerCounter])< halfPhiStep && fabs(M_PI+layerMinPhi[layerCounter]) < 0.5*halfPhiStep ){
+          ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
+          ATH_MSG_VERBOSE("    min phi / max phi detected  : "  << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
+          layerMinPhi[layerCounter] += 2*halfPhiStep;
+      } 
+      // now prepare the phi values
+      ATH_MSG_VERBOSE("Preparing the Phi-binning for   : " << layerPhiSectors[layerCounter] << " sectors.");
+      ATH_MSG_VERBOSE("    min phi / max phi detected  : " << layerMinPhi[layerCounter] << " / " << layerMaxPhi[layerCounter] );
+      double minPhiCorrected = layerMinPhi[layerCounter]-halfPhiStep;
+      double maxPhiCorrected = layerMaxPhi[layerCounter]+halfPhiStep;
+      // catch if the minPhi falls below M_PI
+      if (minPhiCorrected < -M_PI){
+          minPhiCorrected += 2*halfPhiStep;
+          maxPhiCorrected += 2*halfPhiStep;
+      }
+      ATH_MSG_VERBOSE("    min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
+       
+      
+      Trk::BinUtility* currentBinUtility   =  new Trk::BinUtility(layerPhiSectors[layerCounter],
+	  						                                      minPhiCorrected,
+	  						                                      maxPhiCorrected,
+	  						                                      Trk::closed, Trk::binPhi);
+      if (nonEquidistantBinning)
+          (*currentBinUtility) += Trk::BinUtility(layerZboundaries[layerCounter],
+                                                  Trk::open,
+                                                  Trk::binZ);
+      else 
+          (*currentBinUtility) += Trk::BinUtility(layerZsectors[layerCounter],
+                                                  layerMinZ[layerCounter],
+                                                  layerMaxZ[layerCounter],
+                                                  Trk::open,
+                                                  Trk::binZ);
+      // creating the binned array output
+      ATH_MSG_VERBOSE("Creating the binned array for the sensitive detector elements with BinUtility :");
+      ATH_MSG_VERBOSE( *currentBinUtility );
+      // the binned array for the senstive surfaces to be built            
+      Trk::BinnedArray<Trk::Surface>* currentBinnedArray = 
+            new Trk::BinnedArray2D<Trk::Surface>(layerSurfaces[layerCounter],currentBinUtility);       
+      // unit test for sub surface ordering
+	  const std::vector<const Trk::Surface*>& arraySurfaces = currentBinnedArray->arrayObjects();          
+
+      if (m_runGeometryValidation){
+         // checking for :
+         //   - empty surface bins
+         //   - doubly filled bins
+         std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
+         auto usmIter = uniqueSurfaceMap.end();
+         // ------- iterate  
+         auto asurfIter = arraySurfaces.begin();
+         auto asurfIterEnd = arraySurfaces.end();
+         for ( ; asurfIter != asurfIterEnd; ++asurfIter){
+             if ( (*asurfIter) ) {
+                ++sumCheckBarrelModules;
+                usmIter = uniqueSurfaceMap.find(*asurfIter);
+                if ( usmIter != uniqueSurfaceMap.end() )
+                    ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << (*asurfIter)->center().eta() << " / " << (*asurfIter)->center().phi());
+                else uniqueSurfaceMap[(*asurfIter)] = (*asurfIter)->center();
+	       }
+	       else 
+               ATH_MSG_WARNING("Null surface defined in BinUtility ArraySurfaces vector");
+         }
+      }
+
+      // dynamic layer extend and splitDone check (split mode need the dynamic extend !)
+      currentLayerExtend = layerHalfLength[layerCounter];
+      
+      // check if split has been done
+      // split mode < 0 : compare to maxHalfLength
+      // split mode > 0 : compare to minHalflength
+      double compareHalfLengthZ = m_splitMode < 0 ? maxHalflengthZ : minHalflengthZ;
+      
+      splitDone = m_splitMode && fabs(layerHalfLength[layerCounter]-compareHalfLengthZ) > m_splitTolerance;
+      if (m_splitMode){
+           ATH_MSG_DEBUG( "[ Split mode / part 1 ] Layer Halflength determined as: " << layerHalfLength[layerCounter]);
+           ATH_MSG_DEBUG( "                               while minHalflengthZ is: " << minHalflengthZ );
+           ATH_MSG_DEBUG( "                                     -> consequence is: " << (splitDone ? "store for iteration 2" : "build") );
+       }
+      
+      // dynamic layer extend determined by the sensitive layer dimensions
+      layerRadius[layerCounter] = 0.5*(layerRmax[layerCounter] + layerRmin[layerCounter]);
+      layerThickness[layerCounter] = layerRmax[layerCounter] - layerRmin[layerCounter];
+
+      // create the material
+      const Trk::LayerMaterialProperties* layerMaterial = barrelLayerMaterial(layerRadius[layerCounter], currentLayerExtend);
+      double currentLayerThickness = layerThickness[layerCounter]+m_barrelEnvelope;
+      
+      // screen output
+      ATH_MSG_DEBUG( "Construct BinnedArray for CylinderLayer with "<< (layerSurfaces[layerCounter]).size() << " SubSurfaces." );
+      ATH_MSG_DEBUG( "Building a CylinderLayer with " << layerPhiSectors[layerCounter]
+          << " / " <<   ( nonEquidistantBinning ? layerZboundaries[layerCounter].size() :  layerZsectors[layerCounter] ) << " phi/z bins. "   );
+      ATH_MSG_DEBUG( "  -> With Radius     :  " << layerRadius[layerCounter]    );       
+      ATH_MSG_DEBUG( "  -> With Thickness  :  " << currentLayerThickness << " - includes envelope tolerance : " << m_barrelEnvelope );
+      ATH_MSG_DEBUG( "  -> With Zmin/Zmax  :  " << -currentLayerExtend << " / " << currentLayerExtend );
+      
+      if ( nonEquidistantBinning && layerZboundaries[layerCounter].size() ){
+          // overrule the min bin - with the min radius 
+          // do the output to screen
+          double currentZ = -currentLayerExtend;
+          msg(MSG::DEBUG) <<  "  -> Z binning at      :  ";
+          for (size_t zbin = 0; zbin < layerZboundaries[layerCounter].size(); ++zbin) {
+              currentZ += layerZboundaries[layerCounter][zbin];
+              msg(MSG::DEBUG) << currentZ;
+              if (zbin <  layerZboundaries[layerCounter].size()-1) 
+                 msg(MSG::DEBUG) << ", ";
+          }
+          msg(MSG::DEBUG) << endmsg;           
+      }
+      // prepare the right overlap descriptor       
+      Trk::OverlapDescriptor* olDescriptor = 0;
+      if (m_pixelCase)
+          olDescriptor = new InDet::PixelOverlapDescriptor;
+      else olDescriptor = new  InDet::SCT_OverlapDescriptor;
+      // for eventual use with the passive layer
+      currentLayerRadius = layerRadius[layerCounter];
+
+      // construct the layer (finally)
+      activeLayer = new Trk::CylinderLayer(new Trk::CylinderBounds(layerRadius[layerCounter],currentLayerExtend),
+                                           currentBinnedArray,
+                                           *layerMaterial,
+                                           layerThickness[layerCounter],
+                                           olDescriptor);
+      // cleanup of the layer material --------------------------------------------------------------
+      delete layerMaterial; 
+      // register the layer to the surfaces
+      const std::vector<const Trk::Surface*>& layerSurfaces     = currentBinnedArray->arrayObjects();
+      registerSurfacesToLayer(layerSurfaces,*activeLayer);
+
+      // (3) register the layers --- either in the split vector or in the return vector 
+      if (splitDone) {
+          ATH_MSG_DEBUG( "[ Split mode / Part 1 ] Layer cached for Part 2" );
+          readHandle->range(s_splitIOVRange);
+          if (activeLayer) s_splitCylinderLayers.push_back(activeLayer);   
+          // get the split radius to the smallest one possible
+          if (m_splitMode > 0) takeSmaller( s_splitRadius, currentLayerRadius);
+          ATH_MSG_DEBUG("[ Split mode / part 1 ] Split radius (temproarily) set to : " << s_splitRadius );
+       } else {
+          if (m_splitMode < 0) takeBigger ( s_splitRadius, currentLayerRadius );
+          if (activeLayer) cylinderDetectionLayers.push_back(activeLayer);
+       } 
+       // increase the layer counter --- it is built
+       ++layerCounter;            
+
+  } // layer construction
+  // --------------------------- enf of detection layer construction loop ----------------------------------
+
+  ATH_MSG_DEBUG("Creating the final CylinderLayer collection with (potentially) additional layers.");
+  std::vector< const Trk::CylinderLayer* >* cylinderLayers = dressCylinderLayers(cylinderDetectionLayers);
+  
+  // multiply the check number in case of SCT 
+  sumCheckBarrelModules *= (m_pixelCase) ? 1 : 2; 
+  ATH_MSG_DEBUG( barrelModules << " Barrel Modules parsed for Cylinder Layer dimenstions." );
+  ATH_MSG_DEBUG( sumCheckBarrelModules << " Barrel Modules filled in Cylinder Layer Arrays." );
+  if ( barrelModules-sumCheckBarrelModules )
+     ATH_MSG_WARNING( barrelModules-sumCheckBarrelModules << " Modules not registered properly in binned array." );       
+
+  if (m_splitMode)
+     ATH_MSG_DEBUG("[ Split mode / part 1 ] Split radius determined as : " << s_splitRadius );
+
+  ATH_MSG_DEBUG("Returning " << cylinderLayers->size() << " cylinder layers.");
+  EventIDRange range;
+  readHandle->range(range);
+  delete readHandle;
+  std::pair<EventIDRange, const std::vector<const Trk::CylinderLayer*>*> cylinderLayersPair = std::make_pair(range,cylinderLayers);
+  return cylinderLayersPair;
+} 
+      
+/** LayerBuilder interface method - returning Endcap-like layers */
+std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*> InDet::SiLayerBuilderCond::discLayers(const EventContext& ctx) const
+{
+ 
+  // TODO: remove s_splitDiscLayers cache to make threadsafe. ignored for now as is only for ITk
+  // split mode 2nd 
+  if (m_splitMode && s_splitDiscLayers.size() ){
+    ATH_MSG_DEBUG( "[ Split mode/ Part 2 ] Returning " << s_splitDiscLayers.size() << " disc layers." );
+    std::vector<const Trk::DiscLayer*>* splitDiscs = new std::vector<const Trk::DiscLayer*>(s_splitDiscLayers);
+    s_splitDiscLayers.clear();
+    return std::make_pair(s_splitIOVRange, splitDiscs); 
+  }
+  // sanity check for ID Helper
+  if (!m_pixIdHelper && !m_sctIdHelper){
+       ATH_MSG_ERROR("Neither Pixel nor SCT Detector Manager or ID Helper could be retrieved - giving up.");
+    //create dummy infinite range
+    EventIDRange range;
+    return std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*>(range,nullptr);
+  } 
+
+  // check for DBMS
+  int nDBMLayers = m_siMgr->numerology().numEndcapsDBM();
+  if (!nDBMLayers) return createDiscLayers(ctx);
+  
+  ATH_MSG_DEBUG( "Found " << m_siMgr->numerology().numEndcapsDBM() << " DBM layers active, building first ECs, then DBMS");
+  std::pair<EventIDRange, std::vector<const Trk::DiscLayer*>*>  ecLayers = createDiscLayers(ctx);
+  if (ecLayers.second) {
+      ATH_MSG_VERBOSE( "Created " << ecLayers.second->size() << " endcap layers w/o  DBM.");
+      ecLayers = createDiscLayers(ctx, ecLayers.second);
+      ATH_MSG_VERBOSE( "Created " << ecLayers.second->size() << " endcap layers with DBM.");
+  }
+  return ecLayers;
+
+}
+
+/** LayerBuilder interface method - returning Endcap-like layers */
+std::pair<EventIDRange, std::vector< const Trk::DiscLayer* >* > InDet::SiLayerBuilderCond::createDiscLayers(const EventContext& ctx, std::vector<const Trk::DiscLayer*>* dLayers) const {
+ 
+  // this is the DBM flag
+  bool isDBM = (dLayers!=NULL);
+  
+  // get general layout
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection>* readHandle;
+  if(m_pixelCase){
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_PixelReadKey, ctx);
+  }else{
+    readHandle = new SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> (m_SCT_ReadKey, ctx);
+  }
+  const InDetDD::SiDetectorElementCollection* readCdo{**readHandle};
+  InDetDD::SiDetectorElementCollection::const_iterator sidetIter = readCdo->begin();    
+    
+  // save way to estimate the number of barrels
+  unsigned int endcapLayers = 0;
+  if (isDBM){
+     endcapLayers = m_siMgr->numerology().numDisksDBM();
+     ATH_MSG_DEBUG( "Configured to build " << endcapLayers << "*2 disc-like DBM layers" );
+  } else {           
+      for (int i = 0; i < m_siMgr->numerology().numDisks(); i++)
+          if (m_siMgr->numerology().useDisk(i)) endcapLayers++;
+     ATH_MSG_DEBUG( "Configured to build " << endcapLayers << " *2 disc-like layers  (+ additional support layers)." );
+  }
+ 
+  if (m_splitMode) 
+      ATH_MSG_DEBUG( "[ Split mode ] Some layers may bee cached." );
+
+  // prepare the vectors
+  std::vector<double>                                     discZmin(2*endcapLayers,10e10);
+  std::vector<double>                                     discZmax(2*endcapLayers,-10e10);
+  std::vector<double>                                     discZpos(2*endcapLayers,0.);
+  std::vector<double>                                     discRmin(2*endcapLayers,10e10);
+  std::vector<double>                                     discRmax(2*endcapLayers,0);
+  std::vector<double>                                     discThickness(2*endcapLayers,0.);
+  
+  std::vector< std::vector<Trk::SurfaceOrderPosition> >   discSurfaces;  
+  std::vector< std::vector<int> >                         discPhiSectors;
+  std::vector< std::vector<double> >                      discPhiMin;
+  std::vector< std::vector<double> >                      discPhiMax;
+  std::vector< std::vector<double> >                      discRingMinR;
+  std::vector< std::vector<double> >                      discRingMaxR;  
+    
+  // let's make sure the discs are ordered in z: that's the z / map index
+  std::map< double, int>                                  discZposLayerIndex;  
+    
+  // reserve -- better memory management    
+  discPhiMin.reserve(2*endcapLayers);
+  discPhiMax.reserve(2*endcapLayers);
+  discPhiSectors.reserve(2*endcapLayers);
+  discSurfaces.reserve(2*endcapLayers);
+  discRingMinR.reserve(2*endcapLayers);
+  discRingMaxR.reserve(2*endcapLayers);
+   
+  // initialize for checks (pos/neg discs -> 2 times discs)
+  for (unsigned int endcap=0; endcap<2*endcapLayers; endcap++){
+        discPhiMin.push_back(std::vector<double>());
+        discPhiMax.push_back(std::vector<double>());
+        discPhiSectors.push_back(std::vector<int>());
+        discSurfaces.push_back( std::vector<Trk::SurfaceOrderPosition>() );
+        // auto-detection
+        discRingMinR.push_back(std::vector<double>());
+        discRingMaxR.push_back(std::vector<double>());      
+   } // end of for loop
+   
+  int endcapModules = 0;
+  int sumCheckEndcapModules = 0;
+  unsigned int currentlayer = 0;
+  unsigned int currentdisk  = 0;
+  unsigned int currentring  = 0;
+  
+  // [-A1-] ------------------------ first LOOP over Detector Elements of sensitive layers -------------------------------                 
+  // -- get the missing dimensions by loop over DetElements
+  sidetIter = readCdo->begin();
+  for (; sidetIter != readCdo->end(); sidetIter++){
+     // take it - if 
+     // a) you have a detector element ... protection
+     // b) the detector element is EC (in the non-DBM case)
+     // c) the detector elemet is DBM in the DBM case
+     if ( (*sidetIter) && ( (!isDBM && (*sidetIter)->isEndcap()) || (isDBM && (*sidetIter)->isDBM())) ){
+     
+       // increase the counter of endcap modules
+        endcapModules++;
+        // parse all z positions for the mean value of the discs
+        double currentZ = (*sidetIter)->center().z();
+        // get the identifier & calculate current layer and current disk from it     
+        Identifier    currentId((*sidetIter)->identify());
+        currentdisk  = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
+        currentlayer = currentdisk;
+        currentlayer += currentZ > 0. ? endcapLayers : 0;
+
+        // check the current ring
+        currentring = m_pixIdHelper ? m_pixIdHelper->eta_module(currentId) : m_sctIdHelper->eta_module(currentId);
+
+        takeSmallerBigger(discZmin[currentlayer],discZmax[currentlayer],currentZ);
+
+        // set the disc Rmin / Rmax  
+        double currentRmin = (*sidetIter)->rMin();
+        double currentRmax = (*sidetIter)->rMax();
+
+        // how many rings do we have ?
+        unsigned int diskRings =  isDBM ? 
+            m_siMgr->numerology().numRingsForDiskDBM(currentdisk) : 
+            m_siMgr->numerology().numRingsForDisk(currentdisk);
+               
+        // the current phi 
+        double currentPhi = (*sidetIter)->center().phi();
+        takeSmaller(discRmin[currentlayer],currentRmin);
+        takeBigger( discRmax[currentlayer],currentRmax);
+
+        //fill the number of phi sectors for the different rings
+        if (!discPhiSectors[currentlayer].size()){
+           ATH_MSG_VERBOSE("Pre-processing Elements from Disk/Layer (id from idHelper): " << currentdisk << "/" << currentlayer );
+           // prepare the ring bins, initialise the first one to be something big
+           discPhiMin[currentlayer]      = std::vector<double>(diskRings,100.); 
+           discPhiMax[currentlayer]      = std::vector<double>(diskRings,-100.); 
+           discRingMinR[currentlayer]    = std::vector<double>(diskRings,1e10);
+           discRingMaxR[currentlayer]    = std::vector<double>(diskRings,0);
+           // fill the phi sectors 
+           ATH_MSG_VERBOSE("-> The current disk has " << diskRings << " ring(s)");
+           for (unsigned int iring=0; iring < diskRings; ++iring){
+               unsigned int phiSectorsRing = isDBM ? 
+                   m_siMgr->numerology().numPhiModulesForDiskRingDBM(currentdisk, iring) :
+                   m_siMgr->numerology().numPhiModulesForDiskRing(currentdisk, iring);
+              // get the number of phi sectors
+              ATH_MSG_VERBOSE("--> Ring " << iring << " has " << phiSectorsRing << " phi sectors");
+              discPhiSectors[currentlayer].push_back(phiSectorsRing);
+           }
+        }
+        // we take the phi / r binning only from the closer to IP module 
+        if ( !(*sidetIter)->otherSide() || fabs(currentZ) < fabs((*sidetIter)->otherSide()->center().z())){
+            // take phi-min and phimax
+            takeSmaller(discPhiMin[currentlayer][currentring],currentPhi);
+            takeBigger(discPhiMax[currentlayer][currentring],currentPhi);
+            // record the smalles ring & biggest ring radius
+            takeSmaller(discRingMinR[currentlayer][currentring],currentRmin);
+            takeBigger(discRingMaxR[currentlayer][currentring],currentRmax);
+        }
+     } else if (!(*sidetIter))
+        ATH_MSG_WARNING("NULL pointer to Endcap module given by SCT_DetectorManager! Please check db & dict.xml");
+  } // DetElement loop 
+
+  double minRmin = 10e10;
+  double maxRmax = -10e10;
+  
+  ATH_MSG_VERBOSE("Estimating the average z position and the radius for each disk.");
+  // get the average z-position per layer & estimate thes thickness
+  for (unsigned int iec=0; iec<2*endcapLayers; ++iec){
+       takeSmaller(minRmin,discRmin[iec]); takeBigger(maxRmax,discRmax[iec]);
+       // average it out
+       discZpos[iec]        = 0.5 * (discZmin[iec] + discZmax[iec]);
+       discThickness[iec]   = isDBM ? 1. : fabs(discZmax[iec]-discZmin[iec]);
+       // make the map z / index
+       discZposLayerIndex.insert(std::make_pair(discZpos[iec],iec));
+  }
+
+  // [-A2-] ------------------------ second LOOP over Detector Elements of sensitive layers -------------------------------                 
+  // fill the elements for the layers into the surface arrays
+  sidetIter = readCdo->begin();
+  for (; sidetIter != readCdo->end(); sidetIter++){
+    // Endcap
+    if ( ((*sidetIter) && ((!isDBM && (*sidetIter)->isEndcap()) || (isDBM && (*sidetIter)->isDBM()))) ){     
+        // get the identifier & calculate current layer and current disk from it     
+        Identifier    currentId((*sidetIter)->identify());
+        currentdisk  = m_pixIdHelper ? m_pixIdHelper->layer_disk(currentId) : m_sctIdHelper->layer_disk(currentId);
+        currentlayer = currentdisk;
+        currentlayer += (*sidetIter)->center().z() > 0. ? endcapLayers : 0;
+        // decision which module to take
+        const InDetDD::SiDetectorElement* otherSide = (*sidetIter)->otherSide();    
+        bool takeIt =  (!otherSide || fabs((*sidetIter)->center().z()) < fabs(otherSide->center().z()) );
+        const InDetDD::SiDetectorElement* chosenSide = takeIt ?  (*sidetIter) : otherSide;
+        // get the center position
+        const Amg::Vector3D& orderPosition = chosenSide->center();
+        // register the chosen side in the object array
+        Trk::SharedObject<const Trk::Surface> sharedSurface(&(chosenSide->surface()), [](const Trk::Surface*){});
+        Trk::SurfaceOrderPosition surfaceOrder(sharedSurface, orderPosition);
+        if (takeIt) (discSurfaces[currentlayer]).push_back(surfaceOrder);      
+    }      
+  } //end of filling
+    
+  // [-B-] ------------------------ Construction of the layers -----------------------------------
+  // construct the layers
+  std::vector< const Trk::DiscLayer* >* discLayers = dLayers ? dLayers : new std::vector< const Trk::DiscLayer* >;
+  std::vector<double>::iterator discZposIter = discZpos.begin();
+  int discCounter = 0;
+                                              
+  for ( ; discZposIter != discZpos.end(); ++discZposIter){
+       // the gathered R sectors  
+       size_t discRsectors = (discPhiSectors[discCounter]).size();
+       // dynamic estimation 1: estimate the layer thickness dynamically
+       double thickness = discThickness[discCounter]+m_endcapEnvelope;       
+       // put rMin in and sort the bins
+       std::vector<double> discRingMinRcopy = discRingMinR[discCounter];
+       std::sort(discRingMinRcopy.begin(), discRingMinRcopy.end());
+       bool reverseRsectors = !(discRingMinRcopy == discRingMinR[discCounter]); 
+              
+       // this causes a reverse order for the phi sectors
+       if (reverseRsectors){
+           ATH_MSG_VERBOSE("Auto-detect: rings in R are in " << ( reverseRsectors ? "reversed" : "standard") << " order.");
+           std::reverse(discPhiSectors[discCounter].begin(),discPhiSectors[discCounter].end());
+           std::reverse(discPhiMin[discCounter].begin(),discPhiMin[discCounter].end()); 
+           std::reverse(discPhiMax[discCounter].begin(),discPhiMax[discCounter].end()); 
+           std::reverse(discRingMaxR[discCounter].begin(),discRingMaxR[discCounter].end());
+       }       
+       // preperare the rboundaries
+       std::vector<float> discRboundaries;
+       discRboundaries.push_back(float(*discRingMinRcopy.begin()));
+       for ( std::vector<double>::iterator ringMaxRIter = discRingMaxR[discCounter].begin(); 
+            ringMaxRIter != discRingMaxR[discCounter].end(); ++ringMaxRIter)   
+           discRboundaries.push_back(float(*ringMaxRIter));
+
+       // screen output           
+       ATH_MSG_DEBUG( "Building a DiscLayer with " << discRsectors << " R sectors. " );
+       ATH_MSG_DEBUG( "  -> At Z - Position      :  " << discZpos[discCounter] );
+       ATH_MSG_DEBUG( "  -> With Thickness       :  " << thickness   << " i- ncludes envelope tolerance : " << m_endcapEnvelope );
+       ATH_MSG_DEBUG( "  -> With Rmin/Rmax (est) :  " << discRmin[discCounter] << " / " << discRmax[discCounter] );
+       ATH_MSG_DEBUG( "  -> With Rings           :  " << discRsectors );
+          
+       for (size_t irings=0; irings<discRsectors; ++irings)
+         ATH_MSG_DEBUG( " --> " << irings <<  " R sector has " << discPhiSectors[discCounter][irings] << " phi sectors. " );
+            
+       // prepare the binned array, it can be with one to several rings            
+       Trk::BinnedArray<Trk::Surface>* currentBinnedArray = 0;
+       std::vector<Trk::BinUtility*>* singleBinUtils = new std::vector<Trk::BinUtility*>;
+       bool weOwnSingleBinUtils{true};
+       if (discRsectors==1){
+            double halfPhiStep = M_PI/discPhiSectors[discCounter][0];
+            // protection in case phi value was fluctuating around 0 or M_PI in parsing
+            if (fabs(discPhiMin[discCounter][0]+discPhiMax[discCounter][0])< halfPhiStep && fabs(discPhiMin[discCounter][0]) < 0.5*halfPhiStep ){
+                ATH_MSG_VERBOSE("Detected module fluctuation around +/- M_PI, correcting for it.");
+                ATH_MSG_VERBOSE("    min phi / max phi detected  : "  << discPhiMin[discCounter][0] << " / " <<discPhiMax[discCounter][0] );
+                discPhiMin[discCounter][0] += 2*halfPhiStep;
+            } 
+            // prepare min phi and max phi & eventually a sub stepvalue
+            ATH_MSG_VERBOSE("    min phi / max phi detected  : " << discPhiMin[discCounter][0] << " / " << discPhiMax[discCounter][0] );
+            double minPhiCorrected = discPhiMin[discCounter][0]-halfPhiStep;
+            double maxPhiCorrected = discPhiMax[discCounter][0]+halfPhiStep;
+            // catch if the minPhi falls below M_PI
+            if (minPhiCorrected < -M_PI){
+                minPhiCorrected += 2*halfPhiStep;
+                maxPhiCorrected += 2*halfPhiStep;
+            }
+            ATH_MSG_VERBOSE("    min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
+            
+            ATH_MSG_VERBOSE("Constructing a one-dimensional BinnedArray with phiMin / phiMax (bins) = " 
+                << minPhiCorrected << " / " << maxPhiCorrected
+                << " (" << discPhiSectors[discCounter][0] << ")");
+            // an easier bin utility can be used                 
+            Trk::BinUtility* currentBinUtility = new Trk::BinUtility(discPhiSectors[discCounter][0] ,
+                                                                     minPhiCorrected,
+                                                                     maxPhiCorrected,
+                                                                     Trk::closed,
+                                                                     Trk::binPhi);
+            // a one-dimensional BinnedArray is sufficient
+            currentBinnedArray = new Trk::BinnedArray1D<Trk::Surface>(discSurfaces[discCounter],currentBinUtility);
+        } else {
+            ATH_MSG_VERBOSE("Constructing a two-dimensional BinnedArray.");
+            // get the binning in R first (can still be improved with non-aequidistant binning) 
+            Trk::BinUtility* currentSteerBinUtility = 0;
+            if (m_endcapComplexRingBinning && discRsectors > 1 ){
+                // respecting the actual element boundaires
+                ATH_MSG_VERBOSE("Non-equidistant binning detected.");
+                // now create the bin utility                                                          
+                currentSteerBinUtility = new Trk::BinUtility(discRboundaries,
+                                                                    Trk::open,
+                                                                    Trk::binR);
+             } else 
+                currentSteerBinUtility =  new Trk::BinUtility(discRsectors,
+                                                              discRmin[discCounter],
+                                                              discRmax[discCounter],
+                                                              Trk::open,
+                                                              Trk::binR);
+            ATH_MSG_VERBOSE("Steering bin utility constructed as : " << *currentSteerBinUtility);
+            // the single phi bin utilities
+            //std::vector<Trk::BinUtility*>* singleBinUtils = new std::vector<Trk::BinUtility*>;
+            singleBinUtils->reserve(discRsectors);
+            for (size_t irings=0; irings < discRsectors; ++irings){
+                    double halfPhiStep = M_PI/discPhiSectors[discCounter][irings];
+                    ATH_MSG_VERBOSE("    min phi / max phi detected  : " << discPhiMin[discCounter][irings] << " / " << discPhiMax[discCounter][irings] );
+                    double minPhiCorrected = discPhiMin[discCounter][irings]-halfPhiStep;
+                    double maxPhiCorrected = discPhiMax[discCounter][irings]+halfPhiStep;
+                    // catch if the minPhi falls below M_PI
+                    if (minPhiCorrected < -M_PI){
+                        minPhiCorrected += 2*halfPhiStep;
+                        maxPhiCorrected += 2*halfPhiStep;
+                    }
+                    ATH_MSG_VERBOSE("    min phi / max phi corrected : " << minPhiCorrected << " / " << maxPhiCorrected );
+                    ATH_MSG_VERBOSE("Constructing for ring " << irings << " phi utility with phiMin / phiMax (bins) = " 
+                        <<  minPhiCorrected << " / " << maxPhiCorrected << " (" << discPhiSectors[discCounter][irings] << ")") ;
+                    singleBinUtils->push_back(new Trk::BinUtility(discPhiSectors[discCounter][irings],
+                                                                  minPhiCorrected,
+                                                                  maxPhiCorrected,
+                                                                  Trk::closed,
+                                                                  Trk::binPhi));
+            }
+            // a two-dimensional BinnedArray is needed ; takes possession of singleBinUtils and
+            // will delete it on destruction.
+            weOwnSingleBinUtils=false;                                                       
+            currentBinnedArray = new Trk::BinnedArray1D1D<Trk::Surface>(discSurfaces[discCounter],
+                                                                        currentSteerBinUtility,
+                                                                        singleBinUtils);
+        }
+
+
+        int discSurfacesNum = (discSurfaces[discCounter]).size();
+        ATH_MSG_DEBUG( "Constructed BinnedArray for DiscLayer with "<< discSurfacesNum << " SubSurfaces." );
+
+        // always run the geometry validation to catch flaws
+        
+        // checking for :
+        //   - empty surface bins
+        //   - doubly filled bins
+        std::map< const Trk::Surface*,Amg::Vector3D > uniqueSurfaceMap;
+        std::map< const Trk::Surface*,Amg::Vector3D >::iterator usmIter = uniqueSurfaceMap.end();
+        // check the registered surfaces in the binned array
+        const std::vector<const Trk::Surface*>& arraySurfaces = currentBinnedArray->arrayObjects();
+        size_t dsumCheckSurfaces = 0;
+        double lastPhi = 0.;
+        for (auto& asurfIter : arraySurfaces){
+            if ( asurfIter ) {
+                ++dsumCheckSurfaces;
+                usmIter = uniqueSurfaceMap.find(asurfIter);
+                lastPhi = asurfIter->center().phi();
+                if ( usmIter != uniqueSurfaceMap.end() )
+                    ATH_MSG_WARNING("Non-unique surface found with eta/phi = " << asurfIter->center().eta() << " / " << asurfIter->center().phi());
+                else uniqueSurfaceMap[asurfIter] = asurfIter->center();
+            } else 
+                ATH_MSG_WARNING("Zero-pointer in array detected in this ring, last valid phi value was = " << lastPhi);            
+        }
+        sumCheckEndcapModules +=  dsumCheckSurfaces;   
+           
+        // force same size for material collection - may be refined later
+        double rMin = (m_splitMode || m_endcapRingLayout) ? discRmin[discCounter] : minRmin;
+        double rMax = (m_splitMode || m_endcapRingLayout) ? discRmax[discCounter] : maxRmax;
+       
+        ATH_MSG_DEBUG( "  -> With Rmin/Rmax (corr) :  " << minRmin << " / " << maxRmax );
+       
+       // get the layer material from the helper method
+        const Trk::LayerMaterialProperties* layerMaterial = endcapLayerMaterial(rMin,rMax);
+
+        // position & bounds of the active Layer
+        Amg::Transform3D*  activeLayerTransform = new Amg::Transform3D;
+        bool weOwnActiveLayerTransform=true;
+        (*activeLayerTransform) = Amg::Translation3D(0.,0.,discZpos[discCounter]);
+       
+        Trk::DiscBounds* activeLayerBounds    = new Trk::DiscBounds(rMin,rMax);
+        // prepare the right overlap descriptor       
+        Trk::OverlapDescriptor* olDescriptor = 0;
+        if (m_pixelCase)
+            olDescriptor = new InDet::PixelOverlapDescriptor;
+        //else olDescriptor = new  InDet::SCT_OverlapDescriptor;
+	else {
+	  std::vector<Trk::BinUtility*>* binUtils = new std::vector<Trk::BinUtility*>;
+	  if (singleBinUtils) {
+	    std::vector<Trk::BinUtility*>::iterator binIter = singleBinUtils->begin();
+	    for ( ; binIter != singleBinUtils->end(); ++binIter){
+	      binUtils->push_back((*binIter)->clone());
+	    }
+	  }
+	  //DiscOverlapDescriptor takes possession of binUtils, will delete it on destruction.
+	  // but *does not* manage currentBinnedArray.
+	  olDescriptor = new  InDet::DiscOverlapDescriptor(currentBinnedArray, binUtils);
+	}
+        
+        // layer creation; deletes currentBinnedArray in baseclass 'Layer' upon destruction
+        // activeLayerTransform deleted in 'Surface' baseclass
+        Trk::DiscLayer* activeLayer = new Trk::DiscLayer(activeLayerTransform,
+                                                         activeLayerBounds,
+                                                         currentBinnedArray,
+                                                         *layerMaterial,
+                                                         thickness,
+                                                         olDescriptor);
+        weOwnActiveLayerTransform=false;
+        // cleanup
+        delete layerMaterial;
+        // register the layer to the surfaces --- if necessary to the other sie as well
+        const std::vector<const Trk::Surface*>& layerSurfaces     = currentBinnedArray->arrayObjects();
+        registerSurfacesToLayer(layerSurfaces,*activeLayer);
+        if (m_splitMode){
+            ATH_MSG_DEBUG( "[ Split mode ] Checking if this layer needs to be cached." );
+            if (m_splitMode < 0 && rMin > s_splitRadius){
+                ATH_MSG_VERBOSE( "            Split mode is negative and rMin > splitRadius (" << rMin  << " > " << s_splitRadius << ").");
+                ATH_MSG_VERBOSE( "            -> Caching this disk.");
+                readHandle->range(s_splitIOVRange);
+                s_splitDiscLayers.push_back(activeLayer);
+            }
+            else if (m_splitMode > 0 && rMax < s_splitRadius){
+                ATH_MSG_VERBOSE( "            Split mode is positive and rMax < splitRadius (" << rMax  << " < " << s_splitRadius << ").");
+                ATH_MSG_VERBOSE( "            -> Caching this disk.");
+                readHandle->range(s_splitIOVRange);
+                s_splitDiscLayers.push_back(activeLayer);
+            }
+        } else 
+            discLayers->push_back(activeLayer);
+       // increase the disc counter by one
+       ++discCounter;
+       if (weOwnSingleBinUtils){
+         delete singleBinUtils;
+         singleBinUtils=nullptr;
+       }
+       if (weOwnActiveLayerTransform){
+        delete activeLayerTransform;
+        activeLayerTransform=nullptr;
+       }
+  }  
+
+  // multiply the check modules for SCT case
+  sumCheckEndcapModules *= (m_pixelCase) ? 1 : 2;        
+  ATH_MSG_DEBUG( endcapModules << " Endcap Modules parsed for Disc Layer dimensions." );
+  ATH_MSG_DEBUG( sumCheckEndcapModules << " Endcap Modules filled in Disc Layer Arrays." );
+  if ( endcapModules-sumCheckEndcapModules )
+     ATH_MSG_WARNING( endcapModules-sumCheckEndcapModules << " Modules not registered properly in binned array." );       
+
+ 
+  // sort the vector
+  Trk::DiscLayerSorterZ zSorter;
+  std::vector<const Trk::DiscLayer*>::iterator sortIter = discLayers->begin();
+  std::vector<const Trk::DiscLayer*>::iterator sortEnd   = discLayers->end(); 
+  std::sort(sortIter, sortEnd, zSorter);
+ 
+  // if there are additional layers to be built - never build for the DBM loop
+  if (m_endcapAdditionalLayerPosZ.size() && !isDBM){
+      // sort also the additional layer z positions
+      auto addLayerIter     = m_endcapAdditionalLayerPosZ.begin();
+      auto addLayerIterEnd  = m_endcapAdditionalLayerPosZ.end();
+      auto addLayerTypeIter = m_endcapAdditionalLayerType.begin();
+      // reassign the iterators
+      sortIter = discLayers->begin();
+      sortEnd   = discLayers->end();
+      // get the last rmin / rmax
+      double lastRmin = 0.;
+      double lastRmax = 0.;
+      // build the additional layers -------------------------------------------
+      for ( ; sortIter != sortEnd || addLayerIter != addLayerIterEnd; ){
+          // cache befor last parameters are overwritten 
+          double layerRmin       = lastRmin;
+          double layerRmax       = lastRmax;
+          double layerZposition   = 0.; 
+          // check if the z-position is smaller than the 
+          if ( sortIter != sortEnd){
+              // get the current z position to guarantee a symmetrical setup
+              layerZposition = (*sortIter)->surfaceRepresentation().center().z();
+              // get the bounds for the rMin / rMax setting
+              const Trk::DiscBounds* currentBounds = dynamic_cast<const Trk::DiscBounds*>(&((*sortIter)->surfaceRepresentation().bounds()));
+              lastRmin = currentBounds ? currentBounds->rMin() : 0.;
+              lastRmax = currentBounds ? currentBounds->rMax() : 0.;
+              ++sortIter;           
+          }
+          if ( addLayerIter != addLayerIterEnd){
+              // symmetric setup around 0.
+              double rMin = layerZposition > 0. ? layerRmin : lastRmin;
+              double rMax = layerZposition > 0. ? layerRmax : lastRmax;
+              // the passive layer
+              Trk::DiscLayer* passiveLayer = 0;
+              // passive layer creation
+              Amg::Transform3D* passiveDiscTransf = new Amg::Transform3D;
+              (*passiveDiscTransf) = Amg::Translation3D(0.,0.,*addLayerIter);
+              if (*addLayerTypeIter){
+                  ATH_MSG_DEBUG("Building an additional DiscLayer w/o sensitive modules at");
+                  // create the material and the passive layer
+                  const Trk::LayerMaterialProperties* passiveLayerMaterial = endcapLayerMaterial(rMin,rMax);
+                  passiveLayer = new Trk::DiscLayer(passiveDiscTransf,
+                                                    new Trk::DiscBounds(rMin,rMax),
+                                                    *passiveLayerMaterial,
+                                                    1.*Gaudi::Units::mm);
+              } else
+                  passiveLayer = new Trk::DiscLayer(passiveDiscTransf, new Trk::DiscBounds(rMin,rMax), 0);
+              ATH_MSG_DEBUG( "  -> At Z - Position       :  " << *addLayerIter );
+              ATH_MSG_DEBUG( "  -> With Rmin/Rmax (corr) :  " << rMin << " / " << rMax );
+              
+              // increase the iterator and push back the new layer
+             ++addLayerIter; 
+             discLayers->push_back(passiveLayer);
+          }
+      } // the additional layers are build ------------------------------------
+
+    // another round of sorting needed after adding the passive layers
+    sortIter = discLayers->begin();
+    sortEnd   = discLayers->end(); 
+    std::sort(sortIter, sortEnd, zSorter);
+  }
+ 
+  EventIDRange range;
+  readHandle->range(range);
+  delete readHandle;
+  return std::make_pair(range, discLayers);
+}
+
+
+
+std::vector< const Trk::CylinderLayer* >* InDet::SiLayerBuilderCond::dressCylinderLayers(const std::vector< const Trk::CylinderLayer* >& detectionLayers ) const {
+
+
+    std::vector< const Trk::CylinderLayer* >* cylinderLayers = new std::vector< const Trk::CylinderLayer* >;
+    // --------------------------- start of additional layer construction loop -------------------------------
+    // for the additional layer
+    if (m_barrelAdditionalLayerR.size()){
+        auto cylLayerIter         = detectionLayers.begin();
+        auto cylLayerIterEnd      = detectionLayers.end();
+        auto addLayerIter         = m_barrelAdditionalLayerR.begin();
+        auto addLayerIterEnd      = m_barrelAdditionalLayerR.end();
+        auto addLayerTypeIter     = m_barrelAdditionalLayerType.begin();
+        auto addLayerTypeIterEnd  = m_barrelAdditionalLayerType.end();
+        double cylLayerExtend     = 0;
+        for ( ; addLayerIter != addLayerIterEnd && addLayerTypeIter != addLayerTypeIterEnd; ) {
+            // build the passive layer if it is smaller the current cylLayerIter - or if it is the last one 
+            if ( m_splitMode && s_splitCylinderLayers.size() ){
+                ATH_MSG_DEBUG("Called in split mode with split radius = " << s_splitRadius );
+                ATH_MSG_DEBUG("[- X -] Skipping additional layer " );
+                ATH_MSG_DEBUG( "  -> With Radius     :  " << *addLayerIter   );       
+                // increase the additional layer radii
+                ++addLayerIter; ++addLayerTypeIter; 
+                continue;
+            }
+            if  ( cylLayerIter == cylLayerIterEnd || (*addLayerIter) < (*cylLayerIter)->bounds().r() ){
+              cylLayerExtend = (cylLayerIter == cylLayerIterEnd) ? cylLayerExtend : (*cylLayerIter)->bounds().halflengthZ() ;  
+              if ( (*addLayerTypeIter) ) {
+                    ATH_MSG_DEBUG("[- M -] Building an additional CylinderLayer w/o sensitive modules");
+                    // the material for the passive layer
+                    const Trk::LayerMaterialProperties* passiveLayerMaterial = barrelLayerMaterial(*addLayerIter,cylLayerExtend);
+                    // create the passive layer
+                    cylinderLayers->push_back(new Trk::CylinderLayer(new Trk::CylinderBounds(*addLayerIter,cylLayerExtend),
+                                                                     *passiveLayerMaterial,
+                                                                     1.*Gaudi::Units::mm,
+                                                                     0,0));
+                    // cleanup of the layer material --------------------------------------------------------------
+                    delete passiveLayerMaterial;                                                       
+              } else {
+                  ATH_MSG_DEBUG("[- N -] Building an additional NavigationLayer for volume dimension control");
+                  // create the passive layer
+                  cylinderLayers->push_back(new Trk::CylinderLayer(new Trk::CylinderBounds(*addLayerIter,cylLayerExtend),0));
+              }
+              ATH_MSG_DEBUG( "  -> With Radius     :  " << *addLayerIter   );       
+              // increase the additional layer radii
+              ++addLayerIter; ++addLayerTypeIter; 
+              continue;
+          } 
+          ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
+          ATH_MSG_DEBUG( "  -> With Radius     :  " << (*cylLayerIter)->bounds().r()   );
+          cylinderLayers->push_back(*cylLayerIter);
+          ++cylLayerIter;       
+        }
+    } else 
+        for (auto& cylLayerIter : detectionLayers ) {
+            ATH_MSG_DEBUG("[- D -] Registering detection CylinderLayer");
+            ATH_MSG_DEBUG( "  -> With Radius     :  " << cylLayerIter->bounds().r()   );
+            cylinderLayers->push_back(cylLayerIter);
+        }
+    return cylinderLayers;
+}
+
+const Trk::LayerMaterialProperties* InDet::SiLayerBuilderCond::barrelLayerMaterial(double r, double hz) const
+{
+  Trk::LayerMaterialProperties* layerMaterial = 0;
+  // --------------- material estimation ----------------------------------------------------------------
+  // -- material with 1D binning
+  Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -hz, hz, Trk::open, Trk::binZ);
+  if (m_barrelLayerBinsPhi==1){
+      layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityZ);
+  } else  { // -- material with 2D binning
+      Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
+                                                 -r*M_PI, r*M_PI,
+                                                 Trk::closed,
+                                                 Trk::binRPhi);
+      layerBinUtilityRPhiZ += layerBinUtilityZ;                                                       
+      layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityRPhiZ);
+  }
+  // --------------- material estimation ----------------------------------------------------------------
+  return layerMaterial;    
+}
+
+const Trk::LayerMaterialProperties* InDet::SiLayerBuilderCond::endcapLayerMaterial(double rMin, double rMax) const
+{
+  Trk::LayerMaterialProperties* layerMaterial = 0;
+  // --------------- material estimation ----------------------------------------------------------------
+
+  Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,rMin,rMax,Trk::open, Trk::binR);
+  // -- material with 1D binning
+  if (m_endcapLayerBinsPhi==1){
+      layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityR);
+  } else { // -- material with 2D binning
+      Trk::BinUtility layerBinUtilityPhi(m_endcapLayerBinsPhi,-M_PI,M_PI,Trk::closed,Trk::binPhi);
+      layerBinUtilityR += layerBinUtilityPhi;
+      layerMaterial     = new Trk::BinnedLayerMaterial(layerBinUtilityR);
+  }
+  // --------------- material estimation ----------------------------------------------------------------
+  return layerMaterial;    
+}     
+
+void InDet::SiLayerBuilderCond::registerSurfacesToLayer(const std::vector<const Trk::Surface*>& layerSurfaces, const Trk::Layer& lay) const
+{
+    if (!m_setLayerAssociation) return;
+    
+    std::vector<const Trk::Surface*>::const_iterator laySurfIter    = layerSurfaces.begin();
+    std::vector<const Trk::Surface*>::const_iterator laySurfIterEnd = layerSurfaces.end();
+    // register the surfaces to the layer
+    for (; laySurfIter != laySurfIterEnd; ++laySurfIter){
+        if (*laySurfIter) { 
+            // register the current surface --------------------------------------------------------
+            Trk::ILayerBuilderCond::associateLayer(lay, **laySurfIter);
+            const InDetDD::SiDetectorElement* detElement 
+                = dynamic_cast<const InDetDD::SiDetectorElement*>((*laySurfIter)->associatedDetectorElement());             
+            // register the backise if necessary ---------------------------------------------------
+            const InDetDD::SiDetectorElement* otherSideElement = detElement ?  detElement->otherSide() : 0;                 
+            const Trk::Surface* otherSideSurface = otherSideElement ? &(otherSideElement->surface()) : 0;
+            if (otherSideSurface) Trk::ILayerBuilderCond::associateLayer(lay, *otherSideSurface);
+            }
+    }   
+    
+    return;
+}
+
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/StagedTrackingGeometryBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/StagedTrackingGeometryBuilderCond.cxx
new file mode 100755
index 00000000000..9ef48138b05
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/StagedTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,718 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+////////////////////////////////////////////////////////////////////
+// StagedTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// InDet
+#include "InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+// Trk interfaces
+#include "TrkDetDescrInterfaces/ILayerProviderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ILayerArrayCreator.h"
+// Trk Geometry stuff
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkVolumes/VolumeBounds.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/MagneticFieldProperties.h"
+#include "TrkGeometry/Material.h"
+#include "TrkGeometry/Layer.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkSurfaces/DiscBounds.h"
+//Gaudi
+#include "GaudiKernel/SystemOfUnits.h"
+#include "GaudiKernel/MsgStream.h"
+#include <boost/lexical_cast.hpp>
+
+// constructor
+InDet::StagedTrackingGeometryBuilderCond::StagedTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  Trk::TrackingVolumeManipulator(),
+  m_trackingVolumeCreator("Trk::CylinderVolumeCreator/CylinderVolumeCreator"),  
+  m_layerArrayCreator("Trk::LayerArrayCreator/LayerArrayCreator"),
+  m_enclosingEnvelopeSvc("AtlasEnvelopeDefSvc", n),
+  m_layerEnvelopeCover(2*Gaudi::Units::mm),
+  m_buildBoundaryLayers(true),
+  m_replaceJointBoundaries(true),
+  m_materialProperties(0),
+  m_magneticFieldProperties(0),
+  m_indexStaticLayers(true),
+  m_checkForRingLayout(false),
+  m_ringTolerance(10*Gaudi::Units::mm),
+  m_namespace("InDet::"),
+  m_exitVolume("InDet::Containers::InnerDetector")
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);  
+  // layer builders and their configurations
+  declareProperty("LayerBuilders",                    m_layerProviders);
+  declareProperty("LayerBinningTypeCenter",           m_layerBinningTypeCenter);
+  declareProperty("LayerBinningTypeEndcap",           m_layerBinningTypeEndcap);
+  declareProperty("ColorCodes",                       m_colorCodesConfig);  
+  // envelope definition service
+  declareProperty("EnvelopeDefinitionSvc",            m_enclosingEnvelopeSvc );
+  declareProperty("VolumeEnclosureCylinderRadii",     m_enclosingCylinderRadius);
+  declareProperty("VolumeEnclosureDiscPositions",     m_enclosingDiscPositionZ);
+  // helper tools  
+  declareProperty("TrackingVolumeCreator",            m_trackingVolumeCreator);
+  declareProperty("LayerArrayCreator",                m_layerArrayCreator);  
+  // build the Boundary Layers
+  declareProperty("EnvelopeCover",                    m_layerEnvelopeCover);
+  declareProperty("BuildBoundaryLayers",              m_buildBoundaryLayers);
+  declareProperty("ReplaceAllJointBoundaries",        m_replaceJointBoundaries);
+  // force robust layer indexing  
+  declareProperty("IndexStaticLayers",                m_indexStaticLayers);
+  declareProperty("CheckForRingLayout",               m_checkForRingLayout);
+  // volume namespace & contaienr name
+  declareProperty("VolumeNamespace",                  m_namespace); 
+  declareProperty("ExitVolumeName",                   m_exitVolume);
+}
+
+// destructor
+InDet::StagedTrackingGeometryBuilderCond::~StagedTrackingGeometryBuilderCond()
+{
+  delete m_materialProperties;
+  delete m_magneticFieldProperties;
+}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::StagedTrackingGeometryBuilderCond::initialize()
+{
+  
+   // retrieve envelope definition service --------------------------------------------------
+   if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+     ATH_MSG_FATAL( "Could not retrieve EnvelopeDefinition service. Abort.");
+     return StatusCode::FAILURE;
+   }
+           
+   // Retrieve the layer builders -----------------------------------------------------------
+   if (m_layerProviders.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool(s) " << m_layerProviders );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_layerProviders );
+
+   // Retrieve the tracking volume creator  -------------------------------------------------
+   if (m_trackingVolumeCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_DEBUG( "Retrieved tool " << m_trackingVolumeCreator );
+      
+   // Retrieve the layer array creator  ----------------------------------------------------
+   if (m_layerArrayCreator.retrieve().isFailure())
+   {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_layerArrayCreator );
+      return StatusCode::FAILURE;
+   } else
+      ATH_MSG_INFO( "Retrieved tool " << m_layerArrayCreator );      
+
+    // Dummy MaterialProerties
+    m_materialProperties = new Trk::Material;
+
+    ATH_MSG_INFO( "initialize() succesful" );
+    
+  return StatusCode::SUCCESS;
+}
+
+//FIXME: ctx, tVolPair not used yet, range not created
+std::pair<EventIDRange, const Trk::TrackingGeometry*> InDet::StagedTrackingGeometryBuilderCond::trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> /*tVolPair*/) const
+{
+   // only one assumption: 
+   // layer builders are ordered in increasing r
+   ATH_MSG_DEBUG( "[ Start building the ID TrackingGeometry. ]"); 
+   ATH_MSG_DEBUG( "[ STEP 0 ] : Getting overal dimensions from DetectorEnvelope service." );
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////    
+   // The Overall Geometry
+   Trk::TrackingGeometry* trackingGeometry = 0;   
+
+   // get the dimensions from the envelope service 
+   RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getInDetRZValues();
+   ATH_MSG_VERBOSE("       -> retrieved Inner Detector envelope definitions at size " << envelopeDefs.size());
+   double envelopeVolumeRadius = envelopeDefs[1].first;
+   double envelopeVolumeHalfZ  = fabs(envelopeDefs[1].second);
+   ATH_MSG_VERBOSE("       -> envelope R/Z defined as : " << envelopeVolumeRadius << " / " << envelopeVolumeHalfZ );
+
+   ATH_MSG_DEBUG( "[ STEP 1 ] : Getting overal dimensions from the different layer builders." );
+   size_t ilS = 0;
+   double maximumLayerExtendZ   = 0.;
+   double maximumLayerRadius    = 0.;
+   std::vector<InDet::LayerSetup> layerSetups;
+   EventIDRange range;
+   for ( auto& lProvider : m_layerProviders){
+       // screen output 
+       ATH_MSG_DEBUG( "[ LayerBuilder : '" << lProvider->identification() << "' ] being processed. " );
+       // retrieve the layers
+       std::pair< EventIDRange, std::vector<const Trk::Layer*> > centralLayersPair  = lProvider->centralLayers(ctx);
+       std::pair< EventIDRange, std::vector<const Trk::Layer*> > negativeLayersPair = lProvider->negativeLayers(ctx);
+       std::pair< EventIDRange, std::vector<const Trk::Layer*> > positiveLayersPair = lProvider->positiveLayers(ctx);
+       range=EventIDRange::intersect(range,centralLayersPair.first, negativeLayersPair.first, positiveLayersPair.first);
+       ATH_MSG_VERBOSE("       -> retrieved "  << centralLayersPair.second.size()  << " central layers.");
+       ATH_MSG_VERBOSE("       -> retrieved "  << negativeLayersPair.second.size() << " layers on negative side.");
+       ATH_MSG_VERBOSE("       -> retrieved "  << positiveLayersPair.second.size() << " layers on positive side.");
+       // getting the Layer setup from parsing the builder output
+       InDet::LayerSetup lSetup = estimateLayerSetup(lProvider->identification(), ilS, 
+                                                     negativeLayersPair.second,centralLayersPair.second,positiveLayersPair.second,
+                                                     envelopeVolumeRadius, envelopeVolumeHalfZ);
+       // get the maxima - for R and Z
+       takeBigger(maximumLayerRadius, lSetup.rMax);
+       takeBigger(maximumLayerExtendZ, lSetup.zMax);
+       //layer setups for the second run
+       layerSetups.push_back(lSetup);
+       // increase counter
+       ++ilS;
+   }       
+   ATH_MSG_VERBOSE("       -> layer max R/Z defined as : " << maximumLayerRadius << " / " << maximumLayerExtendZ );
+   
+   // create a volume cache for:
+   // - ID volume, i.e. those that can be stacked into the overall container
+   std::vector<const Trk::TrackingVolume*> idVolumes;
+   
+   // create a layer setup cache for flushing when necessary
+   std::vector<InDet::LayerSetup> layerSetupCache;
+   
+   // we only need to take care of the last flush radius
+   double lastFlushRadius = 0.;
+   
+   // (I) PARSE THE LAYERS FOR OVERALL DIMENSIONS -------------------------------------------------------------
+   ATH_MSG_DEBUG( "[ STEP 2 ] : Looping through the layer setups and flush them into the ID detector volume vector." );
+   for ( auto& lSetup : layerSetups){
+        // screen output
+        ATH_MSG_DEBUG( "[ Layer setup: '" << lSetup.identification << "' ] being processed, current cache size is " << layerSetupCache.size() );
+        ATH_MSG_VERBOSE("       -> estimated dimensions for this layer setup are");
+        ATH_MSG_VERBOSE("       -> central sector rMin / rMax / zMax : " 
+            << lSetup.minRadiusCenter << " / " << lSetup.maxRadiusCenter << " / " << lSetup.zExtendCenter);
+        if (lSetup.buildEndcap)                                                                                                
+           ATH_MSG_VERBOSE("       -> endcap  sector rMin / rMax / zMin / zMax : " 
+               << lSetup.minRadiusEndcap << " / " << lSetup.maxRadiusEndcap << " / " << lSetup.minZextendEndcap << " / " << lSetup.maxZextendEndcap);
+        else 
+           ATH_MSG_VERBOSE("       -> endcap is not being built.");
+        
+        // now check what is in the cache 
+           // [a] nothing in the cache or new setup is compatible (in this case sectorZ are updated in all setups)
+        if (!layerSetupCache.size() || setupFitsCache(lSetup,layerSetupCache) ){
+            ATH_MSG_VERBOSE("       -> cache is empty or new sector fits cache setup - add this one to the cache.");
+        } else {
+            // [b] cache is not empty - let's see what is going on:
+            ATH_MSG_VERBOSE("       -> new sector does not fit the current cache specs -> flushing the cache." );
+            // create the outer boundary
+            double flushRadius = 0.5*(layerSetupCache[layerSetupCache.size()-1].rMax + lSetup.rMin);
+            // create a flush volume - clears the cache
+            const Trk::TrackingVolume* fVolume = createFlushVolume(layerSetupCache,lastFlushRadius,flushRadius,maximumLayerExtendZ);
+            // stuff it into the idVolume
+            idVolumes.push_back(fVolume);
+            // remember the last flush radius                                                                                    
+            lastFlushRadius = flushRadius; 
+        }
+        // in any case, this setup needs to go into the cache
+        layerSetupCache.push_back(lSetup);
+   }
+   
+   // check if the cache is empty
+   if (layerSetupCache.size()){
+       ATH_MSG_DEBUG( "[ STEP 3 ] : Flush the remaining cache into the ID detector volume vector." );
+       // set the maximum radius to the last layer radius    
+       double flushRadius = 0.5*(maximumLayerRadius  + envelopeVolumeRadius);
+       const Trk::TrackingVolume* fVolume = createFlushVolume(layerSetupCache,lastFlushRadius,flushRadius,maximumLayerExtendZ);
+       // push it into the vector
+       idVolumes.push_back(fVolume);
+       lastFlushRadius = flushRadius;
+   }
+   
+   ATH_MSG_DEBUG( "[ STEP 4 ] : Create the ID detector volumes" );
+   // build the central enclosure first
+   const Trk::TrackingVolume* centralEnclosure =  m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                           lastFlushRadius, envelopeVolumeRadius,
+                                                                           -maximumLayerExtendZ, maximumLayerExtendZ,
+                                                                           1, true,
+                                                                           m_namespace+"Gaps::CentralEnclosure");
+   idVolumes.push_back(centralEnclosure);
+   // now lets create the container
+   std::string volumeName = m_namespace+"Detectors::Container";
+   const Trk::TrackingVolume* idContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(idVolumes,
+                                                                *m_materialProperties,
+                                                                volumeName,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+   // finally create the two endplates: negative
+   const Trk::TrackingVolume* negativeEnclosure =  m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                                                   0., envelopeVolumeRadius,
+                                                                                                   -envelopeVolumeHalfZ, -maximumLayerExtendZ,
+                                                                                                   1, false,
+                                                                                                   m_namespace+"Gaps::NegativeEnclosure");
+  
+   // finally create the two endplates: positive
+   const Trk::TrackingVolume* positiveEnclosure =  m_trackingVolumeCreator->createGapTrackingVolume(*m_materialProperties,
+                                                                                                   0., envelopeVolumeRadius,
+                                                                                                   maximumLayerExtendZ,envelopeVolumeHalfZ,
+                                                                                                   1, false,
+                                                                                                   m_namespace+"Gaps::PositiveEnclosure");
+   // and the final tracking volume
+   std::vector<const Trk::TrackingVolume*> enclosedVolumes;
+   enclosedVolumes.push_back(negativeEnclosure);
+   enclosedVolumes.push_back(idContainer);
+   enclosedVolumes.push_back(positiveEnclosure);
+   
+   const Trk::TrackingVolume* enclosedDetector = 
+       m_trackingVolumeCreator->createContainerTrackingVolume(enclosedVolumes,
+                                                              *m_materialProperties,
+                                                               m_exitVolume,
+                                                               m_buildBoundaryLayers,
+                                                               m_replaceJointBoundaries);
+
+   //  create the TrackingGeometry ------------------------------------------------------  
+   trackingGeometry = new Trk::TrackingGeometry(enclosedDetector);
+   
+   if (m_indexStaticLayers) {
+      ATH_MSG_VERBOSE("Re-index the static layers ...");
+      trackingGeometry->indexStaticLayers(Trk::Global);   
+   }                       
+
+   return std::make_pair(range, trackingGeometry);
+}
+
+// finalize
+StatusCode InDet::StagedTrackingGeometryBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::packVolumeTriple(const InDet::LayerSetup& layerSetup,
+                                                                                  double rMin, double& rMax,
+                                                                                  double zMax, double zPosCentral) const
+{
+
+
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Layers from '" << layerSetup.identification << "' triple into a container volume. " );
+  
+  // create the strings
+  std::string volumeBase = m_namespace+"Detectors::"+layerSetup.identification;
+  
+  const Trk::TrackingVolume* negativeVolume = createTrackingVolume(layerSetup.negativeLayers, 
+                                                                   rMin,rMax,
+                                                                   -zMax,-zPosCentral,
+                                                                   volumeBase+"::NegativeEndcap",
+                                                                   (Trk::BinningType)layerSetup.binningEndcap,
+								   false);
+
+  const Trk::TrackingVolume* centralVolume = 
+         m_trackingVolumeCreator->createTrackingVolume(layerSetup.centralLayers,
+                                                       *m_materialProperties,
+                                                       rMin,rMax,
+                                                       -zPosCentral,zPosCentral,
+                                                       volumeBase+"::Barrel",
+                                                       (Trk::BinningType)layerSetup.binningCenter);
+                                                       
+   const Trk::TrackingVolume* positiveVolume = createTrackingVolume(layerSetup.positiveLayers,
+                                                                    rMin,rMax,
+                                                                    zPosCentral,zMax,
+                                                                    volumeBase+"::PositiveEndcap",
+                                                                    (Trk::BinningType)layerSetup.binningEndcap,
+								    false);
+   
+   // the base volumes have been created
+   ATH_MSG_VERBOSE('\t' << '\t'<< "Volumes have been created, now pack them into a triple.");
+   // registerColorCode                                                   
+   negativeVolume->registerColorCode(layerSetup.colorCode);   
+   centralVolume->registerColorCode(layerSetup.colorCode);
+   positiveVolume->registerColorCode(layerSetup.colorCode);
+                                                         
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   tripleVolumes.push_back(negativeVolume);
+   tripleVolumes.push_back(centralVolume);
+   tripleVolumes.push_back(positiveVolume);
+   
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+                                                                
+   ATH_MSG_VERBOSE( '\t' << '\t'<< "Created container volume with bounds: " << tripleContainer->volumeBounds() );
+                                                                
+   return tripleContainer;
+}
+
+
+/** Private helper method, estimates the overal dimensions */
+InDet::LayerSetup InDet::StagedTrackingGeometryBuilderCond::estimateLayerSetup(const std::string& idName, size_t ilS,
+                                                                           const std::vector<const Trk::Layer*>& negLayers,
+                                                                           const std::vector<const Trk::Layer*>& cenLayers,
+                                                                           const std::vector<const Trk::Layer*>& posLayers,
+                                                                           double maxR, double maxZ) const
+{  
+  // prepare the dimensions
+  double cenMinR  = 10e10;
+  double cenMaxR  = 0.;
+  double cenMinZ  = 10e10;
+  double cenMaxZ  = 0.;
+  double posMinR  = 10e10;
+  double posMaxR  = 0.;
+  double posMinZ  = 10e10;
+  double posMaxZ  = 0.;
+  // parse through the central layers first
+  estimateLayerDimensions(cenLayers, cenMinR, cenMaxR, cenMinZ, cenMaxZ);
+  // parse throught the positive layers - we assume a symmetric setup 
+  estimateLayerDimensions(posLayers, posMinR, posMaxR, posMinZ, posMaxZ);
+  // reset to maxZ and and maxR if overs
+  if (posMaxZ > maxZ) {
+      ATH_MSG_WARNING("Estimated z extended of central sector bigger than maximal z extened. Resetting - may lose layers though.");
+      cenMaxZ = maxZ;
+  } else if (posMaxZ > maxZ) {
+      ATH_MSG_WARNING("Estimated z extended of endcap sector bigger than maximal z extened. Resetting - may lose layers though.");
+      posMaxZ = maxZ;
+  }
+  // reset the radial wones.
+  if (cenMaxR > maxR) {
+      ATH_MSG_WARNING("Estimated r extended of central sector bigger than maximal r extened. Resetting - may lose layers though.");
+      cenMaxR = maxR;
+  }
+  if (posMaxR > maxR) {
+      ATH_MSG_WARNING("Estimated r extended of endcap sector bigger than maximal r extened. Resetting - may lose layers though.");
+      posMaxR = maxR;
+  }
+  // create the layer setup class  
+  return InDet::LayerSetup(idName, m_colorCodesConfig[ilS], 
+                           negLayers, cenLayers, posLayers,
+                           cenMinR, cenMaxR, cenMaxZ, m_layerBinningTypeCenter[ilS], 
+                           posLayers.size(), posMinR, posMaxR, posMinZ, posMaxZ, m_layerBinningTypeEndcap[ilS]);
+}
+
+
+/** Private helper method to estimate the layer dimensions */
+void InDet::StagedTrackingGeometryBuilderCond::estimateLayerDimensions(const std::vector<const Trk::Layer*>& layers,
+                                                                   double& rMin, double& rMax, double& zMin, double& zMax) const
+{
+    // parse through the layers and estimate
+      for (auto& layer : layers){
+          // the thickness of the layer needs to be taken into account 
+          double thickness = layer->thickness();
+          // get the center
+          const Amg::Vector3D& center = layer->surfaceRepresentation().center();
+          // check if it is a cylinder layer
+          const Trk::CylinderLayer* cLayer = dynamic_cast<const Trk::CylinderLayer*>(layer);
+          if (cLayer){
+              // now we have access to all the information
+              double rMinC  = cLayer->surfaceRepresentation().bounds().r()-0.5*thickness-m_layerEnvelopeCover;
+              double rMaxC  = cLayer->surfaceRepresentation().bounds().r()+0.5*thickness+m_layerEnvelopeCover;
+              double hZ = cLayer->surfaceRepresentation().bounds().halflengthZ();
+              takeSmaller(rMin,rMinC);
+              takeBigger(rMax,rMaxC);
+              takeSmaller(zMin,center.z()-hZ);
+              takeBigger(zMax,center.z()+hZ);
+          } 
+          // proceed further if it is a Disc layer
+          const Trk::DiscBounds* dBounds = dynamic_cast<const Trk::DiscBounds*>(&(layer->surfaceRepresentation().bounds()));
+          if (dBounds){
+              // now we have access to all the information
+              double rMinD =dBounds->rMin();
+              double rMaxD =dBounds->rMax();
+              double zMinD =  center.z()-0.5*thickness-m_layerEnvelopeCover;
+              double zMaxD =  center.z()+0.5*thickness+m_layerEnvelopeCover;
+              takeSmaller(rMin,rMinD);
+              takeBigger(rMax,rMaxD);
+              takeSmaller(zMin,zMinD);
+              takeBigger(zMax,zMaxD);
+          }
+      }
+}  
+ 
+
+/** Private helper method to check if a sector is compatible with the cache */
+bool InDet::StagedTrackingGeometryBuilderCond::setupFitsCache(LayerSetup& layerSetup, std::vector<InDet::LayerSetup>& layerSetupCache) const
+{
+    // the maximum center and overall extend of the cache
+    double maxCenterCacheZ = 0.; 
+    // the maximum endcap extend of the cache
+    double minEndcapCacheZ = 10e10;
+    // chech if he have a fullSectorSetup
+    bool fullSectorSetup   = false;
+    // 
+    for (auto& lCacheSetup : layerSetupCache){
+        takeBigger(maxCenterCacheZ, lCacheSetup.zExtendCenter);
+        takeSmaller(minEndcapCacheZ, lCacheSetup.minZextendEndcap);
+        // once true always true - otherwise it would have been flushed
+        fullSectorSetup = lCacheSetup.buildEndcap ? true : fullSectorSetup;
+        
+    }    
+    // if we do not have a full sector setup - > flush directly
+    if (!fullSectorSetup) {
+        ATH_MSG_VERBOSE("       -> only central sector being built, flush the cache ... ");
+        return false;
+    }
+    // if the cached minimum z endcap z extend cuts within the new barrel -> flush it 
+    if (minEndcapCacheZ < layerSetup.zExtendCenter){
+        ATH_MSG_VERBOSE("       -> cache endcap extend reaches into new central sector, flush the cache ... ");
+        return false;
+    }
+    // the cache center maximumg exceeds the new endcap minimum -> does not fit
+    if (maxCenterCacheZ < layerSetup.minZextendEndcap ) {
+        ATH_MSG_VERBOSE("       -> sector fully fits into cache! Add it and start synchronising ...");
+        // calculate the new sector gap and synchronise
+        double newCenterMaxZ = maxCenterCacheZ > layerSetup.zExtendCenter ? maxCenterCacheZ : layerSetup.zExtendCenter;
+        double newEndcapMinZ = minEndcapCacheZ < layerSetup.minZextendEndcap ? minEndcapCacheZ : layerSetup.minZextendEndcap;
+        double newSectorZ    = 0.5*(newCenterMaxZ+newEndcapMinZ);
+        // and syncrhonise the boundaries 
+        for (auto& lCacheSetup : layerSetupCache)
+            lCacheSetup.zSector = newSectorZ;
+        layerSetup.zSector = newSectorZ;
+        return true;
+    }
+    // it simply does not fit so return false
+    return false;
+}
+ 
+bool InDet::StagedTrackingGeometryBuilderCond::ringLayout(const std::vector<const Trk::Layer*>& layers, std::vector<double>& rmins, std::vector<double>& rmaxs) const {
+    // get the maximum extent in z
+    ATH_MSG_INFO("Checking for Ring layout ... ");
+    for (auto& ring : layers){
+        // Surface
+        const Trk::Surface&     ringSurface = ring->surfaceRepresentation(); 
+        const Trk::DiscBounds*  ringBounds  = dynamic_cast<const Trk::DiscBounds*>(&(ringSurface.bounds()));
+        if (ringBounds){
+            // get the main parameters
+            double zpos         = ringSurface.center().z();
+            double rMin         = ringBounds->rMin();
+            double rMax         = ringBounds->rMax();
+            // take and check
+            checkForInsert(rmins,rMin);
+            checkForInsert(rmaxs,rMax);
+            ATH_MSG_INFO(" -> Ring at z-position " << zpos << " - with rMin/rMax = " << rMin << "/" << rMax );
+        }
+    }
+    return (rmins.size() > 1 );
+}                                              
+ 
+ 
+
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::createTrackingVolume(const std::vector<const Trk::Layer*>& layers, 
+                                                                                      double innerRadius, double& outerRadius,
+                                                                                      double zMin, double zMax,
+                                                                                      const std::string& volumeName,
+                                                                                      Trk::BinningType binningType,
+										       bool doAdjustOuterRadius) const
+{
+
+    // first loop - this is for diagnostics for the radii 
+    std::vector<double> ringRmins;
+    std::vector<double> ringRmaxa;
+    if (m_checkForRingLayout && ringLayout(layers,ringRmins, ringRmaxa)){
+        ATH_MSG_INFO("Ring layout is present for volume '" << volumeName << "' dealing with it.");
+        // create the vector for the sub volumes
+        std::vector<const Trk::TrackingVolume* > ringVolumes;
+
+        // now sort the necessary layers --- for the sub volumes
+        std::vector< std::vector< const Trk::Layer*> > groupedDiscs(ringRmins.size(), std::vector< const Trk::Layer*>() );
+        // second loop over the rings
+        for (auto& ring : layers){
+            // Surface
+            const Trk::Surface&     ringSurface = ring->surfaceRepresentation(); 
+            const Trk::DiscBounds*  ringBounds  = dynamic_cast<const Trk::DiscBounds*>(&(ringSurface.bounds()));
+            if (ringBounds){
+                // get the main parameters
+                double rMax         = ringBounds->rMax();
+                size_t rPos         = 0;
+                // fill into the right group
+                for (auto& rm : ringRmaxa){
+                    if (rMax < rm+m_ringTolerance) break;
+                    ++rPos;
+                }
+                // fill it it 
+                const Trk::DiscLayer* dring = dynamic_cast<const Trk::DiscLayer*>(ring);
+                if (dring) groupedDiscs[rPos].push_back(dring);
+            }
+        }
+        // we are now grouped in cylinder rings per volume
+        for (int idset = 0; idset < int(groupedDiscs.size()); idset++){
+            // always keep the boundaries in mind for the radial extend
+            double crmin = idset ? ringRmaxa[idset-1]+m_layerEnvelopeCover : innerRadius;
+            double crmax = ringRmaxa[idset]+m_layerEnvelopeCover;
+	    if(idset==int(groupedDiscs.size())-1 && !doAdjustOuterRadius) crmax = outerRadius; 
+            // now create the sub volume
+            std::string ringVolumeName = volumeName+"Ring"+boost::lexical_cast<std::string>(idset);
+            const Trk::TrackingVolume* ringVolume = m_trackingVolumeCreator->createTrackingVolume(groupedDiscs[idset],
+                                                                                                  *m_materialProperties,
+                                                                                                  crmin,crmax,
+                                                                                                  zMin,zMax,
+                                                                                                  ringVolumeName,
+                                                                                                  binningType);
+             // push back into the 
+             ringVolumes.push_back(ringVolume);
+        }
+        // set the outer radius
+        if(doAdjustOuterRadius) outerRadius = ringRmaxa[ringRmaxa.size()-1]+m_layerEnvelopeCover;
+        //
+        ATH_MSG_INFO("      -> adjusting the outer radius to the last ring at " << outerRadius );
+        ATH_MSG_INFO("      -> created " << ringVolumes.size() << " ring volumes for Volume '" << volumeName << "'.");
+        // create the tiple container
+        return m_trackingVolumeCreator->createContainerTrackingVolume(ringVolumes,
+                                                                      *m_materialProperties,
+                                                                      volumeName,
+                                                                      m_buildBoundaryLayers,
+                                                                      m_replaceJointBoundaries);
+        
+        
+    } else 
+        return m_trackingVolumeCreator->createTrackingVolume(layers,
+                                                             *m_materialProperties,
+                                                             innerRadius,outerRadius,
+                                                             zMin,zMax,
+                                                             volumeName,
+                                                             binningType);
+}     
+ 
+                             
+/** Private helper method to flush the cache into the id volumes - return volume is the one to be provided */
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::createFlushVolume(std::vector<InDet::LayerSetup>& layerSetupCache,
+                                                                                   double innerRadius, double& outerRadius, double extendZ) const
+{
+  // the return volume 
+  const Trk::TrackingVolume* flushVolume = 0;
+  // 
+  if (layerSetupCache.size() == 1 ){
+    ATH_MSG_VERBOSE("       -> single sector setup - synchronising from inner (" << innerRadius << ") to outer (" << outerRadius << ") radius.");
+    ATH_MSG_VERBOSE("       -> setup identification : " << layerSetupCache[0].identification );
+    // create the new tracking volume - either as a triple or as a single
+        flushVolume = layerSetupCache[0].buildEndcap ? 
+        packVolumeTriple(layerSetupCache[0],
+                         innerRadius, outerRadius,
+                         extendZ,layerSetupCache[0].zSector) :
+        m_trackingVolumeCreator->createTrackingVolume(layerSetupCache[0].centralLayers,
+                                                      *m_materialProperties,
+                                                      innerRadius,outerRadius,
+                                                      -extendZ,extendZ,
+                                                      layerSetupCache[0].identification,
+                                                      (Trk::BinningType)layerSetupCache[0].binningCenter);    
+    
+   } else {
+       ATH_MSG_VERBOSE("       -> setup with " << layerSetupCache.size() << " entries - synchronising from inner (" << innerRadius << ") to outer (" << outerRadius << ") radius.");
+       // prepare the volume vectors & name identification
+       std::vector<const Trk::TrackingVolume*> negVolumes;
+       std::vector<const Trk::TrackingVolume*> centralVolumes;
+       std::vector<const Trk::TrackingVolume*> posVolumes;
+       std::string combinedName;
+       for (size_t ilS = 0; ilS < layerSetupCache.size(); ++ilS){
+           // take the given inner radius for the first one - median otherwise
+           double irE = ilS ? 0.5*(layerSetupCache[ilS].minRadiusEndcap+layerSetupCache[ilS-1].maxRadiusEndcap) : innerRadius;
+           double irC = ilS ? 0.5*(layerSetupCache[ilS].minRadiusCenter+layerSetupCache[ilS-1].maxRadiusCenter) : innerRadius;
+           // take the given outer radius for the last one - median otherwise
+           double orE = ((ilS+1)==layerSetupCache.size()) ? outerRadius : 0.5*(layerSetupCache[ilS+1].minRadiusEndcap+layerSetupCache[ilS].maxRadiusEndcap);
+           double orC = ((ilS+1)==layerSetupCache.size()) ? outerRadius : 0.5*(layerSetupCache[ilS+1].minRadiusCenter+layerSetupCache[ilS].maxRadiusCenter);
+	   // Adjust last volumes in R to the same maximal radial extends!
+	   if(ilS==layerSetupCache.size()-1) {
+	     ATH_MSG_VERBOSE("Processing last volume");
+	     ATH_MSG_VERBOSE("  --> adjust volumes to same extends: orE=" << orE << " orC=" << orC);
+	     if(orE>orC) orC=orE; else orE=orC;
+	   }
+           // create the three volumes
+           const Trk::TrackingVolume* nVolume = createTrackingVolume(layerSetupCache[ilS].negativeLayers,
+                                                                     irE,orE,
+                                                                     -extendZ,-layerSetupCache[ilS].zSector,
+                                                                     layerSetupCache[ilS].identification+"::NegativeEndcap",
+                                                                     (Trk::BinningType)layerSetupCache[ilS].binningEndcap,false);               
+           const Trk::TrackingVolume* cVolume = m_trackingVolumeCreator->createTrackingVolume(layerSetupCache[ilS].centralLayers,
+                                                                                  *m_materialProperties,
+                                                                                  irC,orC,
+                                                                                  -layerSetupCache[ilS].zSector,layerSetupCache[ilS].zSector,
+                                                                                  layerSetupCache[ilS].identification+"::Barrel",
+                                                                                  (Trk::BinningType)layerSetupCache[ilS].binningCenter);
+           const Trk::TrackingVolume* pVolume = createTrackingVolume(layerSetupCache[ilS].positiveLayers,
+                                                                     irE,orE,
+                                                                     layerSetupCache[ilS].zSector,extendZ,
+                                                                     layerSetupCache[ilS].identification+"::PositiveEndcap",
+                                                                     (Trk::BinningType)layerSetupCache[ilS].binningEndcap,false);
+           // register the right color code
+           nVolume->registerColorCode(layerSetupCache[ilS].colorCode);
+           cVolume->registerColorCode(layerSetupCache[ilS].colorCode);
+           pVolume->registerColorCode(layerSetupCache[ilS].colorCode);
+           // push them into the volume containers 
+           negVolumes.push_back(nVolume);
+           centralVolumes.push_back(cVolume);
+           posVolumes.push_back(pVolume);
+           // combined name
+           combinedName += "_"+layerSetupCache[ilS].identification;
+       }
+       ATH_MSG_VERBOSE("       -> setup identification : " << combinedName );
+       flushVolume  = packVolumeTriple(negVolumes,centralVolumes,posVolumes,combinedName);
+   }
+   // clear the cache
+   layerSetupCache.clear();      
+   // return the volume               
+   return flushVolume;
+    
+}  
+
+const Trk::TrackingVolume* InDet::StagedTrackingGeometryBuilderCond::packVolumeTriple(
+                                     const std::vector<const Trk::TrackingVolume*>& negVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& centralVolumes,
+                                     const std::vector<const Trk::TrackingVolume*>& posVolumes,
+                                     const std::string& baseName) const
+{
+  ATH_MSG_VERBOSE( '\t' << '\t'<< "Pack provided Volumes from '" << baseName << "' triple into a container volume. " );
+
+  unsigned int negVolSize = negVolumes.size();
+  unsigned int cenVolSize = centralVolumes.size();
+  unsigned int posVolSize = posVolumes.size();
+  
+  
+  
+    // create the strings
+  std::string volumeBase = m_namespace+"Containers::"+baseName;
+  
+  const Trk::TrackingVolume* negativeVolume = (negVolSize > 1) ?
+       m_trackingVolumeCreator->createContainerTrackingVolume(negVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::NegativeSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                             (negVolSize ? negVolumes[0] : 0);
+  const Trk::TrackingVolume* centralVolume = (cenVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(centralVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::CentralSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) :
+                                              (cenVolSize ? centralVolumes[0] : 0) ;
+                                              
+   const Trk::TrackingVolume* positiveVolume = ( posVolSize > 1) ?
+         m_trackingVolumeCreator->createContainerTrackingVolume(posVolumes,
+                                                       *m_materialProperties,
+                                                       volumeBase+"::PositiveSector",
+                                                       m_buildBoundaryLayers,
+                                                       m_replaceJointBoundaries) : 
+                                               (posVolSize ? posVolumes[0] : 0);
+   
+   if (!negativeVolume && !positiveVolume){
+       ATH_MSG_DEBUG( "No negative/positive sector given - no packing needed, returning central container!" );
+       return centralVolume;
+   }
+   // pack them together
+   std::vector<const Trk::TrackingVolume*> tripleVolumes;
+   if (negativeVolume) tripleVolumes.push_back(negativeVolume);
+   if (centralVolume) tripleVolumes.push_back(centralVolume);
+   if (positiveVolume) tripleVolumes.push_back(positiveVolume);
+   // create the tiple container
+   const Trk::TrackingVolume* tripleContainer = 
+         m_trackingVolumeCreator->createContainerTrackingVolume(tripleVolumes,
+                                                                *m_materialProperties,
+                                                                volumeBase,
+                                                                m_buildBoundaryLayers,
+                                                                m_replaceJointBoundaries);
+   return tripleContainer;
+}
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/TRT_LayerBuilderCond.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/TRT_LayerBuilderCond.cxx
new file mode 100755
index 00000000000..90ac1dc3137
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/TRT_LayerBuilderCond.cxx
@@ -0,0 +1,729 @@
+/*
+ Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// TRT_LayerBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#include "InDetTrackingGeometry/TRT_LayerBuilderCond.h"
+#include "InDetTrackingGeometry/TRT_OverlapDescriptor.h"
+//Trk
+#include "TrkSurfaces/Surface.h"
+#include "TrkSurfaces/RectangleBounds.h"
+#include "TrkSurfaces/DiscBounds.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/PlaneLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+#include "TrkGeometry/BinnedLayerMaterial.h"
+#include "TrkGeometry/ApproachDescriptor.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkDetDescrUtils/BinnedArrayArray.h"
+#include "TrkDetDescrUtils/BinnedArray2D.h"
+#include "TrkDetDescrUtils/BinnedArray1D.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/BinUtility.h"
+// GeoPrimitives
+#include "GeoPrimitives/GeoPrimitivesHelpers.h"
+#include "GeoPrimitives/GeoPrimitivesToStringConverter.h"
+// InDetDD
+#include "TRT_ReadoutGeometry/TRT_DetectorManager.h"
+#include "TRT_ReadoutGeometry/TRT_Numerology.h"
+#include "InDetIdentifier/TRT_ID.h"
+// Gaudi
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/SmartDataPtr.h"
+#include "GaudiKernel/SystemOfUnits.h"
+// STL
+#include <map>
+
+namespace {
+  template <class T>
+  class PtrVectorWrapper 
+  {
+  public:
+    PtrVectorWrapper () 
+      : m_ptr(new std::vector<const T *>)
+    {
+    }
+    
+    ~PtrVectorWrapper() {
+      if (m_ptr) {
+	for (const T *elm : *m_ptr ) {
+	  delete elm;
+	}
+	m_ptr->clear();
+      }
+    }
+    std::vector<const T *> &operator*() { return *m_ptr; }
+    const std::vector<const T *> &operator*() const { return *m_ptr; }
+    
+    std::vector<const T *> *operator->() { return m_ptr.get(); }
+    const std::vector<const T *> *operator->() const { return m_ptr.get(); }
+    
+    std::vector<const T *> *release() { return m_ptr.release(); }
+    
+  private:
+    std::unique_ptr<std::vector<const T *> > m_ptr;
+  };
+  
+}
+
+// constructor
+InDet::TRT_LayerBuilderCond::TRT_LayerBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_trtMgr(0),
+  m_trtMgrLocation("TRT"),
+  m_layerStrawRadius(2.0*Gaudi::Units::mm),
+  m_layerThickness(0.1*Gaudi::Units::mm),
+  m_modelGeometry(true),
+  m_modelBarrelLayers(7),
+  m_modelEndcapLayers(14),
+  m_barrelLayerBinsZ(25),
+  m_barrelLayerBinsPhi(1),
+  m_endcapLayerBinsR(25),
+  m_endcapLayerBinsPhi(1),
+  m_endcapConly(false),
+  m_registerStraws(false),
+  m_barrelSectorAtPiBoundary(16),
+  m_identification("TRT")
+{
+  declareInterface<Trk::ILayerBuilderCond>(this);
+  // properties from outside
+  declareProperty("TRT_DetManagerLocation",       m_trtMgrLocation);
+  declareProperty("LayerThickness",               m_layerThickness);
+  // material binning
+  declareProperty("BarrelLayerBinsZ"            , m_barrelLayerBinsZ);
+  declareProperty("BarrelLayerBinsPhi"          , m_barrelLayerBinsPhi);
+  declareProperty("EndcapLayerBinsR"            , m_endcapLayerBinsR);
+  declareProperty("EndcapLayerBinsPhi"          , m_endcapLayerBinsPhi);
+  // steering
+  declareProperty("ModelLayersOnly",              m_modelGeometry);
+  declareProperty("ModelBarrelLayers",            m_modelBarrelLayers);
+  declareProperty("ModelEndcapLayers",            m_modelEndcapLayers);
+  declareProperty("EndcapConly",                  m_endcapConly);
+  declareProperty("RegisterStraws",               m_registerStraws);
+  declareProperty("BarrelSectorAtPi",             m_barrelSectorAtPiBoundary);
+  // identification
+  declareProperty("Identification"              , m_identification);
+}
+
+// destructor
+InDet::TRT_LayerBuilderCond::~TRT_LayerBuilderCond()
+{}
+
+// Athena standard methods
+// initialize
+StatusCode InDet::TRT_LayerBuilderCond::initialize()
+{
+   ATH_MSG_INFO( "initialize()" );
+   // get TRT Detector Description Manager
+   if ((detStore()->retrieve(m_trtMgr, m_trtMgrLocation)).isFailure())
+     ATH_MSG_ERROR( "Could not get TRT_DetectorManager, no layers for TRT Detector will be built. " );
+
+   return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode InDet::TRT_LayerBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful" );
+
+    return StatusCode::SUCCESS;
+}
+
+
+/** LayerBuilderCond interface method - returning Barrel-like layers */
+//FIXME: context object is unused, elements are retrieved from m_trtMgr instead of CondSvc
+std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* > InDet::TRT_LayerBuilderCond::cylindricalLayers(const EventContext&) const
+{
+
+  //create dummy infinite range
+  EventIDRange range;
+  if (!m_trtMgr) return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+
+  ATH_MSG_DEBUG( "Building cylindrical layers for the TRT " );
+
+  PtrVectorWrapper<Trk::CylinderLayer> barrelLayers;
+
+  // get Numerology and Id HElper
+  const InDetDD::TRT_Numerology* trtNums = m_trtMgr->getNumerology();
+
+  // get the TRT ID Helper
+  const TRT_ID* trtIdHelper = 0;
+  if (detStore()->retrieve(trtIdHelper, "TRT_ID").isFailure()) {
+     ATH_MSG_ERROR("Could not get TRT ID helper");
+     return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+  }
+
+  int    nBarrelRings  = trtNums->getNBarrelRings();
+  int    nBarrelPhiSectors = trtNums->getNBarrelPhi();
+  double layerPhiStep      = 2*M_PI/nBarrelPhiSectors;
+  
+  int nTotalBarrelLayers = 0;
+
+  // get the overall dimensions
+  double rMin = 10e10;
+  double rMax = 0.;
+
+  double layerZmax = 0.;
+  double layerZmin = 10e10;
+
+  // pre-loop for overall layer numbers & some ordering ---------------------------------------
+  for (int ring=0; ring < nBarrelRings; ring++) {
+     // the number of barrel layers 
+     int nBarrelLayers = trtNums->getNBarrelLayers(ring);
+     nTotalBarrelLayers += nBarrelLayers;
+     // loop over layers
+      for (int layer=0; layer < nBarrelLayers; layer++){
+       for (int phisec=0; phisec <nBarrelPhiSectors; ++phisec)
+       {
+         for (int iposneg=0; iposneg<2; ++iposneg){
+            // get the element
+            const InDetDD::TRT_BarrelElement* trtbar = m_trtMgr->getBarrelElement(iposneg, ring, phisec, layer);
+            
+            // get overall dimensions only one time
+            const Trk::PlaneSurface*    elementSurface = dynamic_cast<const Trk::PlaneSurface*>(&(trtbar->surface()));
+            if (!elementSurface) {
+                ATH_MSG_WARNING( "elementSurface: dynamic_cast to Trk::PlaneSurface failed - skipping ... ring/layer/phisec/iposneg = " << ring << "/" << layer << "/" << phisec << "/" << iposneg );
+                continue;
+            }
+            const Trk::RectangleBounds* elementBounds  = dynamic_cast<const Trk::RectangleBounds*>(&(trtbar->bounds()));
+            if (!elementBounds) {
+                ATH_MSG_WARNING( "elementBounds: dynamic_cast to Trk::RectangleBounds failed - skipping ... ring/layer/phisec/iposneg = " << ring << "/" << layer << "/" << phisec << "/" << iposneg );
+                continue;
+            }
+            double elementZcenter = (elementSurface->center()).z();
+            double elementZmin    = fabs(elementZcenter - elementBounds->halflengthY());
+            double elementZmax    = fabs(elementZcenter + elementBounds->halflengthY());
+            // take what you need
+            takeSmaller(layerZmin, elementZmin); takeBigger(layerZmax, elementZmax);
+            // get the radial dimensions
+            double currentR = trtbar->center().perp();
+            takeSmallerBigger(rMin,rMax,currentR);
+         }
+       }
+    }
+  }
+  
+  if (nTotalBarrelLayers==0) {
+      ATH_MSG_WARNING( "nTotalBarrelLayers = 0 ... aborting and returning 0 !" );
+      return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+  }
+  
+  // calculate delta(R) steps and delta(R)
+  double rDiff           = fabs(rMax-rMin);
+  double rStep           = rDiff/(m_modelBarrelLayers+1);
+  double layerHalflength = layerZmax;
+
+  // prepare the material
+  if ( fabs(rDiff) <= 0.1 ){
+    return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+  }
+
+  // ilay - for accessing the straw layers and for material decission
+  int ilay = 0;
+
+  //  fix the positions where the layers are - these are used for the model geometry and the complex geometry ---------------
+  std::vector<double> layerRadii;
+  layerRadii.reserve(m_modelBarrelLayers);
+  for (unsigned int ilay = 1; ilay <= m_modelBarrelLayers; ++ilay)
+       layerRadii.push_back(rMin+ilay*rStep-0.5*m_layerThickness);
+  // these are the layer iterators
+  auto layerRadiusIter    = layerRadii.begin();
+  auto layerRadiusIterEnd = layerRadii.end();
+
+  // (A) model geometry section
+  if (m_modelGeometry && !m_registerStraws){
+
+      ATH_MSG_VERBOSE( " -> " << layerRadii.size() << " cylindrical barrel layers between " << rMin << " and " << rMax << " ( at step "<< rStep << " )");
+
+     // create the layers
+     for ( ; layerRadiusIter != layerRadiusIterEnd; ++layerRadiusIter ) {
+       // ----- prepare the BinnedLayerMaterial -----------------------------------------------------
+       Trk::BinnedLayerMaterial* layerMaterial = 0;
+       // -- material with 1D binning
+       Trk::BinUtility layerBinUtility1DZ(m_barrelLayerBinsZ,-layerHalflength, layerHalflength, Trk::open, Trk::binZ);
+       if (m_barrelLayerBinsPhi==1){
+         // no binning in phi  
+         layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtility1DZ);
+       } else { // -- material with 2D binning : Rphi*Z optimized for cylinder layer
+         Trk::BinUtility layerBinUtility2DRPhiZ(m_barrelLayerBinsPhi,
+                                                -(*layerRadiusIter)*M_PI,
+                                                (*layerRadiusIter)*M_PI,
+                                                Trk::closed,
+                                                Trk::binRPhi);
+         layerBinUtility2DRPhiZ += layerBinUtility1DZ;                                         
+         layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtility2DRPhiZ);
+       }
+       // Barrel layers are centered around (0,0,0) by definition
+       barrelLayers->push_back(new Trk::CylinderLayer(new Trk::CylinderBounds(*layerRadiusIter,layerHalflength),
+                                                      *layerMaterial,
+                                                      m_layerThickness));
+       ATH_MSG_VERBOSE( " --> Creating a layer at radius : " << *layerRadiusIter );
+       delete layerMaterial;
+     }
+  } else {
+    // (B) complex geometry section
+    
+    int nMaterialLayerStep  = int(nTotalBarrelLayers/m_modelBarrelLayers+1);
+    int cMaterialLayerCount = 0;
+    
+    // loop over rings
+    ATH_MSG_VERBOSE("TRT Barrel has " << nBarrelRings << " rings.");
+    
+    for (int ring=0; ring < nBarrelRings; ring++){
+        
+         int nBarrelLayers = trtNums->getNBarrelLayers(ring);
+         ATH_MSG_VERBOSE("-> Ring " << ring << " has " << nBarrelLayers << " barrel layers.");
+         // loop over layers
+         for (int layer=0; layer < nBarrelLayers; layer++){
+
+             // ----------------------------------------------------------------------------------
+              ATH_MSG_VERBOSE("--> Layer " << layer << " is being built with " << nBarrelPhiSectors << " secors in phi.");
+              ++cMaterialLayerCount;
+
+              // set layer dimensions radius
+              double layerRadius         =  0.;
+              double layerRadiusMin      =  10e10;
+              double layerRadiusMax      =  0.;
+              double layerPhiMin         =  10.;
+              double layerPhiMax         = -10;
+              
+              // per phi sector we make a 2D binnin in phi-z 
+              std::vector< std::pair<Trk::BinnedArray<Trk::Surface>*, Amg::Vector3D >  > layerSectorArrays;
+              Amg::Vector3D layerSectorPosition(0.,0.,0.);
+              
+              // the sector approaching surfaces
+              std::vector< std::pair< Trk::SharedObject<const Trk::ApproachSurfaces>, Amg::Vector3D > > layerApproachSurfaces; 
+
+              // layer sector arrays
+              for (int phisec=0; phisec < nBarrelPhiSectors; phisec++){
+                 // ----------------------------------------------------------------------------------
+                 ATH_MSG_VERBOSE("---> Sector " << phisec << " gahtering the details.");
+                 // -------------- a phi sector (expands in +/- z) -----------------------------------
+                 
+                 // order the straws onto layers
+                 std::vector< Trk::SurfaceOrderPosition > strawsPerPhiSecLayer;
+                 // get the min an max phi, the min and max z
+                 double phiMin       =  10.;
+                 double phiMax       = -10.;  
+                 // sector stuff
+                 int    sectorStraws = 0;
+                 // positive and negative sector      
+                 for (int posneg=0; posneg<2; ++posneg){
+                     // sort the elements
+                     const InDetDD::TRT_BarrelElement* currentElement = m_trtMgr->getBarrelElement(posneg, ring, phisec, layer);
+                     // get overall dimensions only one time
+                     const Trk::PlaneSurface*    elementSurface = dynamic_cast<const Trk::PlaneSurface*>(&(currentElement->surface()));
+                     if (!elementSurface) {
+                         ATH_MSG_WARNING( "elementSurface: dynamic_cast to Trk::PlaneSurface failed - skipping ... ring/layer/phisec/posneg = " << ring << "/" << layer << "/" << phisec << "/" << posneg );
+                         continue;
+                     }
+                     
+                     // create teh approach surfaces --------------------------------------------------------------------------------------------------
+                     // getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec )
+                     Trk::ApproachSurfaces* aSurfaces         = new Trk::ApproachSurfaces;
+                     const Amg::Transform3D& elementTransform = elementSurface->transform();
+                     const Amg::Vector3D&    elementCenter    = elementSurface->center();
+                     const Amg::Vector3D&    elementNormal    = elementSurface->normal();     
+                     Amg::RotationMatrix3D   elementRotation  = elementTransform.rotation();
+                     // outer / inner
+                     Amg::Vector3D outerCenter(elementCenter+(0.5*m_layerThickness+m_layerStrawRadius)*elementNormal);
+                     Amg::Vector3D innerCenter(elementCenter-(0.5*m_layerThickness+m_layerStrawRadius)*elementNormal);
+
+                     // assign the layer sector position for the straw array ordering
+                     layerSectorPosition = elementSurface->center();
+                             
+                     // now register the two surfaces
+                     aSurfaces->push_back(new Trk::PlaneSurface(new Amg::Transform3D(Amg::getTransformFromRotTransl(elementRotation, innerCenter))));
+                     aSurfaces->push_back(new Trk::PlaneSurface(new Amg::Transform3D(Amg::getTransformFromRotTransl(elementRotation, outerCenter))));
+                     
+                     // now register it to for building the array
+                     layerApproachSurfaces.push_back( std::pair< Trk::SharedObject<const Trk::ApproachSurfaces>, Amg::Vector3D >( Trk::SharedObject<const Trk::ApproachSurfaces>(aSurfaces),elementCenter));
+                     // screen output 
+                     ATH_MSG_VERBOSE("---> Sector " << phisec << " - posneg - " << posneg << " - with central phi = " << elementSurface->center().phi() );
+                     // sector phi centers
+                     takeSmallerBigger(layerPhiMin,layerPhiMax,elementSurface->center().phi());
+                     
+                     // loop over straws, fill them and find the phi boundaries
+                     for (unsigned int istraw=0; istraw<currentElement->nStraws(); ++istraw)
+                     {
+                       Identifier strawId = trtIdHelper->straw_id(currentElement->identify(), istraw);
+                       const Trk::Surface* currentStraw = &(currentElement->surface(strawId));
+                       // get the phi values 
+                       double currentPhi = currentStraw->center().phi();
+                       if (phisec == m_barrelSectorAtPiBoundary && currentPhi < 0.){
+                           currentPhi  = M_PI + currentPhi;
+                           currentPhi += M_PI;
+                       }
+                       // the layer radius 
+                       takeSmallerBigger(layerRadiusMin,layerRadiusMax,currentStraw->center().perp());
+                       takeSmallerBigger(phiMin, phiMax, currentPhi);
+                       // make the ordering position
+                       Amg::Vector3D strawOrderPos(currentStraw->center());
+                       //Trk::SharedObject<const Trk::Surface> sharedSurface(currentStraw, true);
+                       /*
+                        * The above line was using the nodel (not delete option for the old shared object
+                        * now that SharedObject is a shared_ptr typeded do the same with empty deleter
+                        */
+                       Trk::SharedObject<const Trk::Surface> sharedSurface(currentStraw, Trk::do_not_delete<const Trk::Surface>);
+                       strawsPerPhiSecLayer.push_back(Trk::SurfaceOrderPosition(sharedSurface, strawOrderPos));
+                       // and record
+                       ++sectorStraws;
+                     } // loop over straws done
+                 }  // loop over posneg done
+                 // show the phiMin/phiMax to the screen
+                 // prepare the 
+                 // fix to CID 24918
+                 if (!sectorStraws) {
+                   return std::pair<EventIDRange,const std::vector<const Trk::CylinderLayer* >* >(range,nullptr);
+                 }
+                 double deltaPhi  = (phiMax-phiMin);
+                 double phiStep   = deltaPhi/(0.5*sectorStraws-1);   
+                 ATH_MSG_VERBOSE("---> Sector " << phisec << " - with " << 0.5*sectorStraws << " straws - straw phiMin/phiMax (step) = " << phiMin << " / " << phiMax << " (" << phiStep << ")");
+                 // phi min / phi max 
+                 phiMin -= 0.5*phiStep;
+                 phiMax += 0.5*phiStep;
+                 // correct for the +pi/-pi module 
+                 // now create the BinUtility
+                 Trk::BinUtility* layerStrawPhiZUtility     = new Trk::BinUtility(sectorStraws/2,phiMin,phiMax,Trk::open, Trk::binPhi);
+                                 (*layerStrawPhiZUtility)  += Trk::BinUtility(2,-layerZmax, layerZmax, Trk::open, Trk::binZ);
+                 // create the 2D BinnedArray
+                 Trk::BinnedArray2D<Trk::Surface>* layerStrawPhiSector = new Trk::BinnedArray2D<Trk::Surface>(strawsPerPhiSecLayer,layerStrawPhiZUtility);
+                 ATH_MSG_VERBOSE("---> Sector " << phisec << " - BinnedArray for straws prepared for " << strawsPerPhiSecLayer.size() << " straws.");
+                 // fill the array                  
+                 layerSectorArrays.push_back(std::pair< Trk::BinnedArray<Trk::Surface>*, Amg::Vector3D >(layerStrawPhiSector, layerSectorPosition));                 
+                // ---------------- enf of phi sector ----------------------------------------------------
+              } // loop over PhiSectors done
+              
+              // build the mean of the layer Radius
+              layerRadius = 0.5*(layerRadiusMin+layerRadiusMax)+0.5*m_layerStrawRadius;
+              
+              bool assignMaterial = false;
+              if (cMaterialLayerCount == nMaterialLayerStep) {
+                  assignMaterial      = true;
+                  cMaterialLayerCount = 0;
+                  ATH_MSG_VERBOSE( "--> Creating a material+straw layer at radius  : " << layerRadius );
+              } else 
+                  ATH_MSG_VERBOSE( "--> Creating a straw          layer at radius  : " << layerRadius );
+              
+              // now order the plane layers to sit on cylindrical layers
+              Trk::CylinderBounds* barrelLayerBounds = new Trk::CylinderBounds(layerRadius, layerHalflength);
+              
+              // ---- correct phi -------------------------------------------------------------------
+              ATH_MSG_VERBOSE("    prepare approach description with " << nBarrelPhiSectors << " barrel sectors.");
+              ATH_MSG_VERBOSE("    min phi / max phi detected  : " << layerPhiMin << " / " << layerPhiMax );
+              double layerPhiMinCorrected = layerPhiMin-0.5*layerPhiStep;
+              double layerPhiMaxCorrected = layerPhiMax+0.5*layerPhiStep;
+              // catch if the minPhi falls below M_PI
+              if (layerPhiMinCorrected < -M_PI){
+                  layerPhiMinCorrected += layerPhiStep;
+                  layerPhiMaxCorrected += layerPhiStep;
+              }
+              ATH_MSG_VERBOSE("    min phi / max phi corrected : " << layerPhiMinCorrected << " / " << layerPhiMaxCorrected );
+              
+              // the sector surfaces
+              Trk::BinUtility* layerSectorBinUtility = new Trk::BinUtility(nBarrelPhiSectors,layerPhiMinCorrected,layerPhiMaxCorrected,Trk::closed,Trk::binPhi);
+              Trk::BinnedArrayArray<Trk::Surface>* strawArray = new Trk::BinnedArrayArray<Trk::Surface>(layerSectorArrays, layerSectorBinUtility );
+              
+              ATH_MSG_VERBOSE("--> Layer " << layer << " has been built with " << strawArray->arrayObjects().size() << " straws.");
+              
+              // ApproachDescriptor
+              // build a BinUtility for the ApproachDescritptor
+              Trk::BinUtility* aDescriptorBinUtility = new Trk::BinUtility(nBarrelPhiSectors,layerPhiMinCorrected,layerPhiMaxCorrected,Trk::closed,Trk::binPhi);
+                           (*aDescriptorBinUtility) += Trk::BinUtility(2,-layerHalflength,layerHalflength,Trk::open, Trk::binZ);
+              Trk::BinnedArray2D<Trk::ApproachSurfaces>* aDescriptorBinnedArray = new Trk::BinnedArray2D<Trk::ApproachSurfaces> (layerApproachSurfaces, aDescriptorBinUtility);             
+              // build an approach surface
+              Trk::CylinderSurface* approachSurface  = new Trk::CylinderSurface(barrelLayerBounds->clone()); 
+              Trk::ApproachDescriptor* aDescritpor   = new Trk::ApproachDescriptor(aDescriptorBinnedArray, approachSurface);
+              
+              // do not give every layer material properties
+              if (assignMaterial) {
+                 // ----- prepare the BinnedLayerMaterial -----------------------------------------------------
+                 Trk::BinnedLayerMaterial* layerMaterial = 0;
+                 // -- material with 1D binning
+                 Trk::BinUtility layerBinUtilityZ(m_barrelLayerBinsZ, -layerHalflength, layerHalflength, Trk::open, Trk::binZ );
+                 if (m_barrelLayerBinsPhi==1){
+                    layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityZ);
+                 } else { // -- material with 2D binning: RPhiZ binning
+                    Trk::BinUtility layerBinUtilityRPhiZ(m_barrelLayerBinsPhi,
+                                                               -layerRadius*M_PI, layerRadius*M_PI,
+                                                                Trk::closed,
+                                                                Trk::binRPhi);
+                                                                 layerBinUtilityRPhiZ += layerBinUtilityZ;                       
+                   layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityRPhiZ);
+                 }
+              
+                  barrelLayers->push_back(new Trk::CylinderLayer(barrelLayerBounds,
+                                                                 strawArray,
+                                                                 *layerMaterial,
+                                                                 m_layerThickness,
+                                                                 new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                                 aDescritpor));
+                   delete layerMaterial;
+              
+              } else
+                  barrelLayers->push_back(new Trk::CylinderLayer(barrelLayerBounds,
+                                                                 strawArray,
+                                                                 m_layerThickness,
+                                                                 new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                                 aDescritpor));
+              // increment this layer
+              ++ilay;
+        } // loop over layers
+     } // loop over rings
+   }
+
+  // return what you have
+  return std::make_pair(range,barrelLayers.release());
+}
+
+//TODO: context object is unused, elements are retrieved from m_trtMgr instead of CondSvc
+std::pair<EventIDRange, const std::vector< const Trk::DiscLayer* >* > InDet::TRT_LayerBuilderCond::discLayers(const EventContext&) const
+{
+  ATH_MSG_DEBUG( "Building disc-like layers for the TRT " );
+
+  //create dummy infinite range
+  EventIDRange range;
+
+  const InDetDD::TRT_Numerology* trtNums = m_trtMgr->getNumerology();
+  // get the TRT ID Helper
+  const TRT_ID* trtIdHelper = 0;
+  if (detStore()->retrieve(trtIdHelper, "TRT_ID").isFailure()) {
+     ATH_MSG_ERROR("Could not get TRT ID helper");
+     return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+  }
+  unsigned int nEndcapWheels = trtNums->getNEndcapWheels();
+  unsigned int nEndcapPhiSectors = trtNums->getNEndcapPhi();
+
+  // total layer numbers
+  int numTotalLayers = 0;
+
+  // zMin / zMax
+  double zMin = 10e10;
+  double zMax = 0.;
+
+  const Trk::DiscBounds* sectorDiscBounds = 0;
+
+  // preloop for overall numbers
+  for (unsigned int iwheel=0; iwheel<nEndcapWheels; ++iwheel)
+    {
+       unsigned int nEndcapLayers = trtNums->getNEndcapLayers(iwheel);
+       numTotalLayers += nEndcapLayers;
+       for (unsigned int ilayer = 0; ilayer<nEndcapLayers; ++ilayer){
+         const InDetDD::TRT_EndcapElement* sectorDiscElement = m_trtMgr->getEndcapElement(0, iwheel, ilayer, 0);
+
+         // get a reference element for dimensions
+         if (!sectorDiscBounds){
+           const Trk::SurfaceBounds& sectorSurfaceBounds = sectorDiscElement->bounds();
+           sectorDiscBounds = dynamic_cast<const Trk::DiscBounds*>(&sectorSurfaceBounds);
+         }
+
+         double currentZ = fabs(sectorDiscElement->center().z());
+         takeSmallerBigger(zMin,zMax,currentZ);
+       }
+    }
+  if (numTotalLayers==0) {
+      ATH_MSG_WARNING( "numTotalLayers = 0 ... aborting and returning 0 !" );
+      return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+  }
+
+  Trk::DiscBounds* fullDiscBounds = sectorDiscBounds ? new Trk::DiscBounds(sectorDiscBounds->rMin(), sectorDiscBounds->rMax()) : 0;
+  if (!fullDiscBounds) {
+      ATH_MSG_WARNING( "fullDiscBounds do not exist ... aborting and returning 0 !" );
+      return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+  }
+
+  PtrVectorWrapper<Trk::DiscLayer> endcapLayers;
+
+  // the BinUtility for the material
+  Trk::BinnedLayerMaterial* layerMaterial = 0;
+  // -- material with 1D binning
+  Trk::BinUtility layerBinUtilityR(m_endcapLayerBinsR,
+                                         fullDiscBounds->rMin(),
+                                         fullDiscBounds->rMax(),
+                                         Trk::open,
+                                         Trk::binR);
+  if (m_barrelLayerBinsPhi==1)
+     layerMaterial = new Trk::BinnedLayerMaterial(layerBinUtilityR);
+   else { // -- material with 2D binning
+     Trk::BinUtility layerBinUtilityPhi(m_barrelLayerBinsPhi,
+                                               -M_PI, M_PI,
+                                               Trk::closed,
+                                               Trk::binPhi);
+                            // make it rPhi now
+                       layerBinUtilityR += layerBinUtilityPhi;                   
+     layerMaterial =new Trk::BinnedLayerMaterial(layerBinUtilityR);
+  }
+
+  // global geometry statistics
+  double zDiff      = fabs(zMax-zMin);
+  double zStep      = zDiff/(m_modelEndcapLayers+1);
+
+  // loop for surface ordering
+  int maxendcaps=2;
+  if (m_endcapConly) maxendcaps=1;
+  
+  for (int iposneg=0; iposneg<maxendcaps; ++iposneg){
+
+    // fill the positions of the disc layers
+    std::vector<double> zPositions;
+    zPositions.reserve(m_modelEndcapLayers);
+
+    double stepdir = iposneg ? 1. : -1.;
+    double zStart = stepdir*zMin;
+
+    ATH_MSG_VERBOSE( " -> Creating " << m_modelEndcapLayers << " disc-layers on each side between " 
+                    << zMin << " and " << zMax << " ( at step "<< zStep << " )");
+
+    // take a different modelling for the layers - use these layers for the model geometry and the real geometry
+    for (unsigned int izpos = 1; izpos <= m_modelEndcapLayers; ++izpos){
+       zPositions.push_back(zStart + stepdir * double(izpos) * zStep - 0.5 * m_layerThickness);
+   }
+
+   std::vector<double>::const_iterator zPosIter    = zPositions.begin();
+   std::vector<double>::const_iterator zPosIterEnd = zPositions.end();
+
+   // (a) simplified geometry 
+   if (m_modelGeometry){
+      // build the layers actually
+      for ( ; zPosIter != zPosIterEnd; ++zPosIter){
+         ATH_MSG_VERBOSE( "  --> Creating a layer at z pos    : " << (*zPosIter) );
+         Amg::Transform3D* zPosTrans = new Amg::Transform3D;
+         (*zPosTrans) = Amg::Translation3D(0.,0.,(*zPosIter));
+         endcapLayers->push_back(new Trk::DiscLayer(zPosTrans,
+                                                    fullDiscBounds->clone(),
+                                                    *layerMaterial,
+                                                    m_layerThickness));
+        }
+
+   } else {
+      // (b) complex geometry 
+      int nMaterialLayerStep  = int(numTotalLayers/m_modelEndcapLayers+1);
+      int cMaterialLayerCount = 0;
+      
+      // complex geometry - needs a little bit of joggling
+      int    currentLayerCounter = 0;      
+      for (unsigned int iwheel=0; iwheel<nEndcapWheels; ++iwheel)
+      {
+        // do the loop per side
+        unsigned int nEndcapLayers = trtNums->getNEndcapLayers(iwheel);
+        for (unsigned int ilayer = 0; ilayer < nEndcapLayers; ++ilayer){
+         // increase the layerCounter for material layer decission
+         ++currentLayerCounter;
+         ++cMaterialLayerCount;
+         
+         // count the straws;
+         int numberOfStraws = 0;
+
+         // check if dynamic cast worked
+         if (fullDiscBounds){
+          // get a reference element for dimensions
+           const InDetDD::TRT_EndcapElement* sectorDiscElement = m_trtMgr->getEndcapElement(iposneg, iwheel, ilayer, 0);
+
+           // take the position, but not the rotation (the rotation has to be standard)
+           Amg::Vector3D fullDiscPosition(sectorDiscElement->surface().transform().translation());
+           double discZ = fullDiscPosition.z();
+
+           // check if we need to build a straw layer or not
+           bool assignMaterial = false;
+           if (cMaterialLayerCount == nMaterialLayerStep) {
+               assignMaterial      = true;
+               cMaterialLayerCount = 0;
+               ATH_MSG_VERBOSE( "--> Creating a material+straw layer at z-pos   : " << discZ );
+           } else {
+               ATH_MSG_VERBOSE( "--> Creating a straw          layer at z-pos   : " << discZ );
+           }
+
+           // order the straws onto layers
+           std::vector< Trk::SurfaceOrderPosition > strawPerEndcapLayer;
+
+           // the layer thickness - for approaching surfaces
+           double zMin = 10e10;
+           double zMax = -10e10;
+           
+           for (unsigned int iphisec=0; iphisec<nEndcapPhiSectors; ++iphisec){
+               ATH_MSG_VERBOSE("Building sector " << iphisec << " of endcap wheel " << iwheel );
+                const InDetDD::TRT_EndcapElement* currentElement = m_trtMgr->getEndcapElement(iposneg, iwheel, ilayer, iphisec);
+                unsigned int nstraws = currentElement->nStraws();
+                for (unsigned int istraw=0; istraw<nstraws; istraw++){
+                    Identifier strawId = trtIdHelper->straw_id(currentElement->identify(), istraw);
+                    const Trk::Surface* currentStraw = &(currentElement->surface(strawId));
+                    Amg::Vector3D strawOrderPos(currentStraw->center());
+                    // get the z position
+                    double zPos = currentStraw->center().z();
+                    takeSmaller(zMin,zPos);
+                    takeBigger(zMax,zPos);                    
+                    Trk::SharedObject<const Trk::Surface> sharedSurface(currentStraw, [](const Trk::Surface*){});
+                    strawPerEndcapLayer.push_back(Trk::SurfaceOrderPosition(sharedSurface, strawOrderPos));
+                    ++numberOfStraws;
+                }
+           }
+           // fix to CID 11326
+           if (!numberOfStraws){
+             //fix coverity 118656
+             delete fullDiscBounds;
+             return std::pair<EventIDRange,const std::vector<const Trk::DiscLayer* >* >(range,nullptr);
+           } 
+           Trk::BinUtility* currentBinUtility = new Trk::BinUtility(numberOfStraws, -M_PI, M_PI, Trk::closed, Trk::binPhi);
+           Trk::BinnedArray<Trk::Surface>*  strawArray = new Trk::BinnedArray1D<Trk::Surface>(strawPerEndcapLayer, currentBinUtility);
+           Trk::DiscLayer* currentLayer = 0;
+
+           // redefine the discZ 
+           discZ = 0.5*(zMin+zMax);
+           Amg::Transform3D* fullDiscTransform = new Amg::Transform3D;
+           (*fullDiscTransform) = Amg::Translation3D(0.,0.,discZ);
+
+           ATH_MSG_VERBOSE("TRT Disc being build at z Position " << discZ << " ( from " << zMin << " / " << zMax << " )");
+
+           // create the approach offset
+           Trk::ApproachSurfaces* aSurfaces = new Trk::ApproachSurfaces;
+           // get the position of the approach surfaces
+           const Amg::Vector3D aspPosition(0.,0.,zMin-m_layerStrawRadius);
+           const Amg::Vector3D asnPosition(0.,0.,zMax+m_layerStrawRadius);
+           
+           // create new surfaces
+           Amg::Transform3D* asnTransform = new Amg::Transform3D(Amg::Translation3D(asnPosition));   
+           Amg::Transform3D* aspTransform = new Amg::Transform3D(Amg::Translation3D(aspPosition));   
+           // order in an optimised way for collision direction
+           if (discZ > 0.){
+               aSurfaces->push_back( new Trk::DiscSurface(asnTransform, fullDiscBounds->clone()) );
+               aSurfaces->push_back( new Trk::DiscSurface(aspTransform, fullDiscBounds->clone()) );
+           } else {
+               aSurfaces->push_back( new Trk::DiscSurface(aspTransform, fullDiscBounds->clone()) );
+               aSurfaces->push_back( new Trk::DiscSurface(asnTransform, fullDiscBounds->clone()) );
+           }               
+           // approach descriptor
+           Trk::ApproachDescriptor* aDescriptor = new Trk::ApproachDescriptor(aSurfaces,false);
+           
+           // do not give every layer material properties
+           if (assignMaterial)
+              currentLayer = new Trk::DiscLayer(fullDiscTransform,
+                                                fullDiscBounds->clone(),
+                                                strawArray,
+                                                *layerMaterial,
+                                                m_layerThickness,
+                                                new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                aDescriptor);
+           else if (!m_modelGeometry)
+              currentLayer = new Trk::DiscLayer(fullDiscTransform,
+                                                fullDiscBounds->clone(),
+                                                strawArray,
+                                                m_layerThickness,
+                                                new InDet::TRT_OverlapDescriptor(trtIdHelper),
+                                                aDescriptor);
+
+          if (currentLayer) endcapLayers->push_back(currentLayer);
+       } // end of sectorDiscBounds if
+      } // end of layer loop
+     } // end of wheel loop
+    } // model/real geometry
+  } // end of posneg loop
+
+  delete layerMaterial; layerMaterial = 0;
+  delete fullDiscBounds; fullDiscBounds = 0;
+
+  return std::make_pair(range,endcapLayers.release());
+}
+
diff --git a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx
index 53bdacb2e50..65ae2778d12 100644
--- a/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx
+++ b/InnerDetector/InDetDetDescr/InDetTrackingGeometry/src/components/InDetTrackingGeometry_entries.cxx
@@ -4,6 +4,12 @@
 #include "InDetTrackingGeometry/RobustTrackingGeometryBuilder.h"
 #include "InDetTrackingGeometry/StagedTrackingGeometryBuilder.h"
 
+#include "InDetTrackingGeometry/BeamPipeBuilderCond.h"
+#include "InDetTrackingGeometry/SiLayerBuilderCond.h"
+#include "InDetTrackingGeometry/TRT_LayerBuilderCond.h"
+#include "InDetTrackingGeometry/RobustTrackingGeometryBuilderCond.h"
+#include "InDetTrackingGeometry/StagedTrackingGeometryBuilderCond.h"
+
 using namespace InDet;
 
 DECLARE_COMPONENT( BeamPipeBuilder )
@@ -12,3 +18,9 @@ DECLARE_COMPONENT( TRT_LayerBuilder )
 DECLARE_COMPONENT( RobustTrackingGeometryBuilder )
 DECLARE_COMPONENT( StagedTrackingGeometryBuilder )
 
+DECLARE_COMPONENT( BeamPipeBuilderCond )
+DECLARE_COMPONENT( SiLayerBuilderCond )
+DECLARE_COMPONENT( TRT_LayerBuilderCond )
+DECLARE_COMPONENT( RobustTrackingGeometryBuilderCond )
+DECLARE_COMPONENT( StagedTrackingGeometryBuilderCond )
+
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h
new file mode 100644
index 00000000000..40f179309c4
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h
@@ -0,0 +1,190 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// MuonTrackingGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef MUONTRACKINGGEOMETRY_MUONTRACKINGGEOMETRYBUILDERCOND_H
+#define MUONTRACKINGGEOMETRY_MUONTRACKINGGEOMETRYBUILDERCOND_H
+
+//Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+// Gaudi
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/IChronoStatSvc.h"
+#include "MuonTrackingGeometry/MuonStationBuilder.h"
+#include "MuonTrackingGeometry/MuonInertMaterialBuilder.h"
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/RZPair.h"
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+
+namespace Trk {
+ class TrackingGeometry;
+ class Material; 
+ class VolumeBounds;
+ class ITrackingVolumeBuilder;
+
+ typedef std::pair< SharedObject<const TrackingVolume>, Amg::Vector3D> TrackingVolumeOrderPosition;
+ typedef std::pair< SharedObject<const TrackingVolume>, const Amg::Transform3D*> TrackingVolumeNavOrder;
+
+}
+
+namespace Muon {
+
+  typedef std::vector<double> Span;
+     
+  /** @class MuonTrackingGeometryBuilderCond
+  
+      The Muon::MuonTrackingGeometryBuilderCond retrieves MuonStationBuilder and MuonInertMaterialBuilder
+      for the Muon Detector sub detectors and combines the given Volumes to a full Trk::TrackingGeometry.
+      
+      Inheriting directly from IGeometryBuilderCond it can use the protected member functions of the IGeometryBuilderCond
+      to glue Volumes together and exchange BoundarySurfaces
+      
+      @author Sarka.Todorova@cern.ch
+    */
+    
+  class MuonTrackingGeometryBuilderCond : public AthAlgTool,
+                               virtual public Trk::IGeometryBuilderCond {
+  public:
+      /** Constructor */
+      MuonTrackingGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+      /** Destructor */
+      virtual ~MuonTrackingGeometryBuilderCond() = default;
+      /** AlgTool initailize method.*/
+      StatusCode initialize();
+      /** AlgTool finalize method */
+      StatusCode finalize();
+      /** TrackingGeometry Interface method */
+      std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair ) const; 
+
+      /** The unique signature */
+      Trk::GeometrySignature geometrySignature() const { return Trk::MS; }
+      
+    private:
+      /** Private struct to contain local variables we dont want to be global in this class*/
+      struct LocalVariablesContainer {
+	double m_innerBarrelRadius;
+	double m_outerBarrelRadius;
+	double m_innerEndcapZ;
+	double m_outerEndcapZ;
+	bool m_adjustStatic;
+	bool m_static3d;
+	std::vector<double> m_zPartitions;
+	std::vector<int>       m_zPartitionsType;
+	std::vector<float>    m_adjustedPhi;
+	std::vector<int>       m_adjustedPhiType;
+	std::vector<const Span*>                      m_spans;             // for clearing
+	std::vector<std::vector<std::vector<std::vector<std::pair<int,float> > > > >  m_hPartitions;
+	std::vector<double>                              m_shieldZPart;
+	std::vector<std::vector<std::pair<int,float> > >   m_shieldHPart;
+	std::map<const Trk::DetachedTrackingVolume*,std::vector<const Trk::TrackingVolume*>* > m_blendMap;
+	std::vector<const Trk::DetachedTrackingVolume*> m_blendVols;
+	const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* m_stationSpan; 
+	const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* m_inertSpan; 
+	RZPairVector     m_msCutoutsIn;
+	RZPairVector     m_msCutoutsOut;
+	Trk::Material  m_muonMaterial;               //!< the (empty) material
+	Trk::TrackingVolume*        m_standaloneTrackingVolume;   // muon standalone tracking volume
+      };
+
+      /** Private method to find z/phi span of detached volumes */
+      const Span* findVolumeSpan(const Trk::VolumeBounds* volBounds, Amg::Transform3D transf, double zTol, double phiTol, LocalVariablesContainer &aLVC) const;
+      const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* findVolumesSpan(const std::vector<const Trk::DetachedTrackingVolume*>* objs, double zTol, double phiTol, LocalVariablesContainer &aLVC) const;
+      /** Private methods to define subvolumes and fill them with detached volumes */
+      const Trk::TrackingVolume* processVolume( const Trk::Volume*, int, int, std::string, LocalVariablesContainer &aLVC) const; 
+      const Trk::TrackingVolume* processVolume( const Trk::Volume*, int, std::string, LocalVariablesContainer &aLVC) const; 
+      const Trk::TrackingVolume* processShield( const Trk::Volume*, int, std::string, LocalVariablesContainer &aLVC) const; 
+      /** Private method to check volume properties */
+      void checkVolume(const Trk::TrackingVolume*) const;
+      /** Private method to find detached volumes */
+      std::vector<const Trk::DetachedTrackingVolume*>* getDetachedObjects(const Trk::Volume*, std::vector<const Trk::DetachedTrackingVolume*>&, LocalVariablesContainer &aLVC ,int mode=0) const;
+      /** Private method to check if constituent enclosed */
+      bool enclosed(const Trk::Volume*, const Muon::Span*, LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve z partition */
+      void getZParts(LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve phi partition */
+      void getPhiParts(int, LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve h partition */
+      void getHParts(LocalVariablesContainer &aLVC) const;
+      /** Private method to retrieve shield partition */
+      void getShieldParts(LocalVariablesContainer & aLVC) const; 
+      /** Private method to calculate volume */
+      double calculateVolume(const Trk::Volume*) const;
+      /** Private method to blend the inert material */
+      void blendMaterial(LocalVariablesContainer &aLVC) const;
+     
+      ToolHandle<Trk::IDetachedTrackingVolumeBuilder>      m_stationBuilder{this,"MuonStationBuilder","Muon::MuonStationBuilder/MuonStationBuilder"};                //!< A Tool for station type creation
+
+      ToolHandle<Trk::IDetachedTrackingVolumeBuilder>      m_inertBuilder{this,"InertMaterialBuilder","Muon::MuonInertMaterialBuilder/MuonInertMaterialBuilder"};      //!< A Tool for inert object  creation
+      
+      ToolHandle<Trk::ITrackingVolumeArrayCreator>         m_trackingVolumeArrayCreator{this,"TrackingVolumeArrayCreator","Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"};    //!< Helper Tool to create TrackingVolume Arrays
+
+      ToolHandle<Trk::ITrackingVolumeHelper>               m_trackingVolumeHelper{this,"TrackingVolumeHelper","Trk::TrackingVolumeHelper/TrackingVolumeHelper"};          //!< Helper Tool to create TrackingVolumes
+
+      ServiceHandle<IEnvelopeDefSvc>                       m_enclosingEnvelopeSvc{this,"EnvelopeDefinitionSvc","AtlasEnvelopeDefSvc","n"};   //!< service to provide input volume size
+   
+      Gaudi::Property<bool>                                m_muonSimple{this,"SimpleMuonGeometry",false};
+      Gaudi::Property<bool>                                m_loadMSentry{this,"LoadMSEntry",false};
+      Gaudi::Property<bool>                                m_muonActive{this,"BuildActiveMaterial",true};
+      Gaudi::Property<bool>                                m_muonInert{this,"BuildInertMaterial",true};
+
+      // Overall Dimensions
+      Gaudi::Property<double>        m_innerBarrelRadius{this,"InnerBarrelRadius",4255.};    //!< minimal extend in radial dimension of the muon barrel
+      Gaudi::Property<double>        m_outerBarrelRadius{this,"OuterBarrelRadius",13910.}; //!< maximal extend in radial dimension of the muon barrel
+      Gaudi::Property<double>        m_barrelZ{this,"BarrelZ",6785.};                                              //!< maximal extend in z of the muon barrel
+      Gaudi::Property<double>        m_innerEndcapZ{this,"InnerEndcapZ",12900.};              //!< maximal extend in z of the inner part of muon endcap 
+      Gaudi::Property<double>        m_outerEndcapZ{this,"OuterEndcapZ",26046.};             //!< maximal extend in z of the outer part of muon endcap
+      double                              m_bigWheel;                 //!< maximal extend in z of the big wheel
+      double                              m_outerWheel;               //!< minimal extend in z of the outer wheel (EO)
+      double                              m_ectZ;                     //!< minimal extent in z of the ECT
+      double                              m_beamPipeRadius;
+      double                              m_innerShieldRadius;
+      double                              m_outerShieldRadius;
+      double                              m_diskShieldZ;
+
+      Gaudi::Property<int>                m_barrelEtaPartition{this,"EtaBarrelPartitions",9};
+      Gaudi::Property<int>                m_innerEndcapEtaPartition{this,"EtaInnerEndcapPartitions",3};
+      Gaudi::Property<int>                m_outerEndcapEtaPartition{this,"EtaOuterEndcapPartitions",3};
+      Gaudi::Property<int>                m_phiPartition{this,"PhiPartitions",16};
+
+      Gaudi::Property<bool>              m_adjustStatic{this,"AdjustStatic",true};
+      Gaudi::Property<bool>              m_static3d{this,"StaticPartition3D",true};
+
+      Gaudi::Property<bool>               m_blendInertMaterial{this,"BlendInertMaterial",false}; 
+      Gaudi::Property<bool>               m_removeBlended{this,"RemoveBlendedMaterialObjects",false};
+      mutable std::atomic_uint            m_inertPerm{0};                  // number of perm objects
+      Gaudi::Property<double>           m_alignTolerance{this,"AlignmentPositionTolerance",0.};
+      Gaudi::Property<int>                m_colorCode{this,"ColorCode",0};
+      Gaudi::Property<int>                  m_activeAdjustLevel{this,"ActiveAdjustLevel",2};
+      Gaudi::Property<int>                  m_inertAdjustLevel{this,"InertAdjustLevel",1};
+
+      mutable std::atomic_uint            m_frameNum{0};      
+      mutable std::atomic_uint            m_frameStat{0};      
+
+      Gaudi::Property<std::string>        m_entryVolume{this,"EntryVolumeName","MuonSpectrometerEntrance"};
+      Gaudi::Property<std::string>        m_exitVolume{this,"ExitVolumeName","All::Container::CompleteDetector"};
+
+      
+      const std::vector<const Trk::DetachedTrackingVolume*>*   m_stations;    // muon chambers 
+      const std::vector<const Trk::DetachedTrackingVolume*>*   m_inertObjs;   // muon inert material 
+      //mutable std::vector<std::pair<std::string,std::pair<double, unsigned int> > >   m_dilFact;
+      //mutable std::vector<Trk::MaterialProperties>               m_matProp;
+      typedef ServiceHandle<IChronoStatSvc> IChronoStatSvc_t;
+      IChronoStatSvc_t m_chronoStatSvc{this,"ChronoStatSvc","ChronoStatSvc","n"};      
+ };
+
+
+} // end of namespace
+
+
+#endif //MUONTRACKINGGEOMETRY_MUONTRACKINGGEOMETRYBUILDER_H
+
+
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryBuilderCond.py b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryBuilderCond.py
new file mode 100644
index 00000000000..0bbf301939a
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryBuilderCond.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+#####################################################
+# ConfiguredMuonTrackingGeometry module
+#
+# it inherits from MuonTrackingGeometryBuilder and performs 
+# standard configuration
+#
+######################################################
+# import the include statement
+from AthenaCommon.Include import Include, IncludeError, include
+ 
+# import the configurable
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonTrackingGeometryBuilderCond
+
+# define the class
+class ConfiguredMuonTrackingGeometryBuilderCond( Muon__MuonTrackingGeometryBuilderCond ):
+    # constructor
+    def __init__(self,name = 'MuonTrackingGeometryBuilderCond'):
+ 
+        from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+
+        # import the ToolSvc
+        from AthenaCommon.AppMgr import ToolSvc
+        if 'ToolSvc' not in dir() :
+            ToolSvc = ToolSvc()
+
+        from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationTypeBuilder
+        MuonStationTypeBuilder= Muon__MuonStationTypeBuilder(name = 'MuonStationTypeBuilder')
+
+        ToolSvc += MuonStationTypeBuilder
+
+        # muon active/passive geometry setup
+        from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationBuilder
+        MuonStationBuilder= Muon__MuonStationBuilder(name = 'MuonStationBuilder' )
+        ToolSvc += MuonStationBuilder
+
+        from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonInertMaterialBuilder
+        MuonInertMaterialBuilder= Muon__MuonInertMaterialBuilder(name = 'MuonInertMaterialBuilder')
+        ToolSvc += MuonInertMaterialBuilder 
+
+        Muon__MuonTrackingGeometryBuilderCond.__init__(self,name,\
+                                                   EntryVolumeName=TrkDetFlags.MuonSystemEntryVolumeName(),\
+                                                   ExitVolumeName  = TrkDetFlags.MuonSystemContainerName())
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryCond.py b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryCond.py
new file mode 100644
index 00000000000..c3df82191aa
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/python/ConfiguredMuonTrackingGeometryCond.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+
+from AthenaCommon.AppMgr import ToolSvc
+
+from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationTypeBuilder
+MuonStationTypeBuilder= Muon__MuonStationTypeBuilder(name = 'MuonStationTypeBuilder')
+ToolSvc += MuonStationTypeBuilder
+
+# muon active/passive geometry setup
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonStationBuilder
+MuonStationBuilder= Muon__MuonStationBuilder(name = 'MuonStationBuilder')
+MuonStationBuilder.StationTypeBuilder = MuonStationTypeBuilder
+ToolSvc += MuonStationBuilder
+
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonInertMaterialBuilder
+MuonInertMaterialBuilder= Muon__MuonInertMaterialBuilder(name = 'MuonInertMaterialBuilder')
+ToolSvc += MuonInertMaterialBuilder 
+
+# muon tracking geometry builder
+from MuonTrackingGeometry.MuonTrackingGeometryConf import Muon__MuonTrackingGeometryBuilderCond
+MuonTrackingGeometryBuilderCond= Muon__MuonTrackingGeometryBuilderCond(name = 'MuonTrackingGeometryBuilderCond')
+MuonTrackingGeometryBuilderCond.EntryVolumeName = TrkDetFlags.MuonSystemEntryVolumeName()
+MuonTrackingGeometryBuilderCond.ExitVolumeName  = TrkDetFlags.MuonSystemContainerName()
+MuonTrackingGeometryBuilderCond.OutputLevel     = TrkDetFlags.MuonBuildingOutputLevel()
+ToolSvc += MuonTrackingGeometryBuilderCond
+
+#print MuonTrackingGeometryBuilder
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/MuonTrackingGeometryBuilderCond.cxx b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/MuonTrackingGeometryBuilderCond.cxx
new file mode 100644
index 00000000000..4b4dfeb861e
--- /dev/null
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/MuonTrackingGeometryBuilderCond.cxx
@@ -0,0 +1,2655 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+//////////////////////////////////////////////////////////////////
+// MuonTrackingGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// Muon
+#include "MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h"
+#include "MuonReadoutGeometry/GlobalUtilities.h" 
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Units
+#include "GaudiKernel/SystemOfUnits.h"
+// Trk
+#include "TrkDetDescrUtils/BinUtility.h"
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include "TrkDetDescrUtils/BinnedArray1D.h"
+#include "TrkDetDescrUtils/BinnedArray2D.h"
+#include "TrkDetDescrUtils/BinnedArray1D1D1D.h"
+#include "TrkDetDescrUtils/GeometryStatics.h"
+#include "TrkDetDescrUtils/SharedObject.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkVolumes/TrapezoidVolumeBounds.h"
+#include "TrkVolumes/DoubleTrapezoidVolumeBounds.h"
+#include "TrkVolumes/BevelledCylinderVolumeBounds.h"
+#include "TrkVolumes/CuboidVolumeBounds.h"
+#include "TrkVolumes/SubtractedVolumeBounds.h"
+#include "TrkVolumes/CombinedVolumeBounds.h"
+#include "TrkVolumes/SimplePolygonBrepVolumeBounds.h"
+#include "TrkVolumes/PrismVolumeBounds.h"
+#include "TrkVolumes/BoundarySurface.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/GlueVolumesDescriptor.h"
+#include "TrkGeometry/Material.h"
+#include<fstream>
+
+// STD
+#include <map>
+
+
+// constructor
+Muon::MuonTrackingGeometryBuilderCond::MuonTrackingGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p) :
+  AthAlgTool(t,n,p),
+  m_bigWheel(15600.),
+  m_outerWheel(21000.),
+  m_ectZ(7920.),
+  m_beamPipeRadius(70.),
+  m_innerShieldRadius(850.),
+  m_outerShieldRadius(1500.),
+  m_diskShieldZ(6915.),
+  m_stations(0),
+  m_inertObjs(0)
+{
+  declareInterface<Trk::IGeometryBuilderCond>(this);
+}
+
+// Athena standard methods
+// initialize
+
+StatusCode Muon::MuonTrackingGeometryBuilderCond::initialize()
+{
+ 
+  // Retrieve the tracking volume helper   -------------------------------------------------    
+  if (m_trackingVolumeHelper.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeHelper );
+      return StatusCode::FAILURE;
+    } else
+    ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeHelper );
+  
+  // Retrieve the tracking volume array creator   -------------------------------------------    
+  if (m_trackingVolumeArrayCreator.retrieve().isFailure())
+    {
+      ATH_MSG_FATAL( "Failed to retrieve tool " << m_trackingVolumeArrayCreator );
+      return StatusCode::FAILURE;
+    } else
+    ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+  
+  // Retrieve the station builder (if configured) -------------------------------------------    
+  if (m_muonActive) { 
+    
+    if (m_stationBuilder.retrieve().isFailure())
+      {
+	ATH_MSG_ERROR( "Failed to retrieve tool " << m_stationBuilder <<" Creation of stations might fail." );
+      } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+  } else {
+    m_activeAdjustLevel = 0;                // no active material to consider
+  }
+  
+  // Retrieve the inert material builder builder (if configured) -------------------------------------------    
+  
+  if (m_muonInert || m_blendInertMaterial) {
+    
+    if (m_inertBuilder.retrieve().isFailure())
+      {
+	ATH_MSG_ERROR( "Failed to retrieve tool " << m_inertBuilder <<"Creation of inert material objects might fail." );
+      } else
+      ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeArrayCreator );
+  }
+  
+  if ( !m_muonInert ) m_inertAdjustLevel = 0;
+  
+  if (m_loadMSentry ) {
+    // retrieve envelope definition service --------------------------------------------------
+    if ( m_enclosingEnvelopeSvc.retrieve().isFailure() ){
+      ATH_MSG_WARNING( "Could not retrieve EnvelopeDefinition service. Using default definition.");
+      m_loadMSentry = false;
+    }
+  }
+
+  // process muon material objects
+  if (m_muonActive && m_stationBuilder && !m_stations) m_stations = m_stationBuilder->buildDetachedTrackingVolumes();
+  if (m_muonInert && m_inertBuilder && !m_inertObjs) m_inertObjs = m_inertBuilder->buildDetachedTrackingVolumes(m_blendInertMaterial);
+
+  if (m_chronoStatSvc.retrieve().isFailure()) {
+    ATH_MSG_WARNING( "Could not retrieve Tool " << m_chronoStatSvc << ". Exiting.");
+  }
+  
+
+  ATH_MSG_INFO( name() <<" initialize() successful" );    
+    
+  return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Muon::MuonTrackingGeometryBuilderCond::trackingGeometry(const EventContext& /*ctx*/, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const
+{
+  ATH_MSG_INFO( name() <<" building tracking geometry" );    
+  m_chronoStatSvc->chronoStart("MS::build-up");
+  //start with range from encapsulated TrackingGeometry if it exists, otherwise infinite range
+  //TODO/FIXME: this range must be intersected with IOV range of the Muon Tracking Geometry
+  EventIDRange range;
+  const Trk::TrackingVolume* tvol = nullptr;
+  if (tVolPair.second != nullptr){
+    range = tVolPair.first;
+    tvol = tVolPair.second;
+  }
+  //load local variables to container
+  LocalVariablesContainer aLVC;
+  aLVC.m_innerBarrelRadius = m_innerBarrelRadius;
+  aLVC.m_outerBarrelRadius = m_outerBarrelRadius;
+  aLVC.m_innerEndcapZ = m_innerEndcapZ;
+  aLVC.m_outerEndcapZ = m_outerEndcapZ;
+  aLVC.m_adjustStatic = m_adjustStatic;
+  aLVC.m_static3d = m_static3d;
+  aLVC.m_blendMap.clear();
+  aLVC.m_blendVols.clear(); 
+  aLVC.m_stationSpan = 0;
+  aLVC.m_inertSpan = 0;
+  ///////////////////////////////////////////////////////////////////////////////////////////////////
+  // check setup
+  if (m_muonInert && m_blendInertMaterial) {
+    if (!aLVC.m_adjustStatic || !aLVC.m_static3d) {
+      ATH_MSG_INFO( name() <<" diluted inert material hardcoded for 3D volume frame, adjusting setup" );
+      aLVC.m_adjustStatic = true;
+      aLVC.m_static3d = true;
+    }
+  }
+
+  if (m_inertObjs && m_blendInertMaterial && m_removeBlended) {
+    while ( m_inertPerm<m_inertObjs->size() 
+	    && (*m_inertObjs)[m_inertPerm]->name().substr((*m_inertObjs)[m_inertPerm]->name().size()-4,4)=="PERM") m_inertPerm++;
+  }
+  
+  // find object's span with tolerance for the alignment 
+  if (!aLVC.m_stationSpan) aLVC.m_stationSpan = findVolumesSpan(m_stations, 100.*m_alignTolerance, m_alignTolerance*Gaudi::Units::deg,aLVC);
+  if (!aLVC.m_inertSpan)   aLVC.m_inertSpan = findVolumesSpan(m_inertObjs,0.,0.,aLVC);
+ 
+  // 0) Preparation //////////////////////////////////////////////////////////////////////////////////////
+  
+  aLVC.m_muonMaterial = Trk::Material(10e10,10e10,0.,0.,0.);      // default material properties
+    
+  // dummy substructures
+  const Trk::LayerArray* dummyLayers = 0;
+  const Trk::TrackingVolumeArray* dummyVolumes = 0;
+
+
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////
+  //   Envelope definition (cutouts)
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////
+  RZPairVector envelopeDefs;
+  if (m_enclosingEnvelopeSvc) {
+    // get the dimensions from the envelope service
+    RZPairVector& envelopeDefsIn = m_enclosingEnvelopeSvc->getMuonRZValues();
+
+    // find the max,max pair
+    unsigned int ii=0;
+    for (unsigned int i=0; i<envelopeDefsIn.size(); i++) { 
+      if (envelopeDefsIn[i].second>envelopeDefsIn[ii].second) ii=i;
+      else if (envelopeDefsIn[i].second==envelopeDefsIn[ii].second && 
+	       envelopeDefsIn[i].first>envelopeDefsIn[ii].first) ii=i;
+    }  
+
+    // find the sense of rotation
+    int irot=1;
+    unsigned int inext=ii+1;
+    if (inext==envelopeDefsIn.size()) inext=0;
+    if (envelopeDefsIn[inext].second!=envelopeDefsIn[ii].second) {irot=-1; inext = ii>0 ? ii-1:envelopeDefsIn.size()-1 ;}
+    
+    // fill starting with upper low edge, end with upper high edge
+    if (irot>0) {
+      for (unsigned int i=inext; i<envelopeDefsIn.size(); i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+      if (inext>0) for (unsigned int i=0; i<=inext-1; i++) envelopeDefs.push_back(envelopeDefsIn[i]); 
+    } else {
+      int i=inext;  while (i>=0) {envelopeDefs.push_back(envelopeDefsIn[i]); i=i-1;};
+      inext = envelopeDefsIn.size()-1; while (inext>=ii) {envelopeDefs.push_back(envelopeDefsIn[inext]); inext=inext-1;};
+    } 
+
+    // find maximal z,R extent
+    float maxR = 0.; 
+    for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+      if (envelopeDefs[i].first > maxR )  maxR = envelopeDefs[i].first; 
+    } 
+    
+    aLVC.m_outerBarrelRadius = maxR;
+    aLVC.m_outerEndcapZ      = envelopeDefs[0].second;
+
+    ATH_MSG_VERBOSE( "Muon envelope definition retrieved: outer R,Z:"<<aLVC.m_outerBarrelRadius<<","<< aLVC.m_outerEndcapZ );  
+
+    // construct inner and outer envelope
+    
+    for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+      ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< envelopeDefs[i].first<<","<<envelopeDefs[i].second );   
+    }
+
+  }
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////////
+  
+  if (m_muonSimple) {             
+    Trk::VolumeBounds* globalBounds = new Trk::CylinderVolumeBounds(aLVC.m_outerBarrelRadius,
+								    aLVC.m_outerEndcapZ);
+    Trk::TrackingVolume* topVolume = new Trk::TrackingVolume(0,
+							     globalBounds,
+							     aLVC.m_muonMaterial,
+							     dummyLayers,dummyVolumes,
+							     "GlobalVolume");
+    aLVC.m_standaloneTrackingVolume = topVolume;
+    return std::make_pair(range, new Trk::TrackingGeometry(topVolume));
+  }     
+  
+  ATH_MSG_INFO( name() <<"building barrel+innerEndcap+outerEndcap" );    
+  
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MuonSpectrometer contains:
+//       - Barrel
+//       - Endcaps inner/outer
+  const Trk::TrackingVolume* muonBarrel = 0;
+  Trk::CylinderVolumeBounds* barrelBounds = 0;
+  const Trk::TrackingVolume* negativeMuonOuterWheel = 0;
+  Trk::CylinderVolumeBounds* negativeOuterWheelBounds = 0;
+  const Trk::TrackingVolume* negativeMuonBigWheel = 0;
+  Trk::CylinderVolumeBounds* negativeBigWheelBounds = 0;
+  const Trk::TrackingVolume* negativeMuonOuterBuffer = 0;
+  Trk::CylinderVolumeBounds* negativeOuterBufferBounds = 0;
+  const Trk::TrackingVolume* positiveMuonOuterWheel = 0;
+  const Trk::TrackingVolume* negativeMuonSmallWheel = 0;
+  const Trk::TrackingVolume* positiveMuonSmallWheel = 0;
+  Trk::CylinderVolumeBounds* negativeSmallWheelBounds = 0;
+  const Trk::TrackingVolume* negativeECT = 0;
+  const Trk::TrackingVolume* positiveECT = 0;
+  Trk::CylinderVolumeBounds* negativeECTBounds = 0;
+  const Trk::TrackingVolume* positiveMuonBigWheel = 0;
+  const Trk::TrackingVolume* positiveMuonOuterBuffer = 0;
+// volumes needed to close the geometry
+  const Trk::TrackingVolume* negBeamPipe = 0;
+  const Trk::TrackingVolume* posBeamPipe = 0;
+  Trk::CylinderVolumeBounds* negBeamPipeBounds = 0;
+  Trk::CylinderVolumeBounds* posBeamPipeBounds = 0;
+  const Trk::TrackingVolume* enclosed = 0;
+  Trk::CylinderVolumeBounds* enclosedBounds = 0;
+  const Trk::TrackingVolume* negDiskShield = 0;
+  Trk::CylinderVolumeBounds* negDiskShieldBounds = 0;
+  const Trk::TrackingVolume* posDiskShield = 0;
+  Trk::CylinderVolumeBounds* posDiskShieldBounds = 0;
+  const Trk::TrackingVolume* negInnerShield = 0;
+  const Trk::TrackingVolume* posInnerShield = 0;
+  Trk::CylinderVolumeBounds* negInnerShieldBounds = 0;
+  Trk::CylinderVolumeBounds* posInnerShieldBounds = 0;
+  const Trk::TrackingVolume* negOuterShield = 0;
+  const Trk::TrackingVolume* posOuterShield = 0;
+  Trk::CylinderVolumeBounds* negOuterShieldBounds = 0;
+  Trk::CylinderVolumeBounds* posOuterShieldBounds = 0;
+// if input, redefine dimensions to fit expected MS entry 
+  if (tvol){
+    bool msEntryDefined = false;
+    if ( tvol->volumeName() == m_entryVolume ) msEntryDefined = true; 
+    // get dimensions
+    ATH_MSG_DEBUG(" msEntryDefined " << msEntryDefined);
+    const Trk::CylinderVolumeBounds* enclosedDetectorBounds 
+      = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(tvol->volumeBounds()));
+    if (!enclosedDetectorBounds) {    
+      ATH_MSG_ERROR(" dynamic cast of enclosed volume to the cylinder bounds failed, aborting MTG build-up ");
+      return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);
+    }
+    double enclosedDetectorHalfZ = enclosedDetectorBounds->halflengthZ();
+    double enclosedDetectorOuterRadius = enclosedDetectorBounds->outerRadius();
+    // get subvolumes at navigation level and check THEIR dimensions      
+    const Trk::GlueVolumesDescriptor& enclosedDetGlueVolumes = tvol->glueVolumesDescriptor();
+    std::vector<const Trk::TrackingVolume*> enclosedCentralFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::cylinderCover);
+    std::vector<const Trk::TrackingVolume*> enclosedNegativeFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::negativeFaceXY);
+    std::vector<const Trk::TrackingVolume*> enclosedPositiveFaceVolumes = enclosedDetGlueVolumes.glueVolumes(Trk::positiveFaceXY);
+    if (enclosedCentralFaceVolumes.size()) {
+      const Trk::CylinderVolumeBounds* cylR = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(enclosedCentralFaceVolumes[0]->volumeBounds()));
+      if (cylR && cylR->outerRadius() != enclosedDetectorOuterRadius ) {
+        enclosedDetectorOuterRadius = cylR->outerRadius();
+        ATH_MSG_WARNING(name() << " enclosed volume envelope outer radius does not correspond to radius of glue volumes : adjusted " );
+      }
+    }
+    if (enclosedNegativeFaceVolumes.size() && enclosedPositiveFaceVolumes.size()) {
+      double negZ = -enclosedDetectorHalfZ;
+      double posZ =  enclosedDetectorHalfZ;
+      const Trk::CylinderVolumeBounds* cylN = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(enclosedNegativeFaceVolumes[0]->volumeBounds()));
+      if (cylN) negZ = enclosedNegativeFaceVolumes[0]->center()[2]-cylN->halflengthZ();
+      const Trk::CylinderVolumeBounds* cylP = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(enclosedPositiveFaceVolumes[0]->volumeBounds()));
+      if (cylP) posZ = enclosedPositiveFaceVolumes[0]->center()[2]+cylP->halflengthZ();
+      if ( fabs(negZ+enclosedDetectorHalfZ)>0.001 ||  fabs(posZ-enclosedDetectorHalfZ)>0.001 ) {
+	ATH_MSG_WARNING( name() << " enclosed volume envelope z dimension does not correspond to that of glue volumes " );
+        if ( fabs(negZ+posZ)<0.001) {
+          enclosedDetectorHalfZ = posZ;
+          ATH_MSG_WARNING( name() << " z adjusted " );
+	} else {
+	  ATH_MSG_ERROR( name() << "assymetric Z dimensions - cannot recover "<< negZ <<","<< posZ );
+          return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);
+	}
+     }
+    }
+    //
+    
+
+    // 
+    ATH_MSG_INFO( name() <<" dimensions of enclosed detectors (halfZ,outerR):"
+	<<  enclosedDetectorHalfZ<<","<< enclosedDetectorOuterRadius );    
+    // check if input makes sense - gives warning if cuts into muon envelope
+    // adjust radius
+    const Trk::TrackingVolume* barrelR = 0;
+    if ( enclosedDetectorOuterRadius > aLVC.m_innerBarrelRadius ) {
+      ATH_MSG_WARNING( name() <<" enclosed volume too wide, cuts into muon envelope, abandon :R:" <<enclosedDetectorOuterRadius );
+      return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);   
+    } else { 
+      aLVC.m_innerBarrelRadius = enclosedDetectorOuterRadius;
+      barrelR = tvol;      
+    }
+    // adjust z
+    if ( enclosedDetectorHalfZ > m_barrelZ ) {
+      ATH_MSG_WARNING( name() <<" enclosed volume too long, cuts into muon envelope, abandon :Z:"<< enclosedDetectorHalfZ );    
+      return std::pair<EventIDRange, const Trk::TrackingGeometry*>(range, nullptr);
+    } else {    
+      if ( enclosedDetectorHalfZ < m_barrelZ ) {
+	Trk::CylinderVolumeBounds* barrelZPBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+										 0.5*(m_barrelZ - enclosedDetectorHalfZ) );
+	Trk::CylinderVolumeBounds* barrelZMBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+										 0.5*(m_barrelZ - enclosedDetectorHalfZ) );
+	double zbShift =  0.5*(m_barrelZ + enclosedDetectorHalfZ);
+	const Trk::TrackingVolume* barrelZPBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,zbShift))),
+									    barrelZPBounds,
+									    aLVC.m_muonMaterial,
+									    dummyLayers,dummyVolumes,
+									    "BarrelRZPosBuffer");
+	const Trk::TrackingVolume* barrelZMBuffer = new Trk::TrackingVolume(new Amg::Transform3D(Amg::Translation3D(Amg::Vector3D(0.,0.,-zbShift))),
+									    barrelZMBounds,
+									    aLVC.m_muonMaterial,
+									    dummyLayers,dummyVolumes,
+									    "BarrelRZNegBuffer");
+	
+	ATH_MSG_INFO( name() << "glue barrel R  + barrel Z buffer" );
+	const Trk::TrackingVolume* barrelZP = m_trackingVolumeHelper->glueTrackingVolumeArrays(*barrelR, Trk::positiveFaceXY,
+											       *barrelZPBuffer,Trk::negativeFaceXY, 
+											       "All::Gaps::BarrelZP");    
+        // set name
+	std::string nameEncl = msEntryDefined ? "All::Gaps::Barrel" : m_entryVolume ;
+        ATH_MSG_DEBUG( " nameEncl " << nameEncl);
+	enclosed = m_trackingVolumeHelper->glueTrackingVolumeArrays(*barrelZP, Trk::negativeFaceXY,
+								    *barrelZMBuffer,Trk::positiveFaceXY, 
+								    nameEncl);    
+ 
+      } else enclosed = barrelR;
+      // ST the following simplification forces MuonSpectrometerEntrance to coincide with Calo::Container
+      //m_barrelZ = enclosedDetectorHalfZ;
+      //enclosed = barrelR;      
+    }
+    
+  } else {     // no input, create the enclosed volume
+    if (m_loadMSentry && m_enclosingEnvelopeSvc ) {
+      RZPairVector& envelopeDefs = m_enclosingEnvelopeSvc->getCaloRZValues();
+      // to be implemented in detail - for the moment, take just maximal extent
+      ATH_MSG_DEBUG( " m_loadMSentry " << m_loadMSentry << " m_enclosingEnvelopeSvc " << m_enclosingEnvelopeSvc );
+      double rmax = 0.; double zmax = 0.;
+      for (unsigned int i=0; i<envelopeDefs.size(); i++) { 
+	if ( envelopeDefs[i].first>rmax ) rmax= envelopeDefs[i].first;
+	if ( fabs(envelopeDefs[i].second)>zmax ) zmax= fabs(envelopeDefs[i].second);
+      }
+      if (envelopeDefs.size()) {
+        if ( rmax>0. && rmax <= aLVC.m_innerBarrelRadius && zmax>0. && zmax <= m_barrelZ ) {
+	  enclosedBounds = new Trk::CylinderVolumeBounds(rmax,zmax);
+	} else {
+	  ATH_MSG_INFO( name() << " input MSEntrance size (R,Z:"<< rmax <<","<<zmax<<") clashes with MS material, switch to default values (R,Z:" << aLVC.m_innerBarrelRadius <<","<< m_barrelZ << ")" );
+	}
+      }
+    }
+    
+    if (!enclosedBounds) enclosedBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+									m_barrelZ);
+    enclosed = new Trk::TrackingVolume(0,
+				       enclosedBounds,
+				       aLVC.m_muonMaterial,
+				       dummyLayers,dummyVolumes,
+				       m_entryVolume);
+    enclosed->registerColorCode(0); 
+    ATH_MSG_DEBUG( " register Barrel m_entryVolume " << m_entryVolume);
+  }
+
+  // construct inner and outer envelope
+    
+  for (unsigned int i=0; i<envelopeDefs.size(); i++) {
+    //ATH_MSG_VERBOSE( "Rz pair:"<< i<<":"<< envelopeDefs[i].first<<","<<envelopeDefs[i].second );   
+    if (aLVC.m_msCutoutsIn.size() && aLVC.m_msCutoutsIn.back().second== -aLVC.m_outerEndcapZ) break;
+    if ( !aLVC.m_msCutoutsIn.size() || fabs(aLVC.m_msCutoutsIn.back().second) > m_barrelZ
+	 || fabs(envelopeDefs[i].second)> m_barrelZ ) aLVC.m_msCutoutsIn.push_back(envelopeDefs[i]); 
+    else if (aLVC.m_msCutoutsIn.size() && aLVC.m_msCutoutsIn.back().second==m_barrelZ && aLVC.m_msCutoutsIn.back().first!=aLVC.m_innerBarrelRadius) {
+      aLVC.m_msCutoutsIn.push_back(RZPair(aLVC.m_innerBarrelRadius,m_barrelZ));
+      aLVC.m_msCutoutsIn.push_back(RZPair(aLVC.m_innerBarrelRadius,-m_barrelZ));
+      aLVC.m_msCutoutsIn.push_back(RZPair(aLVC.m_msCutoutsIn[aLVC.m_msCutoutsIn.size()-3].first,-m_barrelZ));
+    }
+  }
+
+  unsigned int il=1; 
+  while (envelopeDefs[il-1].second!=-aLVC.m_outerEndcapZ) il++;
+  for ( ; il<envelopeDefs.size(); il++)  aLVC.m_msCutoutsOut.push_back(envelopeDefs[il]); 
+
+  for (unsigned int i=0; i<aLVC.m_msCutoutsIn.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair for inner MS envelope:"<< i<<":"<< aLVC.m_msCutoutsIn[i].first<<","<<aLVC.m_msCutoutsIn[i].second );   
+  }
+  for (unsigned int i=0; i<aLVC.m_msCutoutsOut.size(); i++) {
+    ATH_MSG_VERBOSE( "Rz pair for outer MS envelope:"<< i<<":"<< aLVC.m_msCutoutsOut[i].first<<","<<aLVC.m_msCutoutsOut[i].second );   
+  }
+
+  if ( aLVC.m_msCutoutsIn[5].second != aLVC.m_innerEndcapZ) {
+    aLVC.m_innerEndcapZ = aLVC.m_msCutoutsIn[5].second;
+  }
+  ATH_MSG_VERBOSE( "inner endcap Z set to:"<< aLVC.m_innerEndcapZ );   
+  
+  // create central volume ("enclosed" + disk shields ) - this is to allow safe gluing with 3D MS binning
+  getShieldParts(aLVC);
+  
+  negDiskShieldBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+						      0.5*(m_diskShieldZ - m_barrelZ) );
+  Amg::Vector3D negDiskShieldPosition(0.,0.,-0.5*(m_diskShieldZ+m_barrelZ));
+  Trk::Volume negDiskVol(new Amg::Transform3D(Amg::Translation3D(negDiskShieldPosition)),negDiskShieldBounds);
+  negDiskShield = processShield(&negDiskVol,2,"Muons::Detectors::NegativeDiskShield",aLVC);
+
+  posDiskShieldBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+						      0.5*(m_diskShieldZ - m_barrelZ) );
+  Amg::Vector3D posDiskShieldPosition(0.,0., 0.5*(m_diskShieldZ+m_barrelZ));
+  Trk::Volume posDiskVol(new Amg::Transform3D(Amg::Translation3D(posDiskShieldPosition)),posDiskShieldBounds);
+  posDiskShield = processShield(&posDiskVol,2,"Muons::Detectors::PositiveDiskShield",aLVC);
+	   
+  ATH_MSG_INFO( name() << "glue enclosed  + disk shields" );
+  const Trk::TrackingVolume* centralP = m_trackingVolumeHelper->glueTrackingVolumeArrays(*enclosed, Trk::positiveFaceXY,
+											 *posDiskShield,Trk::negativeFaceXY, 
+											 "Muon::Container::CentralP");    
+  const Trk::TrackingVolume* central  = m_trackingVolumeHelper->glueTrackingVolumeArrays(*centralP, Trk::negativeFaceXY,
+											 *negDiskShield,Trk::positiveFaceXY, 
+											 "Muon::Container::Central");    
+  
+// define basic volumes
+  if (aLVC.m_adjustStatic) { getZParts(aLVC); getHParts(aLVC);}
+
+// muon barrel
+  barrelBounds = new Trk::CylinderVolumeBounds(aLVC.m_innerBarrelRadius,
+					       aLVC.m_outerBarrelRadius,
+					       m_diskShieldZ);
+  Trk::Volume barrelVol(0,barrelBounds);
+// process volume
+// barrel
+  if (aLVC.m_adjustStatic && aLVC.m_static3d) muonBarrel = processVolume( &barrelVol,0,"Muon::Detectors::Barrel",aLVC); 
+  else if (aLVC.m_adjustStatic) muonBarrel = processVolume( &barrelVol,-1,"Muon::Detectors::Barrel",aLVC); 
+  else muonBarrel = processVolume( &barrelVol,m_barrelEtaPartition,m_phiPartition,"Muon::Detectors::Barrel",aLVC); 
+// inner Endcap
+// build as smallWheel+ECT
+// small wheel
+   double smallWheelZHalfSize = 0.5*(m_ectZ - m_diskShieldZ);
+   negativeSmallWheelBounds = new Trk::CylinderVolumeBounds(m_innerShieldRadius,
+							    aLVC.m_outerBarrelRadius,
+							    smallWheelZHalfSize);
+   Amg::Vector3D negSmallWheelPosition(0.,0.,-m_ectZ+smallWheelZHalfSize);
+   Amg::Transform3D* negSmallWheelTransf = new Amg::Transform3D(Amg::Translation3D(negSmallWheelPosition));
+   Trk::Volume negSWVol(negSmallWheelTransf,negativeSmallWheelBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonSmallWheel = processVolume( &negSWVol,1,"Muon::Detectors::NegativeSmallWheel",aLVC ); 
+   else if (aLVC.m_adjustStatic) negativeMuonSmallWheel = processVolume( &negSWVol,-1,"Muon::Detectors::NegativeSmallWheel" ,aLVC); 
+   else negativeMuonSmallWheel = processVolume( &negSWVol,m_innerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeSmallWheel" ,aLVC); 
+   //checkVolume(negativeMuonSmallWheel);
+   //
+   Amg::Vector3D posSmallWheelShift(0.,0.,2*(m_ectZ-smallWheelZHalfSize));
+   Trk::Volume posSWVol(negSWVol,Amg::Transform3D(Amg::Translation3D(posSmallWheelShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonSmallWheel = processVolume( &posSWVol,1,"Muon::Detectors::PositiveSmallWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonSmallWheel = processVolume( &posSWVol,-1,"Muon::Detectors::PositiveSmallWheel" ,aLVC); 
+   else positiveMuonSmallWheel = processVolume( &posSWVol,m_innerEndcapEtaPartition,m_phiPartition,
+						 "Muon::Detectors::PositiveSmallWheel" ,aLVC); 
+   //checkVolume(positiveMuonSmallWheel);
+// ECT
+   double ectZHalfSize = 0.5*(aLVC.m_innerEndcapZ - m_ectZ);
+   negativeECTBounds = new Trk::CylinderVolumeBounds(m_innerShieldRadius,
+						     aLVC.m_outerBarrelRadius,
+						     ectZHalfSize);
+   Amg::Vector3D negECTPosition(0.,0.,-m_ectZ-ectZHalfSize);
+   Amg::Transform3D* negECTTransf = new Amg::Transform3D(Amg::Translation3D(negECTPosition));
+   Trk::Volume negECTVol(negECTTransf,negativeECTBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeECT = processVolume( &negECTVol,2,"Muon::Detectors::NegativeECT" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeECT = processVolume( &negECTVol,-1,"Muon::Detectors::NegativeECT" ,aLVC); 
+   else negativeECT = processVolume( &negECTVol,m_innerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeECT" ,aLVC); 
+   //checkVolume(negativeECT);
+   //
+   Amg::Vector3D posECTShift(0.,0.,2*(m_ectZ+ectZHalfSize));
+   Trk::Volume posECTVol(negECTVol,Amg::Transform3D(Amg::Translation3D(posECTShift)));
+   if (aLVC.m_adjustStatic && m_static3d) positiveECT = processVolume( &posECTVol,2,"Muon::Detectors::PositiveECT" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveECT = processVolume( &posECTVol,-1,"Muon::Detectors::PositiveECT" ,aLVC); 
+   else positiveECT = processVolume( &posECTVol,m_innerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::PositiveECT" ,aLVC); 
+   //checkVolume(positiveECT);
+   // glue
+   const Trk::TrackingVolume* negativeMuonInnerEndcap =
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeECT, Trk::positiveFaceXY,
+						      *negativeMuonSmallWheel, Trk::negativeFaceXY, 
+						      "Muon::Container::NegInnerEndcap");  
+   const Trk::TrackingVolume* positiveMuonInnerEndcap = 
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonSmallWheel, Trk::positiveFaceXY,
+						      *positiveECT, Trk::negativeFaceXY,
+						      "Muon::Container::PosInnerEndcap");  
+   
+// inner shields   
+   double innerEndcapZHalfSize = 0.5*(aLVC.m_innerEndcapZ - m_diskShieldZ);
+   negInnerShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_innerShieldRadius,
+							innerEndcapZHalfSize);
+   Amg::Vector3D negInnerEndcapPosition(0.,0.,-m_diskShieldZ-innerEndcapZHalfSize);
+   Trk::Volume negisVol(new Amg::Transform3D(Amg::Translation3D(negInnerEndcapPosition)),negInnerShieldBounds);
+   negInnerShield = processShield(&negisVol,1,"Muons::Detectors::NegativeInnerShield",aLVC);
+
+   posInnerShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_innerShieldRadius,
+							innerEndcapZHalfSize);
+   Amg::Vector3D posInnerEndcapPosition(0.,0.,m_diskShieldZ+innerEndcapZHalfSize);
+   Trk::Volume posisVol(new Amg::Transform3D(Amg::Translation3D(posInnerEndcapPosition)),posInnerShieldBounds);
+   posInnerShield = processShield(&posisVol,1,"Muons::Detectors::PositiveInnerShield",aLVC);
+
+// outer Endcap
+// build as bigWheel+buffer+outerWheel
+// outer wheel
+   double outerWheelZHalfSize = 0.5*(aLVC.m_outerEndcapZ - m_outerWheel);
+   negativeOuterWheelBounds = new Trk::CylinderVolumeBounds(m_outerShieldRadius,
+							    aLVC.m_outerBarrelRadius,
+							    outerWheelZHalfSize);
+   Amg::Vector3D negOuterWheelPosition(0.,0.,-aLVC.m_outerEndcapZ+outerWheelZHalfSize);
+   Amg::Transform3D* negOuterWheelTransf = new Amg::Transform3D(Amg::Translation3D(negOuterWheelPosition));
+   Trk::Volume negOWVol(negOuterWheelTransf,negativeOuterWheelBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonOuterWheel = processVolume( &negOWVol,3,"Muon::Detectors::NegativeOuterWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeMuonOuterWheel = processVolume( &negOWVol,-1,"Muon::Detectors::NegativeOuterWheel" ,aLVC); 
+   else negativeMuonOuterWheel = processVolume( &negOWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeOuterWheel" ,aLVC); 
+   //
+   Amg::Vector3D posOuterWheelShift(0.,0.,2*(aLVC.m_outerEndcapZ-outerWheelZHalfSize));
+   Trk::Volume posOWVol(negOWVol,Amg::Transform3D(Amg::Translation3D(posOuterWheelShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonOuterWheel = processVolume( &posOWVol,3,"Muon::Detectors::PositiveOuterWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonOuterWheel = processVolume( &posOWVol,-1,"Muon::Detectors::PositiveOuterWheel" ,aLVC); 
+   else positiveMuonOuterWheel = processVolume( &posOWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						 "Muon::Detectors::PositiveOuterWheel" ,aLVC); 
+// outer buffer
+   double outerBufferZHalfSize = 0.5*(m_outerWheel - m_bigWheel);
+   negativeOuterBufferBounds = new Trk::CylinderVolumeBounds(m_outerShieldRadius,
+							     aLVC.m_outerBarrelRadius,
+							     outerBufferZHalfSize);
+   Amg::Vector3D negOuterBufferPosition(0.,0.,-m_bigWheel-outerBufferZHalfSize);
+   Amg::Transform3D* negOuterBufferTransf = new Amg::Transform3D(Amg::Translation3D(negOuterBufferPosition));
+   Trk::Volume negBuffVol(negOuterBufferTransf,negativeOuterBufferBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonOuterBuffer = processVolume( &negBuffVol,3,"Muon::Detectors::NegativeOuterBuffer" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeMuonOuterBuffer = processVolume( &negBuffVol,-1,"Muon::Detectors::NegativeOuterBuffer" ,aLVC); 
+   else negativeMuonOuterBuffer = processVolume( &negBuffVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeOuterBuffer" ,aLVC); 
+   //
+   Amg::Vector3D posOuterBufferShift(0.,0.,2*(m_bigWheel+outerBufferZHalfSize));
+   Trk::Volume posBuffVol(negBuffVol,Amg::Transform3D(Amg::Translation3D(posOuterBufferShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonOuterBuffer = processVolume( &posBuffVol,3,"Muon::Detectors::PositiveOuterBuffer" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonOuterBuffer = processVolume( &posBuffVol,-1,"Muon::Detectors::PositiveOuterBuffer" ,aLVC); 
+   else positiveMuonOuterBuffer = processVolume( &posBuffVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::PositiveOuterBuffer" ,aLVC); 
+// big wheel
+   double bigWheelZHalfSize = 0.5*(m_bigWheel - aLVC.m_innerEndcapZ);
+   negativeBigWheelBounds = new Trk::CylinderVolumeBounds(m_outerShieldRadius,
+							  aLVC.m_outerBarrelRadius,
+							  bigWheelZHalfSize);
+   Amg::Vector3D negBigWheelPosition(0.,0.,-aLVC.m_innerEndcapZ-bigWheelZHalfSize);
+   Amg::Transform3D* negBigWheelTransf = new Amg::Transform3D(Amg::Translation3D(negBigWheelPosition));
+   Trk::Volume negBWVol(negBigWheelTransf,negativeBigWheelBounds);
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) negativeMuonBigWheel = processVolume( &negBWVol,3,"Muon::Detectors::NegativeBigWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) negativeMuonBigWheel = processVolume( &negBWVol,-1,"Muon::Detectors::NegativeBigWheel" ,aLVC); 
+   else negativeMuonBigWheel = processVolume( &negBWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						"Muon::Detectors::NegativeBigWheel" ,aLVC); 
+   //
+   Amg::Vector3D posBigWheelShift(0.,0.,2*(aLVC.m_innerEndcapZ+bigWheelZHalfSize));
+   Trk::Volume posBWVol(negBWVol,Amg::Transform3D(Amg::Translation3D(posBigWheelShift)));
+   if (aLVC.m_adjustStatic && aLVC.m_static3d) positiveMuonBigWheel = processVolume( &posBWVol,3,"Muon::Detectors::PositiveBigWheel" ,aLVC); 
+   else if (aLVC.m_adjustStatic) positiveMuonBigWheel = processVolume( &posBWVol,-1,"Muon::Detectors::PositiveBigWheel" ,aLVC); 
+   else positiveMuonBigWheel = processVolume( &posBWVol,m_outerEndcapEtaPartition,m_phiPartition,
+						 "Muon::Detectors::PositiveBigWheel" ,aLVC); 
+// glue
+   const Trk::TrackingVolume* negNavOEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeMuonOuterWheel, Trk::positiveFaceXY,
+											       *negativeMuonOuterBuffer, Trk::negativeFaceXY, 
+											       "Muon::Container::NegOEndcap");  
+   const Trk::TrackingVolume* posNavOEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonOuterBuffer, Trk::positiveFaceXY,
+											       *positiveMuonOuterWheel, Trk::negativeFaceXY,
+											       "Muon::Container::PosOEndcap");  
+   const Trk::TrackingVolume* negativeMuonOuterEndcap =
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*negNavOEndcap, Trk::positiveFaceXY,
+						      *negativeMuonBigWheel, Trk::negativeFaceXY, 
+						      "Muon::Container::NegOuterEndcap");  
+   const Trk::TrackingVolume* positiveMuonOuterEndcap =
+     m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonBigWheel, Trk::positiveFaceXY, 
+						      *posNavOEndcap, Trk::negativeFaceXY,
+						      "Muon::Container::PosOuterEndcap");  
+
+// outer shields   
+   double outerEndcapZHalfSize = 0.5*(aLVC.m_outerEndcapZ-aLVC.m_innerEndcapZ);
+   double outerEndcapPosition  = 0.5*(aLVC.m_outerEndcapZ+aLVC.m_innerEndcapZ);
+   Amg::Vector3D negOuterShieldPosition(0.,0.,-outerEndcapPosition);
+   negOuterShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_outerShieldRadius,
+							outerEndcapZHalfSize);
+   Trk::Volume negosVol(new Amg::Transform3D(Amg::Translation3D(negOuterShieldPosition)),negOuterShieldBounds);
+   negOuterShield = processShield(&negosVol,0,"Muons::Detectors::NegativeOuterShield",aLVC);
+
+   posOuterShieldBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+							m_outerShieldRadius,
+							outerEndcapZHalfSize);
+   Amg::Vector3D posOuterShieldPosition(0.,0.,outerEndcapPosition);
+   Trk::Volume pososVol(new Amg::Transform3D(Amg::Translation3D(posOuterShieldPosition)),posOuterShieldBounds);
+   posOuterShield = processShield(&pososVol,0,"Muons::Detectors::PositiveOuterShield",aLVC);
+
+// beamPipe
+   negBeamPipeBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+                                                  outerEndcapZHalfSize+innerEndcapZHalfSize);
+   posBeamPipeBounds = new Trk::CylinderVolumeBounds(m_beamPipeRadius,
+                                                  outerEndcapZHalfSize+innerEndcapZHalfSize);
+   Amg::Vector3D posBeamPipePosition(0.,0., aLVC.m_outerEndcapZ-innerEndcapZHalfSize-outerEndcapZHalfSize);
+   Amg::Vector3D negBeamPipePosition(0.,0.,-aLVC.m_outerEndcapZ+innerEndcapZHalfSize+outerEndcapZHalfSize);
+   Trk::Volume negbpVol(new Amg::Transform3D(Amg::Translation3D(negBeamPipePosition)),negBeamPipeBounds);
+   negBeamPipe = processVolume(&negbpVol,1,1,"Muons::Gaps::NegativeBeamPipe",aLVC);
+   Trk::Volume posbpVol(new Amg::Transform3D(Amg::Translation3D(posBeamPipePosition)),posBeamPipeBounds);
+   posBeamPipe = processVolume(&posbpVol,1,1,"Muons::Gaps::PositiveBeamPipe",aLVC);
+
+   negBeamPipe->registerColorCode(0); 
+   posBeamPipe->registerColorCode(0); 
+
+   ATH_MSG_INFO( name() <<" volumes defined " );    
+//
+// glue volumes at navigation level, create enveloping volume 
+// radially
+// central + barrel
+   ATH_MSG_INFO( name() << "glue barrel+enclosed volumes" );
+   const Trk::TrackingVolume* barrel = m_trackingVolumeHelper->glueTrackingVolumeArrays(*muonBarrel,Trk::tubeInnerCover,
+											*central, Trk::cylinderCover, 
+                                                                                        "All::Container::Barrel");
+   //checkVolume(barrel);
+// shield+outerEndcap
+   ATH_MSG_INFO( name() << "glue shield+outerEndcap" );
+   const Trk::TrackingVolume* negOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeMuonOuterEndcap, Trk::tubeInnerCover,
+												*negOuterShield, Trk::tubeOuterCover,
+												"Muon::Container::NegativeOuterEndcap");
+   //checkVolume(negOuterEndcap);
+   const Trk::TrackingVolume* posOuterEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonOuterEndcap, Trk::tubeInnerCover,
+												*posOuterShield,Trk::tubeOuterCover,
+												"Muon::Container::PositiveOuterEndcap");
+   //checkVolume(posOuterEndcap);
+// shield+innerEndcap
+   ATH_MSG_INFO( name() << "glue shield+innerEndcap" );
+   const Trk::TrackingVolume* negInnerEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negativeMuonInnerEndcap, Trk::tubeInnerCover,
+												*negInnerShield, Trk::tubeOuterCover,
+												"Muon::Container::NegativeInnerEndcap");
+   //checkVolume(negInnerEndcap);
+   const Trk::TrackingVolume* posInnerEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*positiveMuonInnerEndcap, Trk::tubeInnerCover,
+												*posInnerShield,Trk::tubeOuterCover,
+												"Muon::Container::PositiveInnerEndcap");
+   //checkVolume(posInnerEndcap);
+// inner+outerEndcap
+   ATH_MSG_INFO( name() << "glue inner+outerEndcap" );
+   const Trk::TrackingVolume* negNavEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negOuterEndcap, Trk::positiveFaceXY,
+											      *negInnerEndcap, Trk::negativeFaceXY, 
+											      "Muon::Container::NegativeEndcap");  
+   const Trk::TrackingVolume* posNavEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*posInnerEndcap, Trk::positiveFaceXY,
+											      *posOuterEndcap, Trk::negativeFaceXY,
+											      "Muon::Container::PositiveEndcap");  
+   //checkVolume(negNavEndcap);
+   //checkVolume(posNavEndcap);
+// beam pipe + endcaps
+   ATH_MSG_INFO( name() << "glue beamPipe+endcaps" );
+   const Trk::TrackingVolume* negEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negNavEndcap, Trk::tubeInnerCover,
+											   *negBeamPipe, Trk::cylinderCover,
+										           "All::Container::NegativeEndcap");  
+   const Trk::TrackingVolume* posEndcap = m_trackingVolumeHelper->glueTrackingVolumeArrays(*posNavEndcap, Trk::tubeInnerCover,
+											   *posBeamPipe, Trk::cylinderCover,
+										           "All::Container::PositiveEndcap");  
+   //checkVolume(negEndcap);
+   //checkVolume(posEndcap);
+// barrel + endcaps
+   ATH_MSG_INFO( name() << "glue barrel+endcaps" );
+
+   const Trk::TrackingVolume* negDet = m_trackingVolumeHelper->glueTrackingVolumeArrays(*negEndcap, Trk::positiveFaceXY,
+                                                                                        *barrel, Trk::negativeFaceXY, 
+									                "All::Container::NegDet");  
+   const Trk::TrackingVolume* detector = m_trackingVolumeHelper->glueTrackingVolumeArrays(*posEndcap, Trk::negativeFaceXY, 
+											  *negDet, Trk::positiveFaceXY,
+											  m_exitVolume);
+// blend material
+   if (m_blendInertMaterial) blendMaterial(aLVC);
+
+// tracking geometry 
+   Trk::TrackingGeometry* trackingGeometry = new Trk::TrackingGeometry(detector,Trk::globalSearch);
+
+// clean-up
+   if (aLVC.m_stationSpan) {
+     for (size_t i = 0; i < aLVC.m_stationSpan->size(); i++)
+       delete (*aLVC.m_stationSpan)[i];
+     delete aLVC.m_stationSpan; aLVC.m_stationSpan = 0;
+   }
+   if (aLVC.m_inertSpan) {
+     for (size_t i = 0; i < aLVC.m_inertSpan->size(); i++)
+       delete (*aLVC.m_inertSpan)[i];
+     delete aLVC.m_inertSpan; aLVC.m_inertSpan = 0;
+   }
+   
+   for (size_t i = 0; i < aLVC.m_spans.size(); i++) delete aLVC.m_spans[i];
+   
+   for (std::map<const Trk::DetachedTrackingVolume*,std::vector<const Trk::TrackingVolume*>* >::iterator it = aLVC.m_blendMap.begin();
+	it != aLVC.m_blendMap.end();
+	++it)
+     {
+       delete it->second;
+     }   
+
+   m_chronoStatSvc->chronoStop("MS::build-up");
+
+   ATH_MSG_INFO( name() <<" returning tracking geometry " );    
+   ATH_MSG_INFO( name() <<" with "<< m_frameNum<<" subvolumes at navigation level" );    
+   ATH_MSG_INFO( name() <<"( mean number of enclosed detached volumes:"<< float(m_frameStat)/m_frameNum<<")" );    
+   return std::make_pair(range, trackingGeometry);  
+}
+
+// finalize
+StatusCode Muon::MuonTrackingGeometryBuilderCond::finalize()
+{
+    if (m_stations) {
+      for (size_t i = 0; i < m_stations->size(); i++) {
+	if ((*m_stations)[i]) delete (*m_stations)[i];
+        else ATH_MSG_DEBUG( name() << " station pointer corrupted ! " ); 
+      }
+      delete m_stations; m_stations = 0;
+    } 
+    if (m_inertObjs) {
+      unsigned int inLim = (m_blendInertMaterial && m_removeBlended) ? (unsigned int)m_inertPerm : m_inertObjs->size();
+      for (size_t i = 0; i < inLim; i++) {
+	if ((*m_inertObjs)[i])	delete (*m_inertObjs)[i];
+        else ATH_MSG_DEBUG( name() << " inert object pointer corrupted ! " ); 
+      }
+      delete m_inertObjs; m_inertObjs = 0;
+    } 
+
+    m_chronoStatSvc->chronoPrint("MS::build-up");
+
+    ATH_MSG_INFO( name() <<" finalize() successful" );
+    return StatusCode::SUCCESS;
+}
+const Muon::Span* Muon::MuonTrackingGeometryBuilderCond::findVolumeSpan(const Trk::VolumeBounds* volBounds, Amg::Transform3D transform, double zTol, double phiTol, LocalVariablesContainer &aLVC) const
+{
+  if (!volBounds) return 0;
+  // volume shape
+  const Trk::CuboidVolumeBounds* box = dynamic_cast<const Trk::CuboidVolumeBounds*> (volBounds);
+  const Trk::TrapezoidVolumeBounds* trd = dynamic_cast<const Trk::TrapezoidVolumeBounds*> (volBounds);
+  const Trk::DoubleTrapezoidVolumeBounds* dtrd = dynamic_cast<const Trk::DoubleTrapezoidVolumeBounds*> (volBounds);
+  const Trk::BevelledCylinderVolumeBounds* bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (volBounds);
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (volBounds);
+  const Trk::SubtractedVolumeBounds* sub = dynamic_cast<const Trk::SubtractedVolumeBounds*> (volBounds);
+  const Trk::CombinedVolumeBounds* comb = dynamic_cast<const Trk::CombinedVolumeBounds*> (volBounds);
+  const Trk::SimplePolygonBrepVolumeBounds* spb = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*> (volBounds);
+  const Trk::PrismVolumeBounds* prism = dynamic_cast<const Trk::PrismVolumeBounds*> (volBounds);
+
+  if(box)  ATH_MSG_VERBOSE(" findVolumeSpan box " );
+  if(trd)  ATH_MSG_VERBOSE(" findVolumeSpan trd " );
+  if(dtrd) ATH_MSG_VERBOSE( " findVolumeSpan dtrd " );
+  if(bcyl) ATH_MSG_VERBOSE(" findVolumeSpan bcyl " );
+  if(cyl)  ATH_MSG_VERBOSE(" findVolumeSpan cyl " );
+  if(sub)  ATH_MSG_VERBOSE(" findVolumeSpan sub " );
+  if(comb) ATH_MSG_VERBOSE(" findVolumeSpan comb " );
+  if(spb)  ATH_MSG_VERBOSE(" findVolumeSpan spb " );
+  if(prism) ATH_MSG_VERBOSE(" findVolumeSpan prism " );
+
+  if (sub) return findVolumeSpan(&(sub->outer()->volumeBounds()),transform*sub->outer()->transform(),zTol,phiTol,aLVC);
+
+  if (comb) {
+    const Muon::Span* s1 = findVolumeSpan(&(comb->first()->volumeBounds()),transform*comb->first()->transform(),zTol,phiTol,aLVC);     
+    const Muon::Span* s2 = findVolumeSpan(&(comb->second()->volumeBounds()),transform*comb->second()->transform(),zTol,phiTol,aLVC);     
+
+    ATH_MSG_VERBOSE( "Combined span1:"<<name()<< ","<<(*s1)[0]<<","<< (*s1)[1]<<","<<(*s1)[2]<<"," << (*s1)[3]<<","<< (*s1)[4]<<","<< (*s1)[5]);
+    ATH_MSG_VERBOSE( "Combined span2:"<<name()<< ","<<(*s2)[0]<<","<< (*s2)[1]<<","<<(*s2)[2]<<"," << (*s2)[3]<<","<< (*s2)[4]<<","<< (*s2)[5]);
+
+    Muon::Span scomb;
+    scomb.reserve(6); 
+    scomb.push_back(fmin((*s1)[0],(*s2)[0]));
+    scomb.push_back(fmax((*s1)[1],(*s2)[1]));
+    scomb.push_back(fmin((*s1)[2],(*s2)[2]));
+    scomb.push_back(fmax((*s1)[3],(*s2)[3]));
+    scomb.push_back(fmin((*s1)[4],(*s2)[4]));
+    scomb.push_back(fmax((*s1)[5],(*s2)[5]));
+    return new Muon::Span(scomb);
+  }
+
+  // loop over edges ...
+  double minZ = aLVC.m_outerEndcapZ ; double maxZ = - aLVC.m_outerEndcapZ;
+  double minPhi = 2*M_PI; double maxPhi = 0.;
+  double minR = aLVC.m_outerBarrelRadius; double maxR = 0.;
+  std::vector<Amg::Vector3D> edges;
+  edges.reserve(16);
+  Muon::Span span;  
+  span.reserve(6); 
+  
+  double cylZcorr = 0.; 
+  if (box) {
+    edges.push_back( Amg::Vector3D(box->halflengthX(),box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(box->halflengthX(),-box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),-box->halflengthY(),box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(box->halflengthX(),box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(box->halflengthX(),-box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),-box->halflengthY(),-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0.,-box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0., box->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-box->halflengthX(),0.,0.) );
+    edges.push_back( Amg::Vector3D( box->halflengthX(),0.,0.) );
+    edges.push_back( Amg::Vector3D(0.,-box->halflengthY(),0.) );
+    edges.push_back( Amg::Vector3D(0., box->halflengthY(),0.) );
+  }
+  if (trd) {
+//     std::cout <<  " Trapezoid minHalflengthX " << trd->minHalflengthX() << " maxHalflengthX() " << trd->maxHalflengthX() << " halflengthY() " << trd->halflengthY() << " halflengthZ " << trd->halflengthZ() << std::endl;
+  
+    edges.push_back( Amg::Vector3D(trd->maxHalflengthX(),trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->maxHalflengthX(),trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(trd->minHalflengthX(),-trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->minHalflengthX(),-trd->halflengthY(),trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(trd->maxHalflengthX(),trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->maxHalflengthX(),trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(trd->minHalflengthX(),-trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-trd->minHalflengthX(),-trd->halflengthY(),-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0.,-trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0., trd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-0.5*(trd->minHalflengthX()-trd->maxHalflengthX()),0.,0.) );
+    edges.push_back( Amg::Vector3D( 0.5*(trd->minHalflengthX()-trd->maxHalflengthX()),0.,0.) );
+    edges.push_back( Amg::Vector3D(0.,-trd->halflengthY(),0.) );
+    edges.push_back( Amg::Vector3D(0., trd->halflengthY(),0.) );
+  }
+  if (dtrd) {
+    edges.push_back( Amg::Vector3D( dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->medHalflengthX(),0.,dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->medHalflengthX(),0.,dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->maxHalflengthX(),2*dtrd->halflengthY2(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->medHalflengthX(),0.,-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->medHalflengthX(),0.,-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D( dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(-dtrd->minHalflengthX(),-2*dtrd->halflengthY1(),-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0.,-dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,0., dtrd->halflengthZ()) );
+    edges.push_back( Amg::Vector3D(0.,-2*dtrd->halflengthY1(),0.) );
+    edges.push_back( Amg::Vector3D(0., 2*dtrd->halflengthY2(),0.) );
+  }
+  if (bcyl) {
+    edges.push_back( Amg::Vector3D(0.,0.,bcyl->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-bcyl->halflengthZ()));
+  }
+  if (cyl) {
+    edges.push_back( Amg::Vector3D(0.,0.,cyl->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-cyl->halflengthZ()));
+  }
+  if (spb) {
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#define double float
+#endif      
+    const std::vector<std::pair<double, double> > vtcs = spb->xyVertices();
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#undef double
+#endif      
+    for (unsigned int i=0;i<vtcs.size();i++) {
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, spb->halflengthZ()) );
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, -spb->halflengthZ()) );
+    }
+// center
+    edges.push_back( Amg::Vector3D(0.,0.,spb->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-spb->halflengthZ()));
+
+  }
+  if (prism) {
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#define double float
+#endif  
+    const std::vector<std::pair<double, double> > vtcs = prism->xyVertices();
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#undef double
+#endif      
+    for (unsigned int i=0;i<vtcs.size();i++) {
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, prism->halflengthZ()) );
+      edges.push_back( Amg::Vector3D(vtcs[i].first,vtcs[i].second, -prism->halflengthZ()) );
+    }
+    edges.push_back( Amg::Vector3D(0.,0.,prism->halflengthZ()));
+    edges.push_back( Amg::Vector3D(0.,0.,-prism->halflengthZ()));
+
+  }
+  // apply transform and get span
+  double minP0=M_PI; double maxP0 = 0.; double minP1=2*M_PI; double maxP1=M_PI;
+  // determine phiStep for prism and spb
+  double phiStep = 0.;
+  for (unsigned int ie=0; ie < edges.size() ; ie++) {
+    Amg::Vector3D gp = transform*edges[ie];
+    double phi = gp.phi()+M_PI; 
+
+    ATH_MSG_VERBOSE( " local edges:"<< ie<<" x "<< edges[ie].x() << " y " << edges[ie].y() << " z " << edges[ie].z() << " phi "<< edges[ie].phi());
+    ATH_MSG_VERBOSE( " Global edges:"<< ie<<" x "<< gp.x() << " y " << gp.y() << " z " << gp.z() << " phi position + pi "<< phi);
+
+    if(ie>0&&phiStep<0.001) {
+       double phin = (transform*edges[ie-1]).phi() - M_PI;
+       double cph = cos(phi)*cos(phin) + sin(phi)*sin(phin);
+       phiStep = fabs(cph)<=1 ? acos(cph) : M_PI;     // TODO check this logic  
+       ATH_MSG_VERBOSE( " "<< ie<<" phiStep  "<< phiStep );
+    }
+    double rad = gp.perp();
+    if (cyl || bcyl) {
+      double radius = 0.; double hz = 0.;
+      Amg::Vector3D dir = (transform*Amg::Vector3D(0.,0.,1.));
+      double thAx = dir.theta();
+      if (cyl) { radius = cyl->outerRadius(); hz = cyl->halflengthZ();}
+      if (bcyl) { radius = bcyl->outerRadius(); hz = bcyl->halflengthZ();}
+      if ( gp[2]-radius*sin(thAx) <minZ ) minZ = gp[2]-radius*sin(thAx);
+      if ( gp[2]+radius*sin(thAx) >maxZ ) maxZ = gp[2]+radius*sin(thAx);
+      if ( rad-radius*fabs(cos(thAx)) < minR )  minR = rad>radius ? rad-radius*fabs(cos(thAx)): 0;
+      if ( rad+radius*fabs(cos(thAx)) > maxR )  maxR = rad+radius*fabs(cos(thAx));
+      // distance of cylinder axis and global axis
+      if (dir.perp()>0.001) {
+        // distance to minimal approach
+        double dMA = fabs(dir[0]*gp[0]+dir[1]*gp[1])/dir.perp()/dir.perp();
+        double dMD = sqrt (fmax(0.,gp.perp()*gp.perp()-dMA*dMA));
+        if (dMA<2*hz && dMD-radius < minR ) minR = fmax(0.,dMD-radius); 
+      } 
+      double dph = rad>0.001 ? atan(radius/rad) : M_PI;
+      if ( phi-dph <M_PI && phi-dph < minP0 ) minP0 = phi-dph;
+      if ( phi+dph <M_PI && phi+dph > maxP0 ) maxP0 = phi+dph;
+      if ( phi-dph >M_PI && phi-dph < minP1 ) minP1 = phi-dph;
+      if ( phi+dph >M_PI && phi+dph > maxP1 ) maxP1 = phi+dph;      
+    } else {
+      if ( gp[2]<minZ ) minZ = gp[2];
+      if ( gp[2]>maxZ ) maxZ = gp[2];
+      if ( phi<M_PI && phi < minP0 ) minP0 = phi; 
+      if ( phi<M_PI && phi > maxP0 ) maxP0 = phi; 
+      if ( phi>M_PI && phi < minP1 ) minP1 = phi; 
+      if ( phi>M_PI && phi > maxP1 ) maxP1 = phi; 
+      //if ( phi < minPhi ) minPhi = phi; 
+      //if ( phi > maxPhi ) maxPhi = phi; 
+      if ( rad < minR ) minR = rad; 
+      if ( rad > maxR ) maxR = rad;
+    } 
+  }
+  if (maxPhi<minPhi) {
+    if (maxP0>=minP0 && maxP1<minP1) { minPhi = minP0; maxPhi = maxP0; }
+    else if ( maxP1>=minP1 && maxP0<minP0) { minPhi = minP1; maxPhi = maxP1; }
+    else if ( maxP1 - minP0 < (maxP0 - minP1+2*M_PI) ) { minPhi = minP0; maxPhi = maxP1; }
+    else { minPhi = minP1 ; maxPhi = maxP0; }  
+    if (maxPhi<0.001 && minPhi>2*M_PI-0.001) {minPhi=0; maxPhi=2*M_PI;}
+  }
+//
+// correct edges for spb or prism
+//
+  if(spb||prism) {
+    if(minP0<phiStep&&2*M_PI-maxP1<phiStep) {
+      minPhi = 0.;
+      maxPhi = 2*M_PI;
+    }
+  }
+
+  if ( box || trd || dtrd || spb ) {
+    span.push_back( minZ - zTol );  
+    span.push_back( maxZ + zTol );  
+    span.push_back( minPhi - phiTol );  
+    span.push_back( maxPhi + phiTol );  
+    span.push_back( fmax(m_beamPipeRadius+0.001, minR - zTol) );  
+    span.push_back( maxR + zTol );  
+  } else if (bcyl || cyl ) {
+    span.push_back( minZ - cylZcorr -zTol );
+    span.push_back( maxZ + cylZcorr +zTol );
+    span.push_back( minPhi - phiTol );
+    span.push_back( maxPhi + phiTol );
+    span.push_back( fmax(m_beamPipeRadius+0.001, minR - zTol) );  
+    span.push_back( maxR + zTol );  
+  } else {
+    ATH_MSG_ERROR( name() <<" volume shape not recognized: ");
+    for (int i=0; i<6; i++) span.push_back(0.);
+  }
+  const Muon::Span* newSpan=new Muon::Span(span);
+  return newSpan;
+}
+
+const std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Muon::Span*> >* >* Muon::MuonTrackingGeometryBuilderCond::findVolumesSpan(const std::vector<const Trk::DetachedTrackingVolume*>* objs, double zTol, double phiTol, LocalVariablesContainer &aLVC) const
+{
+
+  if (!objs || !objs->size()) return 0;
+  std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >* spans =
+   new std::vector<std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >* >(9);
+  // split MS into 9 blocks to speed up the build-up of geometry
+  for (unsigned int i=0;i<9;i++) (*spans)[i] = new std::vector<std::pair<const Trk::DetachedTrackingVolume*,const Span*> >; 
+  for (unsigned int iobj=0; iobj<objs->size(); iobj++) {
+    Amg::Transform3D  transform = (*objs)[iobj]->trackingVolume()->transform();
+    const Muon::Span* span = findVolumeSpan(&((*objs)[iobj]->trackingVolume()->volumeBounds()), transform, zTol, phiTol, aLVC);
+    double x0 = (*objs)[iobj]->trackingVolume()->X0;
+    double intX0 = fabs((*span)[0]-(*span)[1])/(x0+0.000000001);
+    double l0 = (*objs)[iobj]->trackingVolume()->L0;
+    ATH_MSG_DEBUG( "span:"<<(*objs)[iobj]->name()<< ","<<(*span)[0]<<","<< (*span)[1]<<","<<(*span)[2]<<","
+     << (*span)[3]<<","<< (*span)[4]<<","<< (*span)[5] << " X0 " << x0 << " L0 "<< l0 << " intX0 for span0 span1 " << intX0 );
+
+    int nspans = 0;
+    // negative outer wheel
+    if ( (*span)[0] < -m_bigWheel ) {
+        (*spans)[0]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // negative big wheel
+    if ( (*span)[0] < -aLVC.m_innerEndcapZ && (*span)[1]>-m_bigWheel ) {
+        (*spans)[1]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // neg.ect
+    if ( (*span)[0] < -m_ectZ && (*span)[1]>-aLVC.m_innerEndcapZ ) {
+        (*spans)[2]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // neg.small wheel
+    if ( (*span)[0] < -m_diskShieldZ && (*span)[1]>-m_ectZ ) {
+        (*spans)[3]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // barrel  
+    if ( (*span)[0] <  m_diskShieldZ && (*span)[1]> -m_diskShieldZ ) {
+//	 && ((*span)[5]> m_innerBarrelRadius || (*span)[0]<-m_barrelZ || (*span)[1]>m_barrelZ)  ) {
+        (*spans)[4]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // pos.small wheel
+    if ( (*span)[0] < m_ectZ && (*span)[1]> m_diskShieldZ ) {
+        (*spans)[5]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // pos.ect
+    if ( (*span)[0] < aLVC.m_innerEndcapZ && (*span)[1]> m_ectZ ) {
+        (*spans)[6]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // positive big wheel
+    if ( (*span)[0] < m_bigWheel && (*span)[1]> aLVC.m_innerEndcapZ ) {
+        (*spans)[7]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+    // positive outer wheel
+    if ( (*span)[1] >  m_bigWheel ) {
+        (*spans)[8]->push_back(std::pair<const Trk::DetachedTrackingVolume*,const Span*>((*objs)[iobj],span));
+        nspans++;
+    } 
+
+    if(nspans == 0) ATH_MSG_WARNING( " object not selected in span regions " << (*objs)[iobj]->name() );
+    if(nspans > 1) ATH_MSG_VERBOSE( " object selected in " << nspans << " span regions " << (*objs)[iobj]->name() );
+
+    aLVC.m_spans.push_back(span);                 // keep track of things to delete
+  }
+
+  return spans;
+}
+
+
+const Trk::TrackingVolume* Muon::MuonTrackingGeometryBuilderCond::processVolume(const Trk::Volume* vol, int etaN , int phiN, std::string volumeName, LocalVariablesContainer& aLVC) const
+{
+
+  const Trk::TrackingVolume* tVol = 0;
+
+  unsigned int colorCode = m_colorCode;
+
+  std::vector<const Trk::DetachedTrackingVolume*> blendVols; 
+
+  // partitions ? include protection against wrong setup
+  if (etaN < 1 || phiN < 1) {
+    ATH_MSG_ERROR( name() << "wrong partition setup" );
+    etaN = 1;
+    phiN = 1;
+  }
+  if ( etaN * phiN > 1 ) {  // partition
+    const Trk::CylinderVolumeBounds* cyl=dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+    if (!cyl) {
+      ATH_MSG_ERROR( " process volume: volume cylinder boundaries not retrieved, return 0 " );
+      return 0; 
+    }
+    // subvolume boundaries
+    Trk::CylinderVolumeBounds* subBds = 0;
+
+    double phiSect = M_PI/phiN;
+    double etaSect = (cyl->halflengthZ())/etaN;
+
+    subBds = new Trk::CylinderVolumeBounds(cyl->innerRadius(), cyl->outerRadius(), phiSect,etaSect);
+    const Trk::Volume* protVol= new Trk::Volume(0, subBds);     
+
+    // create subvolumes & BinnedArray
+    std::vector<Trk::TrackingVolumeOrderPosition> subVolumes;
+    std::vector<const Trk::TrackingVolume*> sVols;                // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsNeg;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsPos;             // for gluing
+    for (int eta = 0; eta < etaN; eta++) {
+      if (colorCode>0) colorCode = 26 - colorCode;
+      // reference point for the check of envelope
+      double posZ = (vol->center())[2]+ etaSect * (2.*eta+1.-etaN) ;
+      double posR = 0.5*(cyl->innerRadius()+cyl->outerRadius());
+      int geoSignature = 4;
+      // loop over inner cutouts
+      for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+        if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+          if (posR < aLVC.m_msCutoutsIn[in].first) geoSignature=2;
+          break;
+	}
+      }
+      if (geoSignature == 4) {
+	// loop over outer cutouts
+	for (unsigned int io=1; io<aLVC.m_msCutoutsOut.size(); io++) {
+	  if (posZ>=aLVC.m_msCutoutsOut[io-1].second && posZ<=aLVC.m_msCutoutsOut[io].second) {
+	    if (posR > aLVC.m_msCutoutsOut[io].first) geoSignature=5;
+	    break;
+	  }
+	}
+      }
+      for (int phi = 0; phi < phiN; phi++) {
+	if (colorCode>0) colorCode = 26 - colorCode;
+        // define subvolume
+        Amg::Transform3D  transf(Amg::AngleAxis3D(phiSect*(2*phi+1), Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+        const Trk::Volume* subVol= new Trk::Volume(*protVol, transf);     
+        // enclosed muon objects ?   
+	std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) ; 
+        blendVols.clear();
+        std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( subVol, blendVols,aLVC);
+        const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( *subVol,
+								   aLVC.m_muonMaterial,
+								   detVols,
+								   volName );
+        // statistics
+        m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+        // prepare blending
+        if (m_blendInertMaterial && blendVols.size()) {
+          for (unsigned int id=0;id<blendVols.size();id++) {
+	    if (!aLVC.m_blendMap[blendVols[id]]) {
+	      aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+              aLVC.m_blendVols.push_back(blendVols[id]);
+	    }
+	    aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	  }
+	}  
+        //
+        if (geoSignature == 2) sVol->sign(Trk::BeamPipe);
+        if (geoSignature == 5) sVol->sign(Trk::Cavern);
+        sVol->registerColorCode(colorCode); 
+	// reference position 
+	Amg::Vector3D gp(subBds->outerRadius(),0.,0.);
+	//subVolumes.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, true),
+  //                                                           Amg::Vector3D(transf*gp)));
+  /* The above was passing a SharedObject with the ndel == True
+   * now that SharedObject is a typeded to std::shared_ptr , pass a no-op deleter
+   */
+  subVolumes.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, Trk::do_not_delete<const Trk::TrackingVolume>),
+                                                        Amg::Vector3D(transf*gp)));
+       //glue subVolumes
+        sVols.push_back(sVol); 
+        if (eta==0)      sVolsNeg.push_back(sVol); 
+        if (eta==etaN-1) sVolsPos.push_back(sVol); 
+        // in phi        
+        if ( phiN>1 && phi>0) {
+          m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::tubeSectorNegativePhi,
+						      *(sVols[eta*phiN+phi-1]), Trk::tubeSectorPositivePhi);
+          if ( phi==phiN-1 )  m_trackingVolumeHelper->glueTrackingVolumes(*(sVols[eta*phiN]), Trk::tubeSectorNegativePhi,
+                                                                          *sVol, Trk::tubeSectorPositivePhi);
+	}
+        // in eta
+        if ( etaN>1 && eta>0) m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::negativeFaceXY,
+						      *(sVols[(eta-1)*phiN+phi]), Trk::positiveFaceXY);        
+        //
+	delete subVol; //shouldn't need this any more
+      }
+    }
+
+    //Trk::BinUtility2DPhiZ* volBinUtil=new Trk::BinUtility2DPhiZ(phiN,etaN,subBds->outerRadius(),cyl->halflengthZ(),M_PI, new Amg::Transform3D(vol->transform()));
+    Trk::BinUtility buPhi( phiN, -M_PI, M_PI, Trk::closed, Trk::binPhi ); 
+    const Trk::BinUtility   buZ( etaN, vol->transform().translation()[2]-cyl->halflengthZ(), 
+                                        vol->transform().translation()[2]+cyl->halflengthZ(), Trk::open, Trk::binZ ); 
+    buPhi += buZ; 
+
+    Trk::BinUtility* volBinUtil=new Trk::BinUtility(buPhi);        // TODO verify ordering PhiZ vs. ZPhi 
+
+    delete protVol;
+    Trk::BinnedArray2D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray2D<Trk::TrackingVolume>(subVolumes,volBinUtil);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    0,subVols,
+				    volumeName);
+    // register glue volumes
+    const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+    volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+    volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+
+  } else {
+    // enclosed muon objects ? 
+    blendVols.clear();
+    std::vector<const Trk::DetachedTrackingVolume*>* muonObjs = getDetachedObjects( vol, blendVols,aLVC);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    muonObjs,
+				    volumeName);
+    // statistics
+    m_frameNum++ ; if (muonObjs) m_frameStat += muonObjs->size();  
+    // prepare blending
+    if (m_blendInertMaterial && blendVols.size()) {
+      for (unsigned int id=0;id<blendVols.size();id++) {
+	if (!aLVC.m_blendMap[blendVols[id]]) {
+	  aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+	  aLVC.m_blendVols.push_back(blendVols[id]);
+	}
+	aLVC.m_blendMap[blendVols[id]]->push_back(tVol);
+      }
+    }  
+  }
+
+  return tVol;
+} 
+
+const Trk::TrackingVolume* Muon::MuonTrackingGeometryBuilderCond::processVolume(const Trk::Volume* vol, int mode , std::string volumeName, LocalVariablesContainer& aLVC) const
+{
+  ATH_MSG_VERBOSE( name() << "processing volume in mode:"<< mode );
+
+  // mode : -1 ( adjusted z/phi partition )
+  //         0 ( -"- plus barrel H binning )            
+  //         0 ( -"- plus inner endcap H binning )            
+  //         0 ( -"- plus outer endcap H binning )            
+
+  const Trk::TrackingVolume* tVol = 0;
+
+  unsigned int colorCode = m_colorCode;
+
+  std::vector<const Trk::DetachedTrackingVolume* > blendVols;
+
+  //getPartitionFromMaterial(vol);
+
+  // retrieve cylinder
+  const Trk::CylinderVolumeBounds* cyl=dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  if (!cyl) {
+    ATH_MSG_ERROR( " process volume: volume cylinder boundaries not retrieved, return 0 " );
+    return 0; 
+  }
+  // create vector of zSteps for this volume
+  std::vector<float> zSteps;
+  std::vector<int> zTypes;
+  zSteps.clear(); zTypes.clear();
+  double zPos = vol->center()[2];
+  double hz = cyl->halflengthZ();
+  double z1 = zPos-hz;  double z2 = zPos+hz ;
+  zSteps.push_back(z1);
+  for (unsigned int iz=0;iz<aLVC.m_zPartitions.size();iz++) {
+    if ( aLVC.m_zPartitions[iz]==zSteps.front()) zTypes.push_back(aLVC.m_zPartitionsType[iz]);
+    if ( aLVC.m_zPartitions[iz]> z1 && aLVC.m_zPartitions[iz] < z2 ) {
+      zSteps.push_back(aLVC.m_zPartitions[iz]);
+      if (!zTypes.size()) { 
+	if (iz==0) zTypes.push_back(0);
+        else zTypes.push_back(aLVC.m_zPartitionsType[iz-1]);
+      }
+      zTypes.push_back(aLVC.m_zPartitionsType[iz]);
+      z1 = aLVC.m_zPartitions[iz];
+    }
+  }
+  zSteps.push_back(z2);
+
+  for (unsigned int iz=0;iz<zSteps.size(); iz++) ATH_MSG_DEBUG( "z partition in volume:"<<volumeName<<":"<<iz<<":"<<zSteps[iz]); 
+
+  // phi binning
+  if (fabs(zPos)> m_barrelZ && cyl->outerRadius()<aLVC.m_outerBarrelRadius) getPhiParts(0,aLVC);
+  else if (fabs(zPos)<= m_ectZ) getPhiParts(2,aLVC);
+  else if (fabs(zPos)<= aLVC.m_innerEndcapZ) getPhiParts(3,aLVC);
+  else if (fabs(zPos)> m_outerWheel && cyl->outerRadius()> m_outerShieldRadius ) getPhiParts(1,aLVC);
+  else if (fabs(zPos)> aLVC.m_innerEndcapZ && fabs(zPos)<m_bigWheel && cyl->outerRadius()> m_outerShieldRadius ) getPhiParts(1,aLVC);
+  else getPhiParts(0,aLVC);
+
+  // R/H binning ?
+  unsigned int etaN = zSteps.size()-1;
+  unsigned int phiN = aLVC.m_adjustedPhi.size();
+   
+  int phiTypeMax = 0;                // count different partitions
+
+  if ( mode > -1 ) {
+    // create z,phi bin utilities
+    //Trk::BinUtility1DZZ* zBinUtil = new Trk::BinUtility1DZZ(zSteps);
+    //Trk::BinUtility1DF* pBinUtil = new Trk::BinUtility1DF(m_adjustedPhi);
+    Trk::BinUtility* zBinUtil = new Trk::BinUtility(zSteps, Trk::open, Trk::binZ );
+    Trk::BinUtility* pBinUtil = new Trk::BinUtility(aLVC.m_adjustedPhi,  Trk::closed, Trk::binPhi ); 
+    std::vector<std::vector<Trk::BinUtility*> >*  hBinUtil=new std::vector<std::vector<Trk::BinUtility*> >;
+    for (unsigned iz=0;iz < zSteps.size()-1; iz++) {
+      std::vector<Trk::BinUtility*> phBinUtil; 
+      for (unsigned ip=0;ip < aLVC.m_adjustedPhi.size(); ip++) {
+        // retrieve reference phi
+	float phiRef = 0.5*aLVC.m_adjustedPhi[ip];
+        if (ip<aLVC.m_adjustedPhi.size()-1) phiRef += 0.5*aLVC.m_adjustedPhi[ip+1] ;
+	else phiRef += 0.5*aLVC.m_adjustedPhi[0]+M_PI ;
+
+        if (aLVC.m_adjustedPhiType[ip]>phiTypeMax) phiTypeMax = aLVC.m_adjustedPhiType[ip];
+        for (std::pair<int,float> i: aLVC.m_hPartitions[mode][zTypes[iz]][aLVC.m_adjustedPhiType[ip]]) {
+          ATH_MSG_VERBOSE( " mode " << mode << " phiRef " << phiRef << " zTypes[iz] " << zTypes[iz] << " m_adjustedPhiType[ip] " << aLVC.m_adjustedPhiType[ip] << " hPartitions " << i.second );
+        }
+        phBinUtil.push_back(new Trk::BinUtility(phiRef,aLVC.m_hPartitions[mode][zTypes[iz]][aLVC.m_adjustedPhiType[ip]]));
+      }
+      hBinUtil->push_back(phBinUtil);
+    }
+
+    // create subvolumes & BinnedArray
+    std::vector<Trk::TrackingVolumeOrderPosition>  subVolumesVect;
+    std::vector<std::vector<std::vector<const Trk::TrackingVolume*> > > subVolumes;
+    std::vector<std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > > > hBins;
+    std::vector<const Trk::TrackingVolume*> sVolsInn;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsOut;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsNeg;             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsPos;             // for gluing
+    for (unsigned int eta = 0; eta < zSteps.size()-1; eta++) {
+      if (colorCode>0) colorCode = 6 -colorCode;
+      double posZ = 0.5*(zSteps[eta] + zSteps[eta+1]) ;
+      double   hZ = 0.5*fabs(zSteps[eta+1] - zSteps[eta]) ;
+      std::vector<std::vector<const Trk::TrackingVolume*> > phiSubs;
+      std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > >  phBins;
+      std::vector<int> phiType(phiTypeMax+1,-1);        // indication of first phi/R partition built for a given type (for cloning)
+      std::vector<std::vector<Trk::Volume*> > garbVol(phiTypeMax+1);
+      unsigned int pCode = 1; 
+      for (unsigned int phi = 0; phi < phiN; phi++) {
+	pCode = (colorCode>0) ? 3-pCode : 0;
+	double posPhi = 0.5*aLVC.m_adjustedPhi[phi];
+	double phiSect = 0.;
+        if (phi<phiN-1) {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[phi+1] ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[phi+1]-aLVC.m_adjustedPhi[phi]);
+	} else {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[0]+M_PI ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[0]+2*M_PI-aLVC.m_adjustedPhi[phi]);
+	}
+	std::vector<std::pair<int,float> > hSteps =  aLVC.m_hPartitions[mode][zTypes[eta]][aLVC.m_adjustedPhiType[phi]];
+	std::vector<const Trk::TrackingVolume*> hSubs;
+	std::vector<Trk::TrackingVolumeOrderPosition> hSubsTr;
+        int phiP = phiType[aLVC.m_adjustedPhiType[phi]]; 
+
+        unsigned int hCode = 1; 
+        for (unsigned int h = 0; h < hSteps.size()-1; h++) {
+	  hCode = colorCode>0 ? 1 - hCode : 0; 
+          // similar volume may exist already
+	  Trk::Volume* subVol=0;
+	  Amg::Transform3D* transf = new Amg::Transform3D(Amg::AngleAxis3D(posPhi,Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+          //
+          int volType = 0;     // cylinder 
+          if ( hSteps[h].first == 1 && hSteps[h+1].first == 0 ) volType = 1;  
+          if ( hSteps[h].first == 0 && hSteps[h+1].first == 1 ) volType = 2;  
+          if ( hSteps[h].first == 1 && hSteps[h+1].first == 1 ) volType = 3;  
+	  // define subvolume
+          if (phiP>-1 ) {
+            subVol = new Trk::Volume(*(phiSubs[phiP][h]),(*transf)*phiSubs[phiP][h]->transform().inverse());
+	  } else if ( phiSect<0.5*M_PI) {
+	    Trk::BevelledCylinderVolumeBounds* subBds = new Trk::BevelledCylinderVolumeBounds(hSteps[h].second,
+							   hSteps[h+1].second,
+							   phiSect, 
+							   hZ,
+							   volType);
+	    subVol = new Trk::Volume(transf, subBds);
+	  } else {
+	    Trk::CylinderVolumeBounds* subBds = new Trk::CylinderVolumeBounds(hSteps[h].second,
+						   hSteps[h+1].second,
+						   phiSect, 
+						   hZ);
+	    subVol = new Trk::Volume(transf, subBds);
+	  }
+       
+	  // enclosed muon objects ? also adjusts material properties in case of material blend  
+	  std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) +MuonGM::buildString(h,2) ; 
+          blendVols.clear(); 
+	  std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( subVol, blendVols,aLVC);
+
+	  const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( *subVol,
+								     aLVC.m_muonMaterial,
+								     detVols,
+								     volName );                                                                  
+     
+	  // statistics
+	  m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+	  // prepare blending
+	  if (m_blendInertMaterial && blendVols.size()) {
+	    for (unsigned int id=0;id<blendVols.size();id++) {
+	      if (!aLVC.m_blendMap[blendVols[id]]) {
+		aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+                aLVC.m_blendVols.push_back(blendVols[id]);
+	      }
+	      aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	    }
+	  }  
+	  // reference point for the check of envelope
+	  double posR = 0.5*(hSteps[h].second+hSteps[h+1].second);
+	  // loop over inner cutouts
+	  for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+	    if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+	      if (posR < aLVC.m_msCutoutsIn[in].first) sVol->sign(Trk::BeamPipe);
+	      break;
+	    }
+	  }
+	  // loop over outer cutouts
+	  for (unsigned int io=1; io<aLVC.m_msCutoutsOut.size(); io++) {
+	    if (posZ>=aLVC.m_msCutoutsOut[io-1].second && posZ<=aLVC.m_msCutoutsOut[io].second) {
+	      if (posR > aLVC.m_msCutoutsOut[io].first) sVol->sign(Trk::Cavern);
+	      break;
+	    }
+	  }
+	  //
+          sVol->registerColorCode(colorCode+pCode+hCode);
+	  // reference position 
+	  Amg::Vector3D gp(0.5*(hSteps[h].second+hSteps[h+1].second),0.,0.);
+	  subVolumesVect.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol),
+	                                                       Amg::Vector3D((*transf)*gp)));
+	  hSubsTr.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, Trk::do_not_delete<const Trk::TrackingVolume>),
+	                                                       Amg::Vector3D((*transf)*gp)));
+	  hSubs.push_back(sVol);
+
+          // cleanup 
+          if (phiP>-1) {delete transf; delete subVol;}
+          else garbVol[aLVC.m_adjustedPhiType[phi]].push_back(subVol);       // don't delete before cloned
+
+	  //glue subVolume
+	  if (h==0)                sVolsInn.push_back(sVol); 
+	  if (h==hSteps.size()-2)  sVolsOut.push_back(sVol); 
+	  if (eta==0)      sVolsNeg.push_back(sVol); 
+	  if (eta==etaN-1) sVolsPos.push_back(sVol); 
+          // in R/H
+          if (h>0) { // glue 'manually'
+            if (volType == 1 || volType == 3 ) {  // plane surface
+	      m_trackingVolumeHelper->setOutsideTrackingVolume(*sVol, Trk::tubeSectorInnerCover,hSubs[h-1]); 
+	      m_trackingVolumeHelper->setOutsideTrackingVolume(*(hSubs[h-1]), Trk::tubeSectorOuterCover,sVol); 
+            } else {  // cylinder surface
+	      m_trackingVolumeHelper->setInsideTrackingVolume(*sVol, Trk::tubeSectorInnerCover,hSubs[h-1]); 
+	      m_trackingVolumeHelper->setOutsideTrackingVolume(*(hSubs[h-1]), Trk::tubeSectorOuterCover,sVol);
+	    } 
+          }
+	  // in phi        
+	  if ( phiN>1 && phi>0) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::tubeSectorNegativePhi,phBins[phi-1]);
+	    if ( phi==phiN-1 )  m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::tubeSectorPositivePhi, phBins[0]);
+	  }
+	  // in eta
+	  if ( etaN>1 && eta>0) m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::negativeFaceXY, hBins[eta-1][phi]);     
+	  //
+	}
+        phiSubs.push_back(hSubs); 
+	Trk::BinnedArray1D<Trk::TrackingVolume>* volBinArray = new Trk::BinnedArray1D<Trk::TrackingVolume>(hSubsTr,(*hBinUtil)[eta][phi]->clone());
+        phBins.push_back(Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> >(volBinArray));
+        // save link to current partition for cloning 
+        if (phiP<0) phiType[aLVC.m_adjustedPhiType[phi]] = phi;    
+
+        // finish phi gluing
+        if (phiN>1 && phi>0) {
+	  for (unsigned int j=0; j<phiSubs[phi-1].size(); j++) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(phiSubs[phi-1][j]), Trk::tubeSectorPositivePhi,phBins[phi]);
+	  }
+	}
+        if (phiN>1 && phi==phiN-1) {
+	  for (unsigned int j=0; j<phiSubs[0].size(); j++) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(phiSubs[0][j]), Trk::tubeSectorNegativePhi,phBins[phi]);
+	  }
+	}
+        // finish eta gluing
+        if ( etaN>1 && eta>0) {
+	  for (unsigned int j=0; j<subVolumes[eta-1][phi].size(); j++) {
+	    m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(subVolumes[eta-1][phi][j]), Trk::positiveFaceXY,phBins[phi]);
+	  }
+	}
+      }
+      subVolumes.push_back(phiSubs);
+      hBins.push_back(phBins);
+      // get rid of the garbage
+      for (unsigned int j=0;j<garbVol.size();j++)
+	for (unsigned int jj=0;jj<garbVol[j].size();jj++) delete garbVol[j][jj];
+    }
+
+    //Trk::BinUtility3DZFH* volBinUtil=new Trk::BinUtility3DZFH(zBinUtil,pBinUtil,hBinUtil,new Amg::Transform3D(vol->transform()));
+  
+    Trk::BinnedArray1D1D1D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray1D1D1D<Trk::TrackingVolume>(subVolumesVect,zBinUtil,pBinUtil,hBinUtil);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    0,subVols,
+				    volumeName);
+    // register glue volumes
+    const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+    volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVolsInn);
+    volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVolsOut);
+    volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+    volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+  
+    return tVol;
+  } 
+
+  // proceed with 2D z/phi binning
+  // partitions ? include protection against wrong setup
+  if (phiN < 1) {
+    ATH_MSG_ERROR( name() << "wrong partition setup" );
+    phiN = 1;
+  } else {
+    ATH_MSG_VERBOSE( name() << "partition setup:(z,phi):"<<etaN<<","<<phiN );
+  }
+
+  if ( etaN * phiN > 1 ) {  // partition
+    // subvolume boundaries
+    Trk::CylinderVolumeBounds* subBds=0;
+
+    // create subvolumes & BinnedArray
+    std::vector<Trk::TrackingVolumeOrderPosition> subVolumes(etaN*phiN);
+    std::vector<const Trk::TrackingVolume*> sVols(etaN*phiN);                // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsNeg(phiN);             // for gluing
+    std::vector<const Trk::TrackingVolume*> sVolsPos(phiN);             // for gluing
+    for (unsigned int eta = 0; eta < zSteps.size()-1; eta++) {
+      double posZ = 0.5*(zSteps[eta] + zSteps[eta+1]) ;
+      double   hZ = 0.5*fabs(zSteps[eta+1] - zSteps[eta]) ;
+      colorCode = 26 -colorCode;
+      for (unsigned int phi = 0; phi < phiN; phi++) {
+	colorCode = 26 -colorCode;
+	double posPhi = 0.5*aLVC.m_adjustedPhi[phi];
+	double phiSect = 0.;
+        if (phi<phiN-1) {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[phi+1] ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[phi+1]-aLVC.m_adjustedPhi[phi]);
+	} else {
+	  posPhi += 0.5*aLVC.m_adjustedPhi[0]+M_PI ;
+          phiSect = 0.5*fabs(aLVC.m_adjustedPhi[0]+2*M_PI-aLVC.m_adjustedPhi[phi]);
+	}
+	// define subvolume
+	subBds = new Trk::CylinderVolumeBounds(cyl->innerRadius(),
+					       cyl->outerRadius(),
+					       phiSect, 
+					       hZ);
+        Amg::Transform3D* transf = new Amg::Transform3D(Amg::AngleAxis3D(posPhi,Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+        Trk::Volume subVol(transf, subBds);     
+        // enclosed muon objects ?   
+	std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) ; 
+
+	Trk::Material mat=aLVC.m_muonMaterial;
+        blendVols.clear();
+        std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( &subVol, blendVols,aLVC);
+        const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( subVol,
+								   aLVC.m_muonMaterial,
+								   detVols,
+								   volName );
+        // statistics
+        m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+        // prepare blending
+        if (m_blendInertMaterial && blendVols.size()) {
+          for (unsigned int id=0;id<blendVols.size();id++) {
+	    if (!aLVC.m_blendMap[blendVols[id]]) {
+	      aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+              aLVC.m_blendVols.push_back(blendVols[id]);
+	    }
+	    aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	  }
+	}  
+	// reference point for the check of envelope
+	double posR = 0.5*(cyl->innerRadius()+cyl->outerRadius());
+	// loop over inner cutouts
+	for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+	  if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+	    if (posR < aLVC.m_msCutoutsIn[in].first) sVol->sign(Trk::BeamPipe);
+	    break;
+	  }
+	}
+	// loop over outer cutouts
+	for (unsigned int io=1; io<aLVC.m_msCutoutsOut.size(); io++) {
+	  if (posZ>=aLVC.m_msCutoutsOut[io-1].second && posZ<=aLVC.m_msCutoutsOut[io].second) {
+	    if (posR > aLVC.m_msCutoutsOut[io].first) sVol->sign(Trk::Cavern);
+	    break;
+	  }
+	}
+        //delete subVol;
+        sVol->registerColorCode(colorCode); 
+        // reference position 
+	Amg::Vector3D gp(subBds->outerRadius(),0.,0.);
+	//subVolumes.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, true),
+        //                                                     Amg::Vector3D((*transf)*gp)));
+	subVolumes[phi*etaN+eta] = Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol),
+                                                             Amg::Vector3D((*transf)*gp));
+        //glue subVolumes
+        //sVols[phi*etaN+eta] = sVol; 
+        sVols[phiN*eta+phi] = sVol; 
+        if (eta==0)      sVolsNeg[phi]=sVol; 
+        if (eta==etaN-1) sVolsPos[phi]=sVol; 
+        // in phi        
+        if ( phiN>1 && phi>0) {
+          m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::tubeSectorNegativePhi,
+						      *(sVols[eta*phiN+phi-1]), Trk::tubeSectorPositivePhi);
+          if ( phi==phiN-1 )  m_trackingVolumeHelper->glueTrackingVolumes(*(sVols[eta*phiN]), Trk::tubeSectorNegativePhi,
+                                                                          *sVol, Trk::tubeSectorPositivePhi);
+	}
+        // in eta
+        if ( etaN>1 && eta>0) m_trackingVolumeHelper->glueTrackingVolumes(*sVol, Trk::negativeFaceXY,
+						      *(sVols[(eta-1)*phiN+phi]), Trk::positiveFaceXY);        
+        //
+      }
+    }
+
+    //Trk::BinUtility2DZF* volBinUtil=new Trk::BinUtility2DZF(zSteps,m_adjustedPhi,new Amg::Transform3D(vol->transform()));
+    Trk::BinUtility zBinUtil(zSteps, Trk::BinningOption::open, Trk::BinningValue::binZ );
+    const Trk::BinUtility pBinUtil(aLVC.m_adjustedPhi,  Trk::BinningOption::closed, Trk::BinningValue::binPhi ); 
+
+    zBinUtil += pBinUtil; 
+
+    Trk::BinUtility* volBinUtil=new Trk::BinUtility(zBinUtil);        // TODO verify ordering PhiZ vs. ZPhi 
+
+    Trk::BinnedArray2D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray2D<Trk::TrackingVolume>(subVolumes,volBinUtil);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    0,subVols,
+				    volumeName);
+    // register glue volumes
+    const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+    volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVols);
+    volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+    volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+
+  } else {
+    // enclosed muon objects ? 
+    blendVols.clear();
+    std::vector<const Trk::DetachedTrackingVolume*>* muonObjs = getDetachedObjects( vol, blendVols,aLVC);
+
+    tVol = new Trk::TrackingVolume( *vol,
+                                    aLVC.m_muonMaterial,
+				    muonObjs,
+				    volumeName);
+    // statistics
+    m_frameNum++ ; if (muonObjs) m_frameStat += muonObjs->size();  
+    // prepare blending
+    if (m_blendInertMaterial && blendVols.size()) {
+      for (unsigned int id=0;id<blendVols.size();id++) {
+	if (!aLVC.m_blendMap[blendVols[id]]) {
+	  aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+	  aLVC.m_blendVols.push_back(blendVols[id]);
+	}
+	aLVC.m_blendMap[blendVols[id]]->push_back(tVol);
+      }
+    }  
+  }
+
+  return tVol;
+} 
+
+const Trk::TrackingVolume* Muon::MuonTrackingGeometryBuilderCond::processShield(const Trk::Volume* vol, int type,std::string volumeName, LocalVariablesContainer &aLVC) const
+{
+  ATH_MSG_VERBOSE( name() << "processing shield volume "<< volumeName<<"  in mode:"<< type );
+
+  const Trk::TrackingVolume* tVol = 0;
+
+  unsigned int colorCode = m_colorCode;
+
+  std::vector<const Trk::DetachedTrackingVolume*> blendVols;
+
+  //getPartitionFromMaterial(vol);
+
+  // retrieve cylinder
+  const Trk::CylinderVolumeBounds* cyl=dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  if (!cyl) {
+    ATH_MSG_ERROR( " process volume: volume cylinder boundaries not retrieved, return 0 " );
+    return 0; 
+  }
+  // create vector of zSteps for this volume
+  std::vector<float> zSteps;
+  zSteps.clear();
+  double zPos = vol->center()[2];
+  double hz = cyl->halflengthZ();
+  double z1 = zPos-hz;  double z2 = zPos+hz ;
+  zSteps.push_back(z1);
+  for (unsigned int iz=0;iz<aLVC.m_shieldZPart.size();iz++) {
+    if ( aLVC.m_shieldZPart[iz]> z1 && aLVC.m_shieldZPart[iz] < z2 ) {
+      zSteps.push_back(aLVC.m_shieldZPart[iz]);
+      z1 = aLVC.m_shieldZPart[iz];
+    }
+  }
+  zSteps.push_back(z2);
+
+  // phi binning trivial
+  aLVC.m_adjustedPhi.clear();
+  aLVC.m_adjustedPhi.push_back(0.);
+
+  unsigned int etaN = zSteps.size()-1;
+
+  // create z,h bin utilities
+  //Trk::BinUtility1DZZ* zBinUtil = new Trk::BinUtility1DZZ(zSteps);
+  //Trk::BinUtility1DF* pBinUtil = new Trk::BinUtility1DF(m_adjustedPhi);
+  Trk::BinUtility* zBinUtil = new Trk::BinUtility(zSteps, Trk::BinningOption::open, Trk::BinningValue::binZ );
+  //Trk::BinUtility* pBinUtil = new Trk::BinUtility(m_adjustedPhi,  Trk::BinningOption::closed, Trk::BinningValue::binPhi );
+  Trk::BinUtility* pBinUtil = new Trk::BinUtility( 1, -M_PI, M_PI, Trk::BinningOption::closed, Trk::BinningValue::binPhi ); 
+  std::vector<std::vector<Trk::BinUtility*> >*  hBinUtil=new std::vector<std::vector<Trk::BinUtility*> >;
+  float phiRef = 0.;
+  for (unsigned iz=0;iz < zSteps.size()-1; iz++) {
+    std::vector<Trk::BinUtility*> phBinUtil;
+    phBinUtil.push_back(new Trk::BinUtility(phiRef,aLVC.m_shieldHPart[type]) );
+    hBinUtil->push_back(phBinUtil);
+  }
+
+  // subvolume boundaries
+  Trk::CylinderVolumeBounds* subBds=0;
+
+  // create subvolumes & BinnedArray
+  std::vector<Trk::TrackingVolumeOrderPosition>  subVolumesVect;
+  std::vector<std::vector<std::vector<const Trk::TrackingVolume*> > > subVolumes;
+  std::vector<std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > > > hBins;
+  std::vector<const Trk::TrackingVolume*> sVolsInn;             // for gluing
+  std::vector<const Trk::TrackingVolume*> sVolsOut;             // for gluing
+  std::vector<const Trk::TrackingVolume*> sVolsNeg;             // for gluing
+  std::vector<const Trk::TrackingVolume*> sVolsPos;             // for gluing
+  for (unsigned int eta = 0; eta < zSteps.size()-1; eta++) {
+    if (colorCode>0) colorCode = 26 -colorCode;
+    double posZ = 0.5*(zSteps[eta] + zSteps[eta+1]) ;
+    double   hZ = 0.5*fabs(zSteps[eta+1] - zSteps[eta]) ;
+    std::vector<std::vector<const Trk::TrackingVolume*> > phiSubs;
+    std::vector<Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> > >  phBins;
+    int phi = 0;
+    double posPhi = 0.;
+    double phiSect = M_PI;
+    std::vector<std::pair<int,float> > hSteps =  aLVC.m_shieldHPart[type];
+    std::vector<const Trk::TrackingVolume*> hSubs;
+    std::vector<Trk::TrackingVolumeOrderPosition> hSubsTr;
+    unsigned int hCode = 1; 
+    for (unsigned int h = 0; h < hSteps.size()-1; h++) {
+      hCode = (colorCode>0) ? 1 - hCode : 0; 
+      // define subvolume
+      subBds = new Trk::CylinderVolumeBounds(hSteps[h].second,
+					     hSteps[h+1].second,
+					     phiSect, 
+					     hZ);
+      Amg::Transform3D* transf = new Amg::Transform3D(Amg::AngleAxis3D(posPhi,Amg::Vector3D(0.,0.,1.))*Amg::Translation3D(Amg::Vector3D(0.,0.,posZ)));
+      Trk::Volume subVol(transf, subBds);
+      
+      // enclosed muon objects ? also adjusts material properties in case of material blend  
+      std::string volName = volumeName +MuonGM::buildString(eta,2) +MuonGM::buildString(phi,2) +MuonGM::buildString(h,2) ; 
+      blendVols.clear();
+      std::vector<const Trk::DetachedTrackingVolume*>* detVols= getDetachedObjects( &subVol, blendVols,aLVC);
+      
+      const Trk::TrackingVolume* sVol = new Trk::TrackingVolume( subVol,
+								 aLVC.m_muonMaterial,
+								 detVols,
+								 volName );
+      
+      // statistics
+      m_frameNum++ ; if (detVols) m_frameStat += detVols->size();  
+      // prepare blending
+      if (m_blendInertMaterial && blendVols.size()) {
+	for (unsigned int id=0;id<blendVols.size();id++) {
+	  if (!aLVC.m_blendMap[blendVols[id]]) {
+	    aLVC.m_blendMap[blendVols[id]] = new std::vector<const Trk::TrackingVolume*>;
+	    aLVC.m_blendVols.push_back(blendVols[id]);
+	  }
+	  aLVC.m_blendMap[blendVols[id]]->push_back(sVol);
+	}
+      }  
+      // reference point for the check of envelope
+      double posR = 0.5*(hSteps[h].second+hSteps[h+1].second);
+      // loop over inner cutouts
+      for (unsigned int in=1; in<aLVC.m_msCutoutsIn.size(); in++) {
+	if (posZ>=aLVC.m_msCutoutsIn[in].second && posZ<=aLVC.m_msCutoutsIn[in-1].second) {
+	  if (posR < aLVC.m_msCutoutsIn[in].first) sVol->sign(Trk::BeamPipe);
+	  break;
+	}
+      }
+      //
+      sVol->registerColorCode(colorCode+hCode);
+      // reference position 
+      Amg::Vector3D gp(subBds->mediumRadius(),0.,0.);
+      subVolumesVect.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol),
+								Amg::Vector3D((*transf)*gp)));
+      hSubsTr.push_back(Trk::TrackingVolumeOrderPosition(Trk::SharedObject<const Trk::TrackingVolume>(sVol, Trk::do_not_delete<const Trk::TrackingVolume>),
+                                                         Amg::Vector3D((*transf)*gp)));
+      hSubs.push_back(sVol);
+      
+      //glue subVolume
+      if (h==0)                sVolsInn.push_back(sVol); 
+      if (h==hSteps.size()-2)  sVolsOut.push_back(sVol); 
+      if (eta==0)      sVolsNeg.push_back(sVol); 
+      if (eta==etaN-1) sVolsPos.push_back(sVol); 
+      // in R/H
+      if (h>0) { // glue 'manually'
+	m_trackingVolumeHelper->setInsideTrackingVolume(*sVol, Trk::tubeSectorInnerCover,hSubs[h-1]); 
+	m_trackingVolumeHelper->setOutsideTrackingVolume(*(hSubs[h-1]), Trk::tubeSectorOuterCover,sVol);
+      }
+      // in eta
+      if ( etaN>1 && eta>0) m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*sVol, Trk::negativeFaceXY, hBins[eta-1][phi]);     
+    }	
+    phiSubs.push_back(hSubs); 
+    Trk::BinnedArray1D<Trk::TrackingVolume>* volBinArray = new Trk::BinnedArray1D<Trk::TrackingVolume>(hSubsTr,(*hBinUtil)[eta][phi]->clone());
+    phBins.push_back(Trk::SharedObject<Trk::BinnedArray<Trk::TrackingVolume> >(volBinArray));
+
+    // finish eta gluing
+    if ( etaN>1 && eta>0) {
+      for (unsigned int j=0; j<subVolumes[eta-1][phi].size(); j++) {
+	m_trackingVolumeHelper->setOutsideTrackingVolumeArray(*(subVolumes[eta-1][phi][j]), Trk::positiveFaceXY,phBins[phi]);
+      }
+    }
+    subVolumes.push_back(phiSubs);
+    hBins.push_back(phBins);
+  }
+    
+  //Trk::BinUtility3DZFH* volBinUtil=new Trk::BinUtility3DZFH(zBinUtil,pBinUtil,hBinUtil,new Amg::Transform3D(vol->transform()));
+
+  Trk::BinnedArray1D1D1D<Trk::TrackingVolume>* subVols=new Trk::BinnedArray1D1D1D<Trk::TrackingVolume>(subVolumesVect,zBinUtil,pBinUtil,hBinUtil);
+  
+  tVol = new Trk::TrackingVolume( *vol,
+				  aLVC.m_muonMaterial,
+				  0,subVols,
+				  volumeName);
+  // register glue volumes
+  const Trk::GlueVolumesDescriptor& volGlueVolumes = tVol->glueVolumesDescriptor();
+  volGlueVolumes.registerGlueVolumes(Trk::tubeInnerCover,sVolsInn);
+  volGlueVolumes.registerGlueVolumes(Trk::tubeOuterCover,sVolsOut);
+  volGlueVolumes.registerGlueVolumes(Trk::negativeFaceXY,sVolsNeg);
+  volGlueVolumes.registerGlueVolumes(Trk::positiveFaceXY,sVolsPos);
+  
+  return tVol;
+} 
+
+std::vector<const Trk::DetachedTrackingVolume*>* Muon::MuonTrackingGeometryBuilderCond::getDetachedObjects(const Trk::Volume* vol, std::vector<const Trk::DetachedTrackingVolume*>& blendVols, LocalVariablesContainer &aLVC, int mode ) const
+{
+  // mode : 0 all, 1 active only, 2 inert only
+
+  std::vector<const Trk::DetachedTrackingVolume*>* detTVs = 0;
+
+  if (!m_stations && !m_inertObjs) return detTVs;
+  
+  // get min/max Z/Phi from volume (allways a cylinder/bevelled cylinder volume )  
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  const Trk::BevelledCylinderVolumeBounds* bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (&(vol->volumeBounds()));
+   
+  double rmed = 0.; double dphi = 0.; double hz = 0.; double rMin = 0.; double rMax = 0.; double rMaxc = 0.; int type = 0;
+  if (cyl) {
+    rmed = cyl->mediumRadius();
+    dphi = cyl->halfPhiSector();
+    hz = cyl->halflengthZ();
+    rMin = cyl->innerRadius();
+    rMax = cyl->outerRadius();
+    rMaxc = rMax;
+  } else if (bcyl) {
+    rmed = bcyl->mediumRadius();
+    dphi = bcyl->halfPhiSector();
+    hz = bcyl->halflengthZ();
+    rMin = bcyl->innerRadius();
+    rMax = bcyl->outerRadius();    
+    rMaxc = rMax;    
+    type = bcyl->type();
+    if (type>1) rMaxc *=1./cos(dphi);
+  } else return 0;
+ 
+  Amg::Vector3D center(rmed,0.,0.);
+  center = vol->transform() * center;
+
+  double zMin = center[2] - hz; 
+  double zMax = center[2] + hz;
+  double pMin = 0.;
+  double pMax = +2*M_PI;
+  bool phiLim = false;
+  if (dphi < M_PI) { 
+    pMin = center.phi() - dphi + M_PI; 
+    pMax = center.phi() + dphi + M_PI;
+    phiLim = true;
+  } 
+
+  ATH_MSG_VERBOSE( " zMin "<< zMin <<" zMax " <<zMax << " rMin "<< rMin <<" rMax "<<rMax << " rMaxc " << rMaxc << " phi limits "<< pMin <<" phiMax "<<pMax <<  " phiLim " << phiLim);
+
+  // define detector region : can extend over several
+  int gMin = (zMax <= -m_bigWheel) ? 0 : 1;
+  if ( zMin >= m_bigWheel ) gMin = 8;
+  else if ( zMin >= aLVC.m_innerEndcapZ ) gMin = 7;
+  else if ( zMin >= m_ectZ )         gMin = 6;
+  else if ( zMin >= m_diskShieldZ )      gMin = 5;
+  else if ( zMin >=-m_diskShieldZ )      gMin = 4;
+  else if ( zMin >=-m_ectZ )         gMin = 3;
+  else if ( zMin >=-aLVC.m_innerEndcapZ ) gMin = 2;
+  int gMax = (zMax >= m_bigWheel) ? 8 : 7;
+  if ( zMax <= -m_bigWheel ) gMax = 0;
+  else if ( zMax <= -aLVC.m_innerEndcapZ ) gMax = 1;
+  else if ( zMax <= -m_ectZ )         gMax = 2;
+  else if ( zMax <= -m_diskShieldZ )      gMax = 3;
+  else if ( zMax <= m_diskShieldZ )      gMax = 4;
+  else if ( zMax <= m_ectZ )         gMax = 5;
+  else if ( zMax <= aLVC.m_innerEndcapZ ) gMax = 6;
+
+  ATH_MSG_VERBOSE( " active volumes gMin "<< gMin<<" gMax "<<gMax);
+   
+  std::list<const Trk::DetachedTrackingVolume*> detached;
+  // active, use corrected rMax
+  if (mode <2 && aLVC.m_stationSpan) {
+    for (int gMode=gMin; gMode<=gMax; gMode++) {
+      for (unsigned int i=0; i<(*aLVC.m_stationSpan)[gMode]->size() ; i++) {
+	const Muon::Span* s = (*((*aLVC.m_stationSpan)[gMode]))[i].second;          // span
+	const Trk::DetachedTrackingVolume* station = (*((*aLVC.m_stationSpan)[gMode]))[i].first;   // station
+	bool rLimit = !aLVC.m_static3d || ( (*s)[4] <= rMaxc && (*s)[5] >= rMin );
+// Check meanZ for BME stations
+        bool meanZOK = false;
+        if(station->name()=="BME1_Station"||station->name()=="BME2_Station") {
+            if( ((*s)[0]+(*s)[1])/2.< zMax&&((*s)[0]+(*s)[1])/2.> zMin ) meanZOK = true;
+            if( ((*s)[2]+(*s)[3])/2 <pMin&&phiLim) meanZOK = false;
+            if( ((*s)[2]+(*s)[3])/2 <pMin&&phiLim) meanZOK = false;
+        }
+        if ( rLimit && (((*s)[0] < zMax && (*s)[1] > zMin)||meanZOK) ) {
+          bool accepted = false;
+          if (phiLim) {
+              if (pMin>=0 && pMax<=2*M_PI) {
+                if ( (*s)[2]<=(*s)[3] && (*s)[2] <= pMax && (*s)[3] >= pMin )  accepted = true;
+                if ( (*s)[2]>(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin) ) accepted = true;
+              } else if (pMin < 0) {
+                if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin+2*M_PI) ) accepted = true;
+                if ( (*s)[2]>(*s)[3]  ) accepted = true;
+              } else if (pMax > 2*M_PI) {
+                if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax-2*M_PI || (*s)[3] >= pMin) ) accepted = true;
+                if ( (*s)[2]>(*s)[3]  ) accepted = true;
+              }
+          } else  accepted = true;
+          if(meanZOK) accepted = true;
+          if (accepted) {
+              detached.push_back(station);
+              ATH_MSG_VERBOSE(" active volume accepted by rLimit " <<  station->name() << " zMin " << zMin << " zMax " << zMax << " rMin " << rMin << " rMax " << rMax << " PhiMin " << pMin  << " PhiMax " << pMax);
+          }
+        } else {
+//            ATH_MSG_VERBOSE( " active volume rejected by rLimit " <<  station->name() );
+	} 
+      }
+    }
+  }
+  // passive 
+  if (mode !=1 && aLVC.m_inertSpan) {
+    for (int gMode=gMin; gMode<=gMax; gMode++) {
+      for (unsigned int i=0; i<(*aLVC.m_inertSpan)[gMode]->size() ; i++) {
+	const Muon::Span* s = (*((*aLVC.m_inertSpan)[gMode]))[i].second;
+	const Trk::DetachedTrackingVolume* inert = (*((*aLVC.m_inertSpan)[gMode]))[i].first;
+	//bool rail = ( (*m_inertObjs)[i]->name() == "Rail" ) ? true : false; 
+	bool rLimit = (!aLVC.m_static3d || ( (*s)[4] <= rMaxc && (*s)[5] >= rMin ) ); 
+	if ( rLimit && (*s)[0] < zMax && (*s)[1] > zMin ) {
+	  bool accepted = false;
+	  if (phiLim) {
+	    if (pMin>=0 && pMax<=2*M_PI) {
+	      if ( (*s)[2]<=(*s)[3] && (*s)[2] <= pMax && (*s)[3] >= pMin )  accepted = true;
+	      if ( (*s)[2]>(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin) ) accepted = true;
+	    } else if (pMin < 0) {
+	      if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax || (*s)[3] >= pMin+2*M_PI) ) accepted = true;
+	      if ( (*s)[2]>(*s)[3]  ) accepted = true;
+	    } else if (pMax > 2*M_PI) {
+	      if ( (*s)[2]<=(*s)[3] && ((*s)[2] <= pMax-2*M_PI || (*s)[3] >= pMin) ) accepted = true;
+	      if ( (*s)[2]>(*s)[3]  ) accepted = true;
+	    }
+	  } else  accepted = true;
+	  if (accepted) {
+	    bool perm = inert->name().substr(inert->name().size()-4,4)=="PERM";
+	    if ( !m_blendInertMaterial || !m_removeBlended || perm ) detached.push_back(inert);
+	    if ( m_blendInertMaterial && !perm ) blendVols.push_back(inert);
+            ATH_MSG_VERBOSE( " Inert volume accepted by rLimit " <<  inert->name() << " zMin " << zMin << " zMax " << zMax << " rMin " << rMin << " rMax " << rMax << " PhiMin " << pMin  << " PhiMax " << pMax);
+	  }
+	}
+      } 
+    }
+  }
+  if (!detached.empty()) detTVs = new std::vector<const Trk::DetachedTrackingVolume*>(detached.begin(), detached.end()); 
+  return detTVs;
+}
+
+bool Muon::MuonTrackingGeometryBuilderCond::enclosed(const Trk::Volume* vol, const Muon::Span* s, LocalVariablesContainer &aLVC) const
+{
+  bool encl = false;
+  double tol = 1.;
+  double ptol = 0.11;     // 0.08 for BT, 0.11 feet
+  
+  // get min/max Z/Phi from volume (allways a cylinder/bevelled cylinder volume )  
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  const Trk::BevelledCylinderVolumeBounds* bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (&(vol->volumeBounds()));
+   
+  double rmed = 0.; double dphi = 0.; double hz = 0.; double rMin = 0.; double rMax = 0.; double rMaxc = 0.; int type = 0;
+  if (cyl) {
+    rmed = cyl->mediumRadius();
+    dphi = cyl->halfPhiSector();
+    hz = cyl->halflengthZ();
+    rMin = cyl->innerRadius();
+    rMax = cyl->outerRadius();
+    rMaxc = rMax;
+  } else if (bcyl) {
+    rmed = bcyl->mediumRadius();
+    dphi = bcyl->halfPhiSector();
+    hz = bcyl->halflengthZ();
+    rMin = bcyl->innerRadius();
+    rMax = bcyl->outerRadius();    
+    rMaxc = rMax;    
+    type = bcyl->type();
+    if (type>1) rMaxc *=1./cos(dphi);
+  } else return 0;
+ 
+  Amg::Vector3D center(rmed,0.,0.);
+  center = vol->transform() * center;
+
+  double zMin = center[2] - hz; 
+  double zMax = center[2] + hz;
+  double pMin = 0.;
+  double pMax = +2*M_PI;
+  bool phiLim = false;
+  if (dphi < M_PI) { 
+    pMin = center.phi() - dphi + M_PI; 
+    pMax = center.phi() + dphi + M_PI;
+    phiLim = true;
+  } 
+  //
+  //const Muon::Span* s = findVolumeSpan(&(cs->volumeBounds()), cs->transform(), 0.,0.) ;
+  //std::auto_ptr<const Muon::Span> s (findVolumeSpan(&(cs->volumeBounds()), cs->transform(), 0.,0.) );
+  ATH_MSG_VERBOSE( "enclosing volume:z:"<< zMin<<","<<zMax<<":r:"<< rMin<<","<<rMax<<":phi:"<<pMin<<","<<pMax);
+  //
+  bool rLimit = (!aLVC.m_static3d || ( (*s)[4] < rMax-tol && (*s)[5] > rMin+tol ) ); 
+  if ( rLimit && (*s)[0] < zMax-tol && (*s)[1] > zMin+tol ) {
+    if (phiLim) {
+      if (pMin>=0 && pMax<=2*M_PI) {
+	if ( (*s)[2]<=(*s)[3] && (*s)[2] < pMax+ptol && (*s)[3] > pMin-ptol )  return true;
+	if ( (*s)[2]>(*s)[3] && ((*s)[2] < pMax-ptol || (*s)[3] > pMin+ptol) ) return true;
+      } else if (pMin < 0) {
+	if ( (*s)[2]<=(*s)[3] && ((*s)[2] < pMax+ptol || (*s)[3] > pMin-ptol+2*M_PI) ) return true;
+	if ( (*s)[2]>(*s)[3]  ) return true;
+      } else if (pMax > 2*M_PI) {
+	if ( (*s)[2]<=(*s)[3] && ((*s)[2] < pMax+ptol-2*M_PI || (*s)[3] > pMin-ptol) ) return true;
+	if ( (*s)[2]>(*s)[3]  ) return true;
+      }
+    } else {
+      return true;
+    }
+  }
+  return encl;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::checkVolume(const Trk::TrackingVolume* vol ) const
+{
+
+  std::cout << "MuonTrackingGeometryBuilderCond::checkVolume: " << vol->volumeName() << std::endl;
+
+  const Trk::CylinderVolumeBounds* cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(vol->volumeBounds()));
+  if (!cyl) {
+    std::cout << "MuonTrackingGeometryBuilderCond::checkVolume:not a cylinder, return" << std::endl;
+    return;
+  }
+  std::cout << "cylinder dimensions:innerR,outerR,halfZ,halfPhi:" << cyl->innerRadius() << "," << cyl->outerRadius()
+	    << cyl->halflengthZ() << "," << cyl->halfPhiSector() << std::endl;
+
+  const Trk::GlueVolumesDescriptor& glueDescr = vol->glueVolumesDescriptor();
+  std::cout << "glue volumes:neg,pos,inn,outer" << (glueDescr.glueVolumes(Trk::negativeFaceXY)).size()<<"," 
+                                                << (glueDescr.glueVolumes(Trk::positiveFaceXY)).size()<<","
+                                                << (glueDescr.glueVolumes(Trk::tubeInnerCover)).size()<<","
+	                                        << (glueDescr.glueVolumes(Trk::tubeOuterCover)).size()<<std::endl;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getZParts(LocalVariablesContainer& aLVC) const
+{
+  // activeAdjustLevel:  1: separate MDT stations
+  //                        +(inertLevel=0) barrel Z partition
+  //                     2: split TGC
+  //                        +(inertLevel=0) barrel R partition
+  //                     3: split TGC supports
+  // inertAdjustLevel:   1: BT,ECT     
+ 
+  // hardcode for the moment
+  aLVC.m_zPartitions.clear();
+  aLVC.m_zPartitionsType.clear();
+  aLVC.m_zPartitions.reserve(120);
+  aLVC.m_zPartitionsType.reserve(120);
+
+  // outer endcap
+  aLVC.m_zPartitions.push_back(-aLVC.m_outerEndcapZ);  aLVC.m_zPartitionsType.push_back(1);   // EO
+  aLVC.m_zPartitions.push_back(-23001.);  aLVC.m_zPartitionsType.push_back(1);   // oute envelope change
+  //if (m_activeAdjustLevel>0) { m_zPartitions.push_back(-21630.);  m_zPartitionsType.push_back(1); }   // EOL
+  aLVC.m_zPartitions.push_back(-22030.);  aLVC.m_zPartitionsType.push_back(1);   // EOL
+  aLVC.m_zPartitions.push_back(-m_outerWheel);    aLVC.m_zPartitionsType.push_back(0);   // Octogon
+  // m_zPartitions.push_back(-17990.);          m_zPartitionsType.push_back(0);   // buffer
+  aLVC.m_zPartitions.push_back(-18650.);          aLVC.m_zPartitionsType.push_back(0);   // buffer
+  aLVC.m_zPartitions.push_back(-m_bigWheel);      aLVC.m_zPartitionsType.push_back(1);   // TGC3 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-15225.);  aLVC.m_zPartitionsType.push_back(1);}    
+  if (m_activeAdjustLevel>1) { aLVC.m_zPartitions.push_back(-15172.);  aLVC.m_zPartitionsType.push_back(1);}   // end supp 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-15128.);  aLVC.m_zPartitionsType.push_back(1);}   // supp 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-15070.);  aLVC.m_zPartitionsType.push_back(1);}    
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-14940.);  aLVC.m_zPartitionsType.push_back(1); }  //
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-14805.);  aLVC.m_zPartitionsType.push_back(1);}    
+  if (m_activeAdjustLevel>1) { aLVC.m_zPartitions.push_back(-14733.);  aLVC.m_zPartitionsType.push_back(1);}   // end supp.
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-14708.);  aLVC.m_zPartitionsType.push_back(1);}   // supp.   
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-14650.);  aLVC.m_zPartitionsType.push_back(1);}   //    
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-14560.);  aLVC.m_zPartitionsType.push_back(1); }   // EML 
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-14080.);  aLVC.m_zPartitionsType.push_back(1); }   // EMS
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-13620.);  aLVC.m_zPartitionsType.push_back(1); }   // TGC
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-13525.);  aLVC.m_zPartitionsType.push_back(1); }   // TGC
+  if (m_activeAdjustLevel>1) { aLVC.m_zPartitions.push_back(-13448.5); aLVC.m_zPartitionsType.push_back(1); }   // end supp.
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-13421.5); aLVC.m_zPartitionsType.push_back(1); }   // supp.
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-13346);   aLVC.m_zPartitionsType.push_back(1); }   // TGC
+
+  // inner endcap
+  aLVC.m_zPartitions.push_back(-aLVC.m_innerEndcapZ);     aLVC.m_zPartitionsType.push_back(0);   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-12790);  aLVC.m_zPartitionsType.push_back(0); }   // ECT 
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-12100.); aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-12000.); aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-11210.); aLVC.m_zPartitionsType.push_back(1); }   // BT 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-10480.); aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-9700.);  aLVC.m_zPartitionsType.push_back(0); }   // 
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-9300.);  aLVC.m_zPartitionsType.push_back(0); }   // rib
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-8800.);  aLVC.m_zPartitionsType.push_back(0); }   // ect
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-8610.);  aLVC.m_zPartitionsType.push_back(1); }   // BT
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-8000.);  aLVC.m_zPartitionsType.push_back(1); }   // BT
+  aLVC.m_zPartitions.push_back(-m_ectZ);  aLVC.m_zPartitionsType.push_back(0);              // ECT/small wheel
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-7450.); aLVC.m_zPartitionsType.push_back(0); }   // EIS 
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-7364.); aLVC.m_zPartitionsType.push_back(0); }   // EIS 
+  if (m_activeAdjustLevel>0 || m_inertAdjustLevel>0) {aLVC.m_zPartitions.push_back(-7170.); aLVC.m_zPartitionsType.push_back(0);}   // cone assembly,TGC 
+  if (m_activeAdjustLevel>0) { aLVC.m_zPartitions.push_back(-7030.); aLVC.m_zPartitionsType.push_back(0); }   // TGC
+  if (m_activeAdjustLevel>2) { aLVC.m_zPartitions.push_back(-6978.); aLVC.m_zPartitionsType.push_back(0); }   // TGC
+
+  // barrel
+  aLVC.m_zPartitions.push_back(-m_diskShieldZ);   aLVC.m_zPartitionsType.push_back(0);   // disk 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-6829.);  aLVC.m_zPartitionsType.push_back(0); }   // back disk 
+  //if (m_inertAdjustLevel>1) { (*m_zPartitions).push_back(-6600.);  m_zPartitionsType.push_back(0); }   // 
+  aLVC.m_zPartitions.push_back(-6550.); aLVC.m_zPartitionsType.push_back(0);          // outer envelope change
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-6100.);  aLVC.m_zPartitionsType.push_back(0); }  
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-5503.);  aLVC.m_zPartitionsType.push_back(1); }   // BT 
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-4772.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-4300.);  aLVC.m_zPartitionsType.push_back(0); }  //  
+  aLVC.m_zPartitions.push_back(-4000.); aLVC.m_zPartitionsType.push_back(0);          // outer envelope change
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-3700.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-3300.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-2600.);  aLVC.m_zPartitionsType.push_back(0); }   //  
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-2078.);  aLVC.m_zPartitionsType.push_back(1); }   // BT  
+  if (m_inertAdjustLevel>0) { aLVC.m_zPartitions.push_back(-1347.);  aLVC.m_zPartitionsType.push_back(1); }   //  cryoring 
+  if (m_activeAdjustLevel>0){ aLVC.m_zPartitions.push_back(-800.);   aLVC.m_zPartitionsType.push_back(1); }  //  cryoring 
+  if (m_inertAdjustLevel>1) { aLVC.m_zPartitions.push_back(-300.);   aLVC.m_zPartitionsType.push_back(0); }   //   
+  if (static_cast<int>(m_inertAdjustLevel)+static_cast<int>(m_activeAdjustLevel)<1) { aLVC.m_zPartitions.push_back(-0.7*m_diskShieldZ);   aLVC.m_zPartitionsType.push_back(0); }   //
+
+  unsigned int zSiz = aLVC.m_zPartitions.size();
+  for (unsigned int i = 0; i<zSiz ; i++) {
+    aLVC.m_zPartitions.push_back(- aLVC.m_zPartitions[zSiz-1-i]);  
+    if (i<zSiz-1) aLVC.m_zPartitionsType.push_back(aLVC.m_zPartitionsType[zSiz-2-i]);  
+  } 
+  
+  return;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getPhiParts(int mode, LocalVariablesContainer &aLVC) const
+{
+  if (mode==0) {             // trivial
+    aLVC.m_adjustedPhi.clear();
+    aLVC.m_adjustedPhiType.clear();
+    aLVC.m_adjustedPhi.push_back(0.);
+    aLVC.m_adjustedPhiType.push_back(0);
+
+  } else if (mode==1) {  
+    int phiNum = 1;
+    if ( m_activeAdjustLevel>0 ) phiNum = m_phiPartition;
+    aLVC.m_adjustedPhi.resize(phiNum);
+    aLVC.m_adjustedPhiType.resize(phiNum);
+    aLVC.m_adjustedPhi[0] = 0.;
+    aLVC.m_adjustedPhiType[0] = 0;
+    int ic = 0;
+    while (ic < phiNum-1 ) {
+      ic++; 
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2.*M_PI/phiNum ;
+      aLVC.m_adjustedPhiType[ic]= 0;
+    }
+
+  } else if (mode==2) {        // barrel(BT)
+    // hardcode for the moment
+    aLVC.m_adjustedPhi.resize(16);
+    aLVC.m_adjustedPhiType.resize(16);
+    
+    double phiSect[2];
+    phiSect[0] = ( M_PI/8 - 0.105 ); 
+    phiSect[1] = 0.105 ; 
+    
+    aLVC.m_adjustedPhi[0]= - phiSect[0];
+    aLVC.m_adjustedPhiType[0]= 0;
+    int ic = 0; int is = 1;
+
+    while (ic < 15 ) {
+      ic++; is = 1 - is;
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2*phiSect[is] ;
+      aLVC.m_adjustedPhiType[ic]= 1-is;
+    }
+
+  } else if (mode==3) {      // ECT(+BT)
+    // hardcode for the moment
+    aLVC.m_adjustedPhi.resize(32);
+    aLVC.m_adjustedPhiType.resize(32);
+    
+    double phiSect[3];
+    phiSect[0] = 0.126;
+    phiSect[2] = 0.105;
+    phiSect[1] = 0.5*( M_PI/8. - phiSect[0]-phiSect[2] ); 
+    
+    aLVC.m_adjustedPhi[0]= - phiSect[0];
+    aLVC.m_adjustedPhiType[0]= 0;
+    aLVC.m_adjustedPhi[1]= aLVC.m_adjustedPhi[0]+2*phiSect[0];
+    aLVC.m_adjustedPhiType[1]= 1;
+    int ic = 1; int is = 0;
+
+    while (ic < 31 ) {
+      ic++; is = 2 - is;
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2*phiSect[1] ;
+      aLVC.m_adjustedPhiType[ic]= is;
+      ic++;
+      aLVC.m_adjustedPhi[ic]= aLVC.m_adjustedPhi[ic-1] + 2*phiSect[is] ;
+      aLVC.m_adjustedPhiType[ic]= 1;
+    }
+    //for (unsigned int ic=0;ic<m_adjustedPhi.size();ic++) std::cout<<"adjustedPhi:"<<ic<<","<<m_adjustedPhi[ic]<<","<<m_adjustedPhiType[ic]<< std::endl;
+  }
+
+  return;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getHParts(LocalVariablesContainer &aLVC) const
+{
+  // hardcode for the moment
+  aLVC.m_hPartitions.clear();              // barrel, inner endcap, outer endcap
+
+  // 0: barrel 2x2
+  // non BT sector
+  std::vector<std::pair<int,float> >  barrelZ0F0;
+  barrelZ0F0.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (m_activeAdjustLevel>0) {
+    barrelZ0F0.push_back( std::pair<int,float>(0,4450.) );                // for DiskShieldingBackDisk
+    barrelZ0F0.push_back( std::pair<int,float>(0,6500.) );                // BI/BM
+    barrelZ0F0.push_back( std::pair<int,float>(0,8900.) );                // BM/BO
+    barrelZ0F0.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  }
+  barrelZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::pair<int,float> >  barrelZ0F1;
+  barrelZ0F1.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ0F1.push_back( std::pair<int,float>(1,4500.) );
+    barrelZ0F1.push_back( std::pair<int,float>(1,5900.) );
+  } else if (m_activeAdjustLevel>0) barrelZ0F1.push_back( std::pair<int,float>(0,4450.) );                
+  if (m_activeAdjustLevel>0) barrelZ0F1.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0)  barrelZ0F1.push_back( std::pair<int,float>(1,8900.) );
+  else if (m_activeAdjustLevel>0)  barrelZ0F1.push_back( std::pair<int,float>(0,8900.) );
+  if (m_inertAdjustLevel>0)  barrelZ0F1.push_back( std::pair<int,float>(1,10100.) );
+  barrelZ0F1.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  barrelZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // BT sector
+  std::vector<std::pair<int,float> >  barrelZ1F0;
+  barrelZ1F0.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (static_cast<int>(m_activeAdjustLevel)+static_cast<int>(m_inertAdjustLevel)>0) barrelZ1F0.push_back( std::pair<int,float>(0,4450.) );                
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F0.push_back( std::pair<int,float>(1,5800.) );
+    barrelZ1F0.push_back( std::pair<int,float>(1,6500.) );
+  } else if (m_activeAdjustLevel>0) barrelZ1F0.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F0.push_back( std::pair<int,float>(1,6750.) );
+    barrelZ1F0.push_back( std::pair<int,float>(1,8400.) );
+  }
+  if (m_activeAdjustLevel>0) barrelZ1F0.push_back( std::pair<int,float>(0,8770.) );  // adapted for cryoring (from 8900)
+  if (m_inertAdjustLevel>0) barrelZ1F0.push_back( std::pair<int,float>(1,9850.) );   // adapted for cryoring (from 9600)
+  barrelZ1F0.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  barrelZ1F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::pair<int,float> >  barrelZ1F1;
+  barrelZ1F1.push_back( std::pair<int,float>(0,aLVC.m_innerBarrelRadius) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F1.push_back( std::pair<int,float>(1,4500.) );
+    barrelZ1F1.push_back( std::pair<int,float>(1,6000.) );
+  } else if (m_activeAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(0,4450.) );
+  if (m_activeAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(1,6800.) );
+  if (m_inertAdjustLevel>0) {
+    barrelZ1F1.push_back( std::pair<int,float>(1,8900.) );
+    barrelZ1F1.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) barrelZ1F1.push_back( std::pair<int,float>(0,8900.) );
+  barrelZ1F1.push_back( std::pair<int,float>(0,13000.) );               // outer envelope
+  barrelZ1F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  barrelZF(2);
+  barrelZF[0].push_back(barrelZ0F0);
+  barrelZF[0].push_back(barrelZ0F1);
+  barrelZF[1].push_back(barrelZ1F0);
+  barrelZF[1].push_back(barrelZ1F1);
+
+  // small wheel 1x2 ( no z BT sector) 
+  // non BT sector
+  std::vector<std::pair<int,float> >  swZ0F0;
+  swZ0F0.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_activeAdjustLevel>1) {
+    swZ0F0.push_back( std::pair<int,float>(0,2700.) );                
+  }
+  if (static_cast<int>(m_activeAdjustLevel)+static_cast<int>(m_inertAdjustLevel)>0) swZ0F0.push_back( std::pair<int,float>(0,4450.) );                
+  if (m_activeAdjustLevel>0) {
+    swZ0F0.push_back( std::pair<int,float>(0,6560.) );                // BI/BM
+    swZ0F0.push_back( std::pair<int,float>(0,8900.) );                // BM/BO
+  }
+  swZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // phi BT sector
+  std::vector<std::pair<int,float> >  swZ0F1;
+  swZ0F1.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_activeAdjustLevel>1) swZ0F1.push_back( std::pair<int,float>(0,2700.) );               
+  if (static_cast<int>(m_inertAdjustLevel)+static_cast<int>(m_activeAdjustLevel)>0) swZ0F1.push_back( std::pair<int,float>(0,4450.) );
+  if (m_inertAdjustLevel>0) swZ0F1.push_back( std::pair<int,float>(1,5900.) );
+  if (m_activeAdjustLevel>0) swZ0F1.push_back( std::pair<int,float>(0,6560.) );
+  if (m_inertAdjustLevel>0) {
+    swZ0F1.push_back( std::pair<int,float>(1,8900.) );
+    swZ0F1.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) swZ0F1.push_back( std::pair<int,float>(0,8900.) );
+  swZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  swZF(1);
+  swZF[0].push_back(swZ0F0);
+  swZF[0].push_back(swZ0F1);
+
+  // inner endcap/ECT 2x3
+  // ect coil, non-BT z
+  std::vector<std::pair<int,float> >  innerZ0F0;
+  innerZ0F0.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ0F0.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) innerZ0F0.push_back( std::pair<int,float>(1,5150.) );
+  if (m_inertAdjustLevel>0) innerZ0F0.push_back( std::pair<int,float>(1,5300.) );
+  if (m_activeAdjustLevel>0) {
+    innerZ0F0.push_back( std::pair<int,float>(0,6500.) );
+    innerZ0F0.push_back( std::pair<int,float>(0,8900.) );
+  }
+  innerZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // coil gap, non-BT z
+  std::vector<std::pair<int,float> >  innerZ0F1;
+  innerZ0F1.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ0F1.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ0F1.push_back( std::pair<int,float>(1,1400.) );
+    innerZ0F1.push_back( std::pair<int,float>(1,1685.) );
+  }
+  if (m_inertAdjustLevel>0) {
+    innerZ0F1.push_back( std::pair<int,float>(1,4700.) );
+    innerZ0F1.push_back( std::pair<int,float>(1,5900.) );
+  }
+  if (m_activeAdjustLevel>0) {
+    innerZ0F1.push_back( std::pair<int,float>(0,6500.) );
+    innerZ0F1.push_back( std::pair<int,float>(0,8900.) );
+  }
+  innerZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // BT coil, no-BT z 
+  std::vector<std::pair<int,float> >  innerZ0F2;
+  innerZ0F2.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ0F2.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ0F2.push_back( std::pair<int,float>(1,1400.) );
+    innerZ0F2.push_back( std::pair<int,float>(1,1685.) );
+  }
+  if (m_inertAdjustLevel>0) {
+    innerZ0F2.push_back( std::pair<int,float>(1,4450.) );
+    innerZ0F2.push_back( std::pair<int,float>(1,5900.) );
+  }
+  if (m_activeAdjustLevel>0) innerZ0F2.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ0F2.push_back( std::pair<int,float>(1,8900.) );
+    innerZ0F2.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) innerZ0F2.push_back( std::pair<int,float>(0,8900.) );
+  innerZ0F2.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // ect coil, z BT sector
+  std::vector<std::pair<int,float> >  innerZ1F0;
+  innerZ1F0.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) innerZ1F0.push_back( std::pair<int,float>(1,5150.) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(1,5300.) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(1,5800.) );
+  if (m_inertAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(1,6750.) );
+  else if (m_activeAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F0.push_back( std::pair<int,float>(1,8400.) );
+    innerZ1F0.push_back( std::pair<int,float>(1,9600.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F0.push_back( std::pair<int,float>(0,8900.) );
+  innerZ1F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // coil gap, BT z sector
+  std::vector<std::pair<int,float> >  innerZ1F1;
+  innerZ1F1.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0)  innerZ1F1.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ1F1.push_back( std::pair<int,float>(1,1400.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,1685.) );
+  }
+  if (m_inertAdjustLevel>0) {
+    innerZ1F1.push_back( std::pair<int,float>(1,4700.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,5800.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,6750.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F1.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F1.push_back( std::pair<int,float>(1,8400.) );
+    innerZ1F1.push_back( std::pair<int,float>(1,9600.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F1.push_back( std::pair<int,float>(0,8900.) );
+  innerZ1F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  // BT coil, BT z sector
+  std::vector<std::pair<int,float> >  innerZ1F2;
+  innerZ1F2.push_back( std::pair<int,float>(0,m_innerShieldRadius) );
+  if (m_inertAdjustLevel>0) innerZ1F2.push_back( std::pair<int,float>(0,1100.) );
+  if (m_inertAdjustLevel>1) {
+    innerZ1F2.push_back( std::pair<int,float>(1,1400.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,1685.) );
+  }
+  innerZ1F2.push_back( std::pair<int,float>(0,4150.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F2.push_back( std::pair<int,float>(1,4700.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,5900.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,6800.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F2.push_back( std::pair<int,float>(0,6500.) );
+  if (m_inertAdjustLevel>0) {
+    innerZ1F2.push_back( std::pair<int,float>(1,8900.) );
+    innerZ1F2.push_back( std::pair<int,float>(1,10100.) );
+  } else if (m_activeAdjustLevel>0) innerZ1F2.push_back( std::pair<int,float>(0,8900.) );
+  innerZ1F2.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  innerZF(2);
+  innerZF[0].push_back(innerZ0F0);
+  innerZF[0].push_back(innerZ0F1);
+  innerZF[0].push_back(innerZ0F2);
+  innerZF[1].push_back(innerZ1F0);
+  innerZF[1].push_back(innerZ1F1);
+  innerZF[1].push_back(innerZ1F2);
+
+  // outer 1x1
+  std::vector<std::pair<int,float> >  outerZ0F0;
+  outerZ0F0.push_back( std::pair<int,float>(0,m_outerShieldRadius) );
+  outerZ0F0.push_back( std::pair<int,float>(0,2750.) );       // outer envelope 
+  outerZ0F0.push_back( std::pair<int,float>(0,12650.) );      // outer envelope
+  outerZ0F0.push_back( std::pair<int,float>(0,13400.) );      // outer envelope
+  outerZ0F0.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::pair<int,float> >  outerZ0F1;
+  outerZ0F1.push_back( std::pair<int,float>(0,m_outerShieldRadius) );
+  outerZ0F1.push_back( std::pair<int,float>(0,2750.) );      // outer envelope
+  if ( m_activeAdjustLevel>0 ) {
+    outerZ0F1.push_back( std::pair<int,float>(0,3600.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,5300.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,7000.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,8500.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,10000.) );
+    outerZ0F1.push_back( std::pair<int,float>(0,12000.) );
+  }
+  outerZ0F1.push_back( std::pair<int,float>(0,12650.) );      // outer envelope
+  outerZ0F1.push_back( std::pair<int,float>(0,13400.) );      // outer envelope
+  outerZ0F1.push_back( std::pair<int,float>(0,aLVC.m_outerBarrelRadius) );
+
+  std::vector<std::vector<std::vector<std::pair<int,float> > > >  outerZF(2);
+  outerZF[0].push_back(outerZ0F0);
+  outerZF[0].push_back(outerZ0F0);
+  outerZF[0].push_back(outerZ0F0);
+  outerZF[1].push_back(outerZ0F1);
+  outerZF[1].push_back(outerZ0F1);
+  outerZF[1].push_back(outerZ0F1);
+
+  // collect everything
+  aLVC.m_hPartitions.push_back(barrelZF);
+  aLVC.m_hPartitions.push_back(swZF);
+  aLVC.m_hPartitions.push_back(innerZF);
+  aLVC.m_hPartitions.push_back(outerZF);
+   
+  return;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::getShieldParts(LocalVariablesContainer& aLVC) const
+{
+  aLVC.m_shieldZPart.resize(18);
+
+  aLVC.m_shieldZPart[0]=-21900.;      // elm2
+  aLVC.m_shieldZPart[1]=-21500.;      // elm1
+  aLVC.m_shieldZPart[2]=-21000.;      // octogon
+  aLVC.m_shieldZPart[3]=-18000.;      // tube
+  aLVC.m_shieldZPart[4]=-12882.;      // ect
+  aLVC.m_shieldZPart[5]= -7930.;      // ect
+  aLVC.m_shieldZPart[6]= -7914.;      // cone
+  aLVC.m_shieldZPart[7]= -6941.;      // disk
+  aLVC.m_shieldZPart[8]= -6783.;       //
+  for (unsigned int i = 9; i<18 ; i++) aLVC.m_shieldZPart[i] = - aLVC.m_shieldZPart[17-i];  
+
+  aLVC.m_shieldHPart.clear();
+
+  std::vector<std::pair<int,float> >  outerShield;
+  outerShield.push_back(std::pair<int,float>(0,m_beamPipeRadius));
+  outerShield.push_back(std::pair<int,float>(0,279.));    // outer envelope
+  outerShield.push_back(std::pair<int,float>(0,436.7));   // outer envelope
+  outerShield.push_back(std::pair<int,float>(0,1050.));   // outer envelope 
+  outerShield.push_back(std::pair<int,float>(0,m_outerShieldRadius));
+  aLVC.m_shieldHPart.push_back(outerShield);
+
+  std::vector<std::pair<int,float> >  innerShield;
+  innerShield.push_back(std::pair<int,float>(0,m_beamPipeRadius));
+  innerShield.push_back(std::pair<int,float>(0,530.));
+  innerShield.push_back(std::pair<int,float>(0,m_innerShieldRadius));
+  aLVC.m_shieldHPart.push_back(innerShield);
+
+  std::vector<std::pair<int,float> >  diskShield;
+  diskShield.push_back(std::pair<int,float>(0,0.));
+  diskShield.push_back(std::pair<int,float>(0,540.));
+  diskShield.push_back(std::pair<int,float>(0,750.));
+  diskShield.push_back(std::pair<int,float>(0,2700.));
+  diskShield.push_back(std::pair<int,float>(0,4255.));
+  aLVC.m_shieldHPart.push_back(diskShield);
+
+  return;
+}
+
+double  Muon::MuonTrackingGeometryBuilderCond::calculateVolume( const Trk::Volume* envelope) const
+{
+  double envVol = 0.;
+  
+  if (!envelope) return 0.;
+  
+  const Trk::CylinderVolumeBounds*  cyl = dynamic_cast<const Trk::CylinderVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::CuboidVolumeBounds*    box = dynamic_cast<const Trk::CuboidVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::TrapezoidVolumeBounds* trd = dynamic_cast<const Trk::TrapezoidVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::BevelledCylinderVolumeBounds*  bcyl = dynamic_cast<const Trk::BevelledCylinderVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::PrismVolumeBounds* prism = dynamic_cast<const Trk::PrismVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::SimplePolygonBrepVolumeBounds* spb = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::CombinedVolumeBounds*  comb = dynamic_cast<const Trk::CombinedVolumeBounds*> (&(envelope->volumeBounds()));
+  const Trk::SubtractedVolumeBounds*  sub = dynamic_cast<const Trk::SubtractedVolumeBounds*> (&(envelope->volumeBounds()));  
+
+  if ( cyl ) envVol = 2*cyl->halfPhiSector()*(cyl->outerRadius()*cyl->outerRadius()-cyl->innerRadius()*cyl->innerRadius())*cyl->halflengthZ();
+  if ( box ) envVol = (8*box->halflengthX()*box->halflengthY()*box->halflengthZ());
+  if ( trd ) envVol = (4*(trd->minHalflengthX()+trd->maxHalflengthX())*trd->halflengthY()*trd->halflengthZ());
+  if ( bcyl ) {
+    int type = bcyl->type();
+    if ( type<1 ) envVol = 2*bcyl->halfPhiSector()*(bcyl->outerRadius()*bcyl->outerRadius()-bcyl->innerRadius()*bcyl->innerRadius())*bcyl->halflengthZ(); 
+    if ( type==1 ) envVol = 2*bcyl->halflengthZ()*( bcyl->halfPhiSector()*bcyl->outerRadius()*bcyl->outerRadius()
+						    -bcyl->innerRadius()*bcyl->innerRadius()*tan(bcyl->halfPhiSector()) ); 
+    if ( type==2 ) envVol = 2*bcyl->halflengthZ()*( -bcyl->halfPhiSector()*bcyl->innerRadius()*bcyl->innerRadius()
+						    +bcyl->outerRadius()*bcyl->outerRadius()*tan(bcyl->halfPhiSector()) ); 
+    if ( type==3 ) envVol = 2*bcyl->halflengthZ()*tan(bcyl->halfPhiSector())*( bcyl->outerRadius()*bcyl->outerRadius() 
+									       -bcyl->innerRadius()*bcyl->innerRadius()); 
+  }
+  if ( prism ) {
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#define double float
+#endif    
+    std::vector<std::pair<double,double> > v=prism->xyVertices();
+#ifdef TRKDETDESCR_USEFLOATPRECISON
+#undef double
+#endif      
+    double a2 = v[1].first*v[1].first+v[1].second*v[1].second
+               +v[0].first*v[0].first+v[0].second*v[0].second
+	    -2*(v[0].first*v[1].first+v[0].second*v[1].second);
+    double c2 = v[2].first*v[2].first+v[2].second*v[2].second
+               +v[0].first*v[0].first+v[0].second*v[0].second
+	    -2*(v[0].first*v[2].first+v[0].second*v[2].second);
+    double ca = v[1].first*v[2].first+v[1].second*v[2].second
+               +v[0].first*v[0].first+v[0].second*v[0].second
+	       -v[0].first*v[1].first-v[0].second*v[1].second
+	       -v[0].first*v[2].first-v[0].second*v[2].second;
+    double vv = sqrt(c2-ca*ca/a2);
+    envVol = vv*sqrt(a2)*prism->halflengthZ();
+  }
+  if ( spb ) {
+    envVol = calculateVolume(spb->combinedVolume());    // exceptional use of combined volume (no intersections)
+  }   
+  if ( comb ) {
+    envVol = calculateVolume(comb->first()) + calculateVolume(comb->second());
+  }
+  if ( sub ) {
+    return -1;
+  }
+
+  return envVol;
+}
+
+void Muon::MuonTrackingGeometryBuilderCond::blendMaterial(LocalVariablesContainer& aLVC) const
+{
+  // loop over map
+  //std::map<const Trk::DetachedTrackingVolume*,std::vector<const Trk::TrackingVolume*>* >::iterator mIter = m_blendMap.begin();
+  std::vector<const Trk::DetachedTrackingVolume*>::iterator viter = aLVC.m_blendVols.begin();
+
+  const std::vector<std::pair<const Trk::Volume*,float> >* cs = 0;
+  
+  //  for ( ; mIter!= m_blendMap.end(); mIter++) {
+  //  cs = (*mIter).first->constituents();     
+  for (;viter!= aLVC.m_blendVols.end();++viter) {
+    cs = (*viter)->constituents();
+    if (!cs) continue;
+    // find material source
+    //const Trk::Material* detMat = (*mIter).first->trackingVolume();
+    const Trk::Material* detMat = (*viter)->trackingVolume();
+    //if ( (*mIter).first->trackingVolume()->confinedDenseVolumes()) detMat = (*(*mIter).first->trackingVolume()->confinedDenseVolumes())[0];
+    if ( (*viter)->trackingVolume()->confinedDenseVolumes()) detMat = (*(*viter)->trackingVolume()->confinedDenseVolumes())[0];
+    for (unsigned int ic=0; ic<cs->size(); ic++) {
+      //const Trk::Volume* nCs = new Trk::Volume(*((*cs)[ic].first),(*mIter).first->trackingVolume()->transform());
+      const Trk::Volume* nCs = new Trk::Volume(*((*cs)[ic].first),(*viter)->trackingVolume()->transform());
+      double fraction = (*cs)[ic].second;
+      double csVol = fraction*calculateVolume(nCs);      
+      const Muon::Span* s = findVolumeSpan(&(nCs->volumeBounds()), nCs->transform(), 0.,0.,aLVC) ;
+      if (s) {
+	ATH_MSG_VERBOSE("constituent:"<<ic<<":z:"<< (*s)[0]<<","<<(*s)[1]<<":r:"<< (*s)[4]<<","<<(*s)[5]
+			<<":phi:"<<(*s)[2]<<","<<(*s)[3]);      
+	double enVol = 0.;
+	// loop over frame volumes, check if confined
+	//std::vector<const Trk::TrackingVolume*>::iterator fIter = (*mIter).second->begin(); 
+	std::vector<const Trk::TrackingVolume*>* vv =aLVC.m_blendMap[*viter]; 
+	std::vector<const Trk::TrackingVolume*>::iterator fIter=vv->begin(); 
+	std::vector<bool> fEncl; 
+	fEncl.clear();
+	// blending factors can be saved, and not recalculated for each clone
+	//for ( ; fIter!=(*mIter).second->end(); fIter++) {
+	for ( ; fIter!=vv->end(); fIter++) {
+	  fEncl.push_back(enclosed(*fIter,s,aLVC));
+	  if ( fEncl.back() ) enVol += calculateVolume(*fIter);
+	}
+	// diluting factor
+	double dil =  enVol>0. ?  csVol/enVol : 0.;
+	//std::cout << "const:dil:"<< ic<<","<<dil<< std::endl;
+	if (dil>0.) { 
+	  //for ( fIter=(*mIter).second->begin(); fIter!=(*mIter).second->end(); fIter++) { 
+	  for ( fIter=vv->begin(); fIter!=vv->end(); fIter++) { 
+	    //if (fEncl[fIter-(*mIter).second->begin()]) { (*fIter)->addMaterial(*detMat,dil); if (m_colorCode==0) (*fIter)->registerColorCode(12) ; 
+	    if (fEncl[fIter-vv->begin()]) { (*fIter)->addMaterial(*detMat,dil); if (m_colorCode==0) (*fIter)->registerColorCode(12) ; 
+	      //ATH_MSG_VERBOSE((*fIter)->volumeName()<<" acquires material from "<<  (*mIter).first->name());  }
+	      ATH_MSG_VERBOSE((*fIter)->volumeName()<<" acquires material from "<<  (*viter)->name());  }
+	  }
+	  ATH_MSG_VERBOSE("diluting factor:"<< dil<<" for "<< (*viter)->name()<<","<<ic);
+	} else {
+	  ATH_MSG_VERBOSE("diluting factor:"<< dil<<" for "<< (*viter)->name()<<","<<ic);
+	}
+      }
+      delete nCs; delete s;
+    }
+    if ( m_removeBlended ) {  ATH_MSG_VERBOSE("deleting "<< (*viter)->name()); delete *viter; }
+  }
+}
diff --git a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx
index 923aa7eaa8e..576b652ff9d 100644
--- a/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx
+++ b/MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/src/components/MuonTrackingGeometry_entries.cxx
@@ -3,6 +3,7 @@
 #include "MuonTrackingGeometry/MuonStationTypeBuilder.h"
 #include "MuonTrackingGeometry/MuonInertMaterialBuilder.h"
 
+#include "MuonTrackingGeometry/MuonTrackingGeometryBuilderCond.h"
 
 using namespace Muon;
 
@@ -11,3 +12,4 @@ DECLARE_COMPONENT( MuonStationBuilder )
 DECLARE_COMPONENT( MuonStationTypeBuilder )
 DECLARE_COMPONENT( MuonInertMaterialBuilder )
 
+DECLARE_COMPONENT( MuonTrackingGeometryBuilderCond )
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h
index e02deeea842..d85ca20ef79 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/ISF_FatrasDetDescrTools/LayerMaterialProvider.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -46,20 +46,20 @@ namespace iFatras {
     virtual ~LayerMaterialProvider();
 
     /** Processor Action to work on TrackingGeometry& tgeo */
-    virtual StatusCode process(const Trk::TrackingGeometry& tgeo);
+    virtual StatusCode process(const Trk::TrackingGeometry& tgeo) const;
        
     /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-    virtual StatusCode process(const Trk::TrackingVolume& tvol, size_t level = 0);   
+    virtual StatusCode process(const Trk::TrackingVolume& tvol, size_t level = 0) const;
        
     /** Processor Action to work on Layers */
-    virtual StatusCode process(const Trk::Layer& lay, size_t level = 0);
+    virtual StatusCode process(const Trk::Layer& lay, size_t level = 0) const;
        
     /** Processor Action to work on Surfaces */
-    virtual StatusCode process(const Trk::Surface& surf, size_t level = 0);
+    virtual StatusCode process(const Trk::Surface& surf, size_t level = 0) const;
 
   private:
           
-    StatusCode loadMaterialMap();               //!< reatrieve the Material map from the detector store
+    StatusCode loadMaterialMap() const; //!< retrieve the Material map from the detector store
 
     //!< boolean switch for assignLayerMaterial
     mutable const Trk::LayerMaterialMap*         m_layerMaterialMap;
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx
index 6ba568e5eaf..1c4d75f1a78 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasDetDescrTools/src/LayerMaterialProvider.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -34,7 +34,7 @@ iFatras::LayerMaterialProvider::~LayerMaterialProvider()
 
 
 // Processor Action to work on TrackingGeometry 
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) const{
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -79,7 +79,7 @@ StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingGeometry&
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) const{
   
   // load the material map if not done yet
   if (!m_layerMaterialMap){ 
@@ -149,7 +149,7 @@ StatusCode iFatras::LayerMaterialProvider::process(const Trk::TrackingVolume& tv
 }
 
 // Processor Action to work on Layers 
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) const {
 
     // load the material map if not done yet
     if (!m_layerMaterialMap){ 
@@ -187,12 +187,12 @@ StatusCode iFatras::LayerMaterialProvider::process(const Trk::Layer& lay, size_t
 }
 
 // Processor Action to work on Surfaces 
-StatusCode iFatras::LayerMaterialProvider::process(const Trk::Surface&, size_t) {
+StatusCode iFatras::LayerMaterialProvider::process(const Trk::Surface&, size_t) const {
     return StatusCode::SUCCESS;
 }
 
 // load the material map from StoreGate
-StatusCode iFatras::LayerMaterialProvider::loadMaterialMap() {
+StatusCode iFatras::LayerMaterialProvider::loadMaterialMap() const {
     
     // -------------------------------------------------------------------------------
     if (detStore()->retrieve(m_layerMaterialMap, m_layerMaterialMapName).isFailure()){
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt b/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
new file mode 100644
index 00000000000..fcae79acc82
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
@@ -0,0 +1,40 @@
+################################################################################
+# Package: TrackingGeometryCondAlg
+################################################################################
+
+# Declare the package name:
+atlas_subdir( TrackingGeometryCondAlg )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs(
+   PUBLIC
+   Control/AthenaBaseComps
+   Control/AthenaKernel
+   GaudiKernel
+   Tracking/TrkDetDescr/TrkDetDescrInterfaces
+   Tracking/TrkDetDescr/TrkDetDescrUtils
+   Tracking/TrkDetDescr/TrkGeometry
+   InnerDetector/InDetDetDescr/InDetReadoutGeometry
+   PRIVATE
+    )
+
+find_package( Eigen )
+
+# Component(s) in the package:
+
+atlas_add_component( TrackingGeometryCondAlg
+   TrackingGeometryCondAlg/*.h src/*.cxx src/components/*.cxx
+   INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}
+   LINK_LIBRARIES ${EIGEN_LIBRARIES} 
+   AthenaBaseComps
+   AthenaKernel
+   GaudiKernel 
+   TrkDetDescrInterfaces
+   TrkDetDescrUtils
+   TrkGeometry
+   InDetReadoutGeometry
+    )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
new file mode 100644
index 00000000000..b450935f4c7
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
@@ -0,0 +1,45 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef TRACKINGGEOMETRYCONDALG_H
+#define TRACKINGGEOMETRYCONDALG_H
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "PersistentDataModel/AthenaAttributeList.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrInterfaces/IGeometryProcessor.h"
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+
+#include "GaudiKernel/ICondSvc.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaKernel/CLASS_DEF.h"
+
+namespace Trk{
+class TrackingGeometryCondAlg : public AthReentrantAlgorithm
+{
+public:
+  TrackingGeometryCondAlg(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TrackingGeometryCondAlg() override = default;
+
+  virtual StatusCode initialize() override;
+  virtual StatusCode execute(const EventContext& ctx) const override;
+  virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
+  /** Make this algorithm clonable. */
+  virtual bool isClonable() const override { return true; };
+
+private:
+
+  /// Output conditions object.
+  SG::WriteCondHandleKey<TrackingGeometry> m_trackingGeometryWriteKey{this, "TrackingGeometryWriteKey", "AlignedTrackingGeometry", "Key of output of TrackingGeometry for ID"};
+  ServiceHandle<ICondSvc> m_condSvc{this, "CondSvc", "CondSvc"};
+  ToolHandle<Trk::IGeometryBuilderCond>           m_trackingGeometryBuilder {this, "GeometryBuilder", ""};
+  ToolHandleArray<Trk::IGeometryProcessor>    m_geometryProcessors ;
+};
+}
+#endif //TRACKINGGEOMETRYCONDALG_H
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
new file mode 100644
index 00000000000..8a433eb66a8
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlg.py
@@ -0,0 +1,180 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+##################################################################################
+# The AtlasTrackingGeometryCondAlg fragment
+#
+# usage: 
+#   from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+#   TrkGeoCondAlg = ConfiguredTrackingGeometryCondAlg('AtlasTrackingGeometryCondAlg')
+#   from AthenaCommon.AlgSequence import AthSequencer
+#   condSeq = AthSequencer("AthCondSeq")
+#   condSeq+= TrkGeoCondAlg
+#
+##################################################################################
+# import the DetFlags for the setting
+from AthenaCommon.DetFlags import DetFlags
+
+#################################################################################
+# Material for the Geometry comes from COOL or local database
+#################################################################################
+
+from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+
+
+from TrackingGeometryCondAlg.TrackingGeometryCondAlgConf import Trk__TrackingGeometryCondAlg
+   
+class ConfiguredTrackingGeometryCondAlg( Trk__TrackingGeometryCondAlg ) :   
+
+    # constructor
+    def __init__(self,name = 'AtlasTrackingGeometryCondAlg'):
+        
+        if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+          print ('[ Configuration : start ] *** '+name+' ********************************')
+          print ('[ TrackingGeometryCondAlg ]')
+        
+        from AthenaCommon.AppMgr import ToolSvc 
+
+        #################################################################################
+        # The Geometry Builder
+        #################################################################################
+        
+        # the geometry builder alg tool
+        from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__GeometryBuilderCond
+        AtlasGeometryBuilder = Trk__GeometryBuilderCond(name = 'AtlasGeometryBuilder')
+        # switch the building outputlevel on 
+        AtlasGeometryBuilder.OutputLevel = TrkDetFlags.ConfigurationOutputLevel()
+        
+        # the envelope definition service
+        from AthenaCommon.CfgGetter import getPrivateTool,getPrivateToolClone,getPublicTool,getPublicToolClone,\
+           getService,getServiceClone,getAlgorithm,getAlgorithmClone
+        AtlasEnvelopeSvc = getService('AtlasGeometry_EnvelopeDefSvc')
+           
+        # (ID) 
+        if DetFlags.ID_on() :
+#          FIXME: removed to get the migration to CondAlg started
+#          # get hand on the ID Tracking Geometry Builder
+#          if TrkDetFlags.ISF_FatrasCustomGeometry() :
+#              if hasattr(ToolSvc, TrkDetFlags.ISF_FatrasCustomGeometryBuilderName()):
+#                  InDetTrackingGeometryBuilder = getattr(ToolSvc, TrkDetFlags.ISF_FatrasCustomGeometryBuilderName())
+#          elif TrkDetFlags.XMLFastCustomGeometry() :
+#              if hasattr(ToolSvc, TrkDetFlags.InDetTrackingGeometryBuilderName()):
+#                  InDetTrackingGeometryBuilder = getattr(ToolSvc, TrkDetFlags.InDetTrackingGeometryBuilderName())
+#          else:
+          if not TrkDetFlags.InDetStagedGeometryBuilder():
+              from InDetTrackingGeometry.ConfiguredInDetTrackingGeometryBuilderCond import ConfiguredInDetTrackingGeometryBuilderCond as IDGeometryBuilder
+          else:
+              from InDetTrackingGeometry.ConfiguredStagedTrackingGeometryBuilderCond import ConfiguredStagedTrackingGeometryBuilderCond as IDGeometryBuilder
+          InDetTrackingGeometryBuilder = IDGeometryBuilder(name ='InDetTrackingGeometryBuilder')
+                
+          InDetTrackingGeometryBuilder.EnvelopeDefinitionSvc = AtlasEnvelopeSvc
+          InDetTrackingGeometryBuilder.OutputLevel = TrkDetFlags.InDetBuildingOutputLevel()
+          # and give it to the Geometry Builder
+          AtlasGeometryBuilder.InDetTrackingGeometryBuilder = InDetTrackingGeometryBuilder
+          # 
+        # (Calo)
+        if DetFlags.Calo_on() :
+           from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__CylinderVolumeCreator
+           CaloVolumeCreator = Trk__CylinderVolumeCreator("CaloVolumeCreator")
+           CaloVolumeCreator.OutputLevel = TrkDetFlags.CaloBuildingOutputLevel()
+           ToolSvc += CaloVolumeCreator
+
+           from CaloTrackingGeometry.ConfiguredCaloTrackingGeometryBuilderCond import ConfiguredCaloTrackingGeometryBuilderCond as ConfiguredCaloGeo 
+           CaloTrackingGeometryBuilder = ConfiguredCaloGeo(name='CaloTrackingGeometryBuilder');
+           CaloTrackingGeometryBuilder.TrackingVolumeCreator = CaloVolumeCreator
+           CaloTrackingGeometryBuilder.EnvelopeDefinitionSvc = AtlasEnvelopeSvc
+           CaloTrackingGeometryBuilder.OutputLevel           = TrkDetFlags.CaloBuildingOutputLevel()
+           CaloTrackingGeometryBuilder.GeometryName          = 'Calo'
+           # and give it to the Geometry Builder
+           AtlasGeometryBuilder.CaloTrackingGeometryBuilder = CaloTrackingGeometryBuilder
+        
+        # (Muon)
+        if DetFlags.Muon_on() :
+           from MuonTrackingGeometry.ConfiguredMuonTrackingGeometryCond import MuonTrackingGeometryBuilderCond
+           MuonTrackingGeometryBuilderCond.EnvelopeDefinitionSvc = AtlasEnvelopeSvc
+           # and give it to the Geometry Builder
+           AtlasGeometryBuilder.MuonTrackingGeometryBuilder = MuonTrackingGeometryBuilderCond
+           
+        # processors
+        AtlasGeometryProcessors = []   
+           
+        # check whether the material retrieval is ment to be from COOL
+        if TrkDetFlags.MaterialSource() is 'COOL':
+            # the material provider
+            from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerMaterialProvider as LayerMaterialProvider
+            AtlasMaterialProvider = LayerMaterialProvider('AtlasMaterialProvider')
+            AtlasMaterialProvider.OutputLevel           = TrkDetFlags.ConfigurationOutputLevel()
+            AtlasMaterialProvider.LayerMaterialMapName  = TrkDetFlags.MaterialStoreGateKey()
+        
+            AtlasGeometryProcessors += [ AtlasMaterialProvider ]
+        
+            # the tag names
+            CoolDataBaseFolder = TrkDetFlags.MaterialStoreGateKey()
+            AtlasMaterialTag = TrkDetFlags.MaterialTagBase()+str(TrkDetFlags.MaterialVersion())+TrkDetFlags.MaterialSubVersion()+'_'
+        
+            if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+               print '[ TrackingGeometryCondAlg ] Associating DB folder : ', CoolDataBaseFolder
+        
+            # we need the conditions interface
+            from IOVDbSvc.CondDB import conddb
+            # use a local database
+            if TrkDetFlags.MaterialDatabaseLocal():
+                # specify the local database
+                DataBasePath  = TrkDetFlags.MaterialDatabaseLocalPath() 
+                DataBaseName  = TrkDetFlags.MaterialDatabaseLocalName()
+                MagicTag      = TrkDetFlags.MaterialMagicTag()
+                DataBaseConnection = '<dbConnection>sqlite://X;schema='+DataBasePath+DataBaseName+';dbname=OFLP200</dbConnection>'
+                conddb.blockFolder('/GLOBAL/TrackingGeo/LayerMaterialV2')
+                conddb.addFolderWithTag('',DataBaseConnection+CoolDataBaseFolder,AtlasMaterialTag+MagicTag,force=True)
+                if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+                    print '[ TrackingGeometryCondAlg ] Using Local Database: '+DataBaseConnection        
+                # make sure that the pool files are in the catalog
+            elif TrkDetFlags.SLHC_Geometry() :
+                # set the folder to the SLHC location        
+                CoolDataBaseFolder = '/GLOBAL/TrackingGeo/LayerMaterialITK'
+                ctag = AtlasMaterialTag+TrkDetFlags.MaterialMagicTag()
+                cfoldertag = CoolDataBaseFolder+' <tag>'+ctag+'</tag>'
+                conddb.addFolderSplitMC('GLOBAL',cfoldertag,cfoldertag)
+            else :
+                print '[ TrackingGeometryCondAlg ]     base material tag : ', AtlasMaterialTag
+                cfolder = CoolDataBaseFolder +'<tag>TagInfoMajor/'+AtlasMaterialTag+'/GeoAtlas</tag>'
+                print '[ TrackingGeometryCondAlg ]     translated to COOL: ', cfolder
+                # load the right folders (preparation for calo inclusion)
+                conddb.addFolderSplitMC('GLOBAL',cfolder,cfolder)
+
+        elif TrkDetFlags.MaterialSource() is 'Input' :
+            # the material provider
+            from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__InputLayerMaterialProvider
+            AtlasMaterialProvider = Trk__InputLayerMaterialProvider('AtlasMaterialProvider')
+            AtlasMaterialProvider.OutputLevel           = TrkDetFlags.ConfigurationOutputLevel()
+            AtlasGeometryProcessors += [ AtlasMaterialProvider ]            
+
+        # material validation
+        if TrkDetFlags.MaterialValidation() :
+            # load the material inspector
+            from TrkDetDescrTestTools.TrkDetDescrTestToolsConf import Trk__LayerMaterialInspector
+            AtlasLayerMaterialInspector = Trk__LayerMaterialInspector('AtlasLayerMaterialInspector')
+            AtlasLayerMaterialInspector.OutputLevel = TrkDetFlags.ConfigurationOutputLevel()
+            
+            AtlasGeometryProcessors += [ AtlasLayerMaterialInspector ]
+
+        # call the base class constructor : sets the tools
+        Trk__TrackingGeometryCondAlg.__init__(self,name,\
+                                          GeometryBuilder = AtlasGeometryBuilder,\
+                                          GeometryProcessors = AtlasGeometryProcessors, \
+                                          OutputLevel = TrkDetFlags.ConfigurationOutputLevel())
+        
+        # screen output of the configuration
+        if TrkDetFlags.ConfigurationOutputLevel() < 3 :
+           print self
+           print '* [ GeometryBuilder       ]'
+           print AtlasGeometryBuilder
+           print '* [ Configuration : end   ] ***'+name+'********************************'
+        
+##################################################################################    
+
+# now create the instance
+#AtlasTrackingGeometryCondAlg = ConfiguredTrackingGeometryCondAlg('AtlasTrackingGeometryCondAlg')
+# add it to the ServiceManager
+#from AthenaCommon.AlgSequence import AthSequencer
+#condSeq = AthSequencer("AthCondSeq")
+#condSeq+= AtlasTrackingGeometryCondAlg
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
new file mode 100644
index 00000000000..fe96f02eaf9
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/python/AtlasTrackingGeometryCondAlgConfig.py
@@ -0,0 +1,293 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+Trk__TrackingGeometryCondAlg=CompFactory.Trk__TrackingGeometryCondAlg
+from IOVDbSvc.IOVDbSvcConfig import addFoldersSplitOnline
+from SubDetectorEnvelopes.SubDetectorEnvelopesConfig import getEnvelopeDefSvc
+
+# This file is a placeholder - the entire way we build geometry needs to be rewritten so this is to unblock new configuration developments for the moment.
+# It is based on: https://gitlab.cern.ch/atlas/athena/blob/master/Tracking/TrkDetDescr/TrkDetDescrSvc/python/AtlasTrackingGeometrySvc.py#L112
+
+def _setupCondDB(flags, CoolDataBaseFolder, quiet=True):
+    result=ComponentAccumulator()
+    
+    # the tag names
+    materialTagBase = 'AtlasLayerMat_v'
+    version = 21
+    sub_version = ''
+    
+    AtlasMaterialTag = materialTagBase+str(version)+sub_version+'_'
+    cfolder = CoolDataBaseFolder +'<tag>TagInfoMajor/'+AtlasMaterialTag+'/GeoAtlas</tag>'
+
+    # if not quiet:
+    #   print('[ TrackingGeometrySvc ]     base material tag : ' + AtlasMaterialTag)
+    #   print('[ TrackingGeometrySvc ]     translated to COOL: ' + cfolder)
+
+    # load the right folders
+    result.merge( addFoldersSplitOnline(flags,'GLOBAL',[cfolder],[cfolder],splitMC=True) )
+    return result
+    
+def _getInDetTrackingGeometryBuilder(name, flags,result, envelopeDefinitionSvc, namePrefix='', setLayerAssociation = True, buildTrtStrawLayers = False):
+  # Based on https://gitlab.cern.ch/atlas/athena/blob/master/InnerDetector/InDetDetDescr/InDetTrackingGeometry/python/ConfiguredInDetTrackingGeometryBuilder.py
+  # A lot of comments below are to help people understand differences from the above, in case we need to revert some simplifications I made
+  # i.e. this is far from complete, but is better than what was there before.
+  
+  # beampipe        
+  InDet__BeamPipeBuilder=CompFactory.InDet__BeamPipeBuilderCond
+  beamPipeBuilder = InDet__BeamPipeBuilder(name=namePrefix+'BeamPipeBuilder')
+
+  result.addPublicTool(beamPipeBuilder)
+  layerbuilders = []
+  binnings      = []
+  colors        = []
+
+  # Pixel
+  if flags.Detector.GeometryPixel:
+    InDet__SiLayerBuilder=CompFactory.InDet__SiLayerBuilderCond
+    PixelLayerBuilder = InDet__SiLayerBuilder(name=namePrefix+'PixelLayerBuilder')
+    PixelLayerBuilder.PixelCase            = True
+    PixelLayerBuilder.Identification       = 'Pixel'
+    PixelLayerBuilder.SiDetManagerLocation = 'Pixel'
+    # additional layers - handle with care !
+    PixelLayerBuilder.BarrelAdditionalLayerRadii      = [ 130 ]   # The PST
+    PixelLayerBuilder.BarrelAdditionalLayerType       = [ 0 ]     # -- will shift volume boundary to PST
+    PixelLayerBuilder.EndcapAdditionalLayerPositionsZ = [ -1900. , 1900. ] # DBM
+    PixelLayerBuilder.EndcapAdditionalLayerType       = [  1 , 1 ] # DBM
+    # Pixel barrel specifications
+    # Since we don't have TrkDetFlags, using defaults here.
+    
+    # set the layer association
+    PixelLayerBuilder.SetLayerAssociation  = setLayerAssociation
+
+    # the binning type of the layers   
+    PixelLayerBinning = 2
+    # add it to tool service
+    result.addPublicTool(PixelLayerBuilder)
+    # put them to the caches
+    layerbuilders += [ PixelLayerBuilder ]
+    binnings      += [ PixelLayerBinning ]
+    colors        += [ 3 ]
+
+  if flags.Detector.GeometrySCT:
+    # SCT building
+    InDet__SiLayerBuilder=CompFactory.InDet__SiLayerBuilderCond
+    SCT_LayerBuilder = InDet__SiLayerBuilder(name=namePrefix+'SCT_LayerBuilder')
+    SCT_LayerBuilder.PixelCase                       = False
+    SCT_LayerBuilder.Identification                  = 'SCT'
+    SCT_LayerBuilder.SiDetManagerLocation            = 'SCT'
+    # additionall layers - handle with care !
+    SCT_LayerBuilder.EndcapAdditionalLayerPositionsZ = [ -2850 , 2850 ] 
+    SCT_LayerBuilder.EndcapAdditionalLayerType       = [  0 , 0 ] 
+    # SCT barrel specifications - use defaults
+    # SCT endcap specifications - use defaults           
+    # set the layer association                   
+    SCT_LayerBuilder.SetLayerAssociation             = setLayerAssociation        
+    # the binning type of the layer     
+    SCT_LayerBinning = 2
+    # SCT -> ToolSvc                             
+    result.addPublicTool(SCT_LayerBuilder)
+                       
+    # put them to the caches
+    layerbuilders += [ SCT_LayerBuilder ]
+    binnings      += [ SCT_LayerBinning ]
+    colors        += [ 4 ]
+
+  if flags.Detector.GeometryTRT:                                                      
+    InDet__TRT_LayerBuilder=CompFactory.InDet__TRT_LayerBuilderCond
+    TRT_LayerBuilder = InDet__TRT_LayerBuilder(name=namePrefix+'TRT_LayerBuilder')
+    # TRT barrel specifications - assume defaults
+    # SCT endcap specifications - assume defaults
+                       
+    # set the binning from bi-aequidistant to arbitrary for complex TRT volumes
+    TRT_LayerBinning = 1        
+    if buildTrtStrawLayers:
+       TRT_LayerBinning = 2
+       TRT_LayerBuilder.ModelLayersOnly = False
+    # TRT -> ToolSvc                      
+    result.addPublicTool(TRT_LayerBuilder)
+    
+    # put them to the caches
+    layerbuilders += [ TRT_LayerBuilder ]
+    binnings      += [ TRT_LayerBinning ]
+    colors        += [ 5 ]
+
+  # helpers for the InDetTrackingGeometry Builder : layer array creator
+  Trk__LayerArrayCreator=CompFactory.Trk__LayerArrayCreator
+  InDetLayerArrayCreator = Trk__LayerArrayCreator(name = 'InDetLayerArrayCreator')
+  InDetLayerArrayCreator.EmptyLayerMode           = 2 # deletes empty material layers from arrays
+  # add to ToolSvc
+  result.addPublicTool(InDetLayerArrayCreator)  
+
+  # helpers for the InDetTrackingGeometry Builder : volume array creator
+  Trk__TrackingVolumeArrayCreator=CompFactory.Trk__TrackingVolumeArrayCreator
+  InDetTrackingVolumeArrayCreator                       = Trk__TrackingVolumeArrayCreator(name = 'InDetTrackingVolumeArrayCreator')
+  # add to ToolSvc
+  result.addPublicTool(InDetTrackingVolumeArrayCreator)  
+
+  # helpers for the InDetTrackingGeometry Builder : tracking voluem helper for glueing
+  Trk__TrackingVolumeHelper=CompFactory.Trk__TrackingVolumeHelper
+  InDetTrackingVolumeHelper                             = Trk__TrackingVolumeHelper(name ='InDetTrackingVolumeHelper')
+  # the material bins - assume defaults
+  # add to ToolSvc
+  result.addPublicTool(InDetTrackingVolumeHelper)  
+  
+  # helpers for the InDetTrackingGeometry Builder : cylinder volume creator
+  Trk__CylinderVolumeCreator=CompFactory.Trk__CylinderVolumeCreator
+  InDetCylinderVolumeCreator = Trk__CylinderVolumeCreator(name = 'InDetCylinderVolumeCreator')
+  # give it the layer array creator - assume defaults
+  # specifiy the binning, passive layers, entry layers - assume defaults
+  # add to ToolSvc
+  result.addPublicTool(InDetCylinderVolumeCreator)  
+
+  # the tracking geometry builder
+  InDet__RobustTrackingGeometryBuilder=CompFactory.InDet__RobustTrackingGeometryBuilderCond
+  return InDet__RobustTrackingGeometryBuilder(namePrefix+name,
+                                                BeamPipeBuilder   = beamPipeBuilder,
+                                                LayerBuilders     = layerbuilders,
+                                                LayerBinningType  = binnings,
+                                                ColorCodes        = colors,
+                                                EnvelopeDefinitionSvc = envelopeDefinitionSvc,
+                                                VolumeEnclosureDiscPositions = [ 3000., 3450. ],
+                                                TrackingVolumeCreator     = InDetCylinderVolumeCreator,
+                                                LayerArrayCreator         = InDetLayerArrayCreator)
+
+                                                # FIXME - not sure what to do about the following:
+                                                # BuildBoundaryLayers       = TrkDetFlags.InDetBuildMaterialBoundaries(),
+                                                # ReplaceAllJointBoundaries = TrkDetFlags.InDetBuildJointBoundaries(),
+                                                # OutputLevel               = TrkDetFlags.InDetBuildingOutputLevel(),
+                                                # ExitVolumeName            = TrkDetFlags.InDetContainerName(),
+                                                
+                                                # Probably they should just be dropped, but I leave this comment for the moment so reviewers can have a think as well.
+                                                
+                                                # Barrel Entry layers (in old config) etc were removed in 323990adfce581a635ae1809fd2ecc6a093a704c (!)
+  
+# Replaces https://gitlab.cern.ch/atlas/athena/blob/master/Calorimeter/CaloTrackingGeometry/python/ConfiguredCaloTrackingGeometryBuilder.py
+def _getCaloTrackingGeometryBuilder(name, flags,result, envelopeDefinitionSvc, trackingVolumeHelper, namePrefix=''):
+  # The following replaces LArCalorimeter/LArTrackingGeometry/python/ConfiguredLArVolumeBuilder.py
+  LAr__LArVolumeBuilder=CompFactory.LAr__LArVolumeBuilder
+  lArVolumeBuilder = LAr__LArVolumeBuilder(TrackingVolumeHelper = trackingVolumeHelper,)
+  result.addPublicTool(lArVolumeBuilder)
+  
+  # The following replaces TileCalorimeter/TileTrackingGeometry/python/ConfiguredTileVolumeBuilder.py
+  Tile__TileVolumeBuilder=CompFactory.Tile__TileVolumeBuilder
+  tileVolumeBuilder = Tile__TileVolumeBuilder( TrackingVolumeHelper = trackingVolumeHelper,  )
+  result.addPublicTool(tileVolumeBuilder)
+  
+  Calo__CaloTrackingGeometryBuilder=CompFactory.Calo__CaloTrackingGeometryBuilderCond
+  return Calo__CaloTrackingGeometryBuilder(namePrefix+name, LArVolumeBuilder = lArVolumeBuilder,
+                                                   TileVolumeBuilder = tileVolumeBuilder,
+                                                   TrackingVolumeHelper = trackingVolumeHelper,
+                                                   EnvelopeDefinitionSvc = envelopeDefinitionSvc,
+                                                   )
+
+# Originally this function would use was TrkDetFlags.MaterialSource() and TrkDetFlags.MaterialValidation(). For new configuration, (temporarily?) pass as parameters.
+# https://gitlab.cern.ch/atlas/athena/blob/master/Tracking/TrkDetDescr/TrkDetDescrSvc/python/AtlasTrackingGeometrySvc.py#L112
+def TrackingGeometryCondAlgCfg( flags , name = 'AtlasTrackingGeometryCondAlg', doMaterialValidation=False ) :
+    """
+    Sets up the Tracking Geometry Conditions Algorithm
+    """
+    result = ComponentAccumulator()
+    atlas_tracking_geometry_name = 'AtlasTrackingGeometry'
+    Trk__GeometryBuilder=CompFactory.Trk__GeometryBuilderCond
+    atlas_geometry_builder = Trk__GeometryBuilder(name = 'AtlasGeometryBuilder')
+
+    atlas_env_def_service = getEnvelopeDefSvc()
+    result.addService(atlas_env_def_service)  
+
+    # Depending on the job configuration, setup the various detector builders, and add to atlas_geometry_builder
+    if flags.Detector.GeometryID:
+      # TODO Not sure how to handle TrkDetFlags, specifically ISF_FatrasCustomGeometry, XMLFastCustomGeometry, SLHC_Geometry
+      # So, here we only setup the default InDet geometry builder!
+      inDetTrackingGeometryBuilder = _getInDetTrackingGeometryBuilder(name ='InDetTrackingGeometryBuilder', flags=flags, result=result, envelopeDefinitionSvc=atlas_env_def_service)
+      result.addPublicTool(inDetTrackingGeometryBuilder)
+      
+      atlas_geometry_builder.InDetTrackingGeometryBuilder = inDetTrackingGeometryBuilder
+      
+    if flags.Detector.GeometryCalo:
+      Trk__CylinderVolumeCreator=CompFactory.Trk__CylinderVolumeCreator
+      caloVolumeCreator = Trk__CylinderVolumeCreator("CaloVolumeCreator")
+      result.addPublicTool(caloVolumeCreator)
+
+      Trk__TrackingVolumeHelper=CompFactory.Trk__TrackingVolumeHelper
+      trackingVolumeHelper = Trk__TrackingVolumeHelper(name='TrackingVolumeHelper')
+      result.addPublicTool(trackingVolumeHelper)
+
+      caloTrackingGeometryBuilder = _getCaloTrackingGeometryBuilder(name ='CaloTrackingGeometryBuilder', flags=flags, result=result, envelopeDefinitionSvc=atlas_env_def_service, trackingVolumeHelper=trackingVolumeHelper)
+      result.addPublicTool(caloTrackingGeometryBuilder)
+      atlas_geometry_builder.CaloTrackingGeometryBuilder = caloTrackingGeometryBuilder
+
+    if flags.Detector.GeometryMuon:
+      # Copied from from MuonTrackingGeometry.ConfiguredMuonTrackingGeometry import MuonTrackingGeometryBuilder
+      Muon__MuonStationTypeBuilder=CompFactory.Muon__MuonStationTypeBuilder
+      muonStationTypeBuilder= Muon__MuonStationTypeBuilder(name = 'MuonStationTypeBuilder')
+      result.addPublicTool(muonStationTypeBuilder)
+    
+      Muon__MuonStationBuilder=CompFactory.Muon__MuonStationBuilder
+      muonStationBuilder= Muon__MuonStationBuilder(name = 'MuonStationBuilder')
+      muonStationBuilder.StationTypeBuilder = muonStationTypeBuilder
+      result.addPublicTool(muonStationBuilder)
+
+      Muon__MuonInertMaterialBuilder=CompFactory.Muon__MuonInertMaterialBuilder
+      muonInertMaterialBuilder= Muon__MuonInertMaterialBuilder(name = 'MuonInertMaterialBuilder')
+      result.addPublicTool(muonInertMaterialBuilder)
+
+      Muon__MuonTrackingGeometryBuilder=CompFactory.Muon__MuonTrackingGeometryBuilderCond
+      muonTrackingGeometryBuilder= Muon__MuonTrackingGeometryBuilder(name = 'MuonTrackingGeometryBuilder', EnvelopeDefinitionSvc=atlas_env_def_service)
+      result.addPublicTool(muonTrackingGeometryBuilder)
+    
+      atlas_geometry_builder.MuonTrackingGeometryBuilder = muonTrackingGeometryBuilder
+    
+    # Now set up processors
+    atlas_geometry_processors=[]
+    
+    if flags.TrackingGeometry.MaterialSource == 'COOL':
+       CoolDataBaseFolder = '/GLOBAL/TrackingGeo/LayerMaterialV2' # Was from TrkDetFlags.MaterialStoreGateKey()
+       # the material provider
+       Trk__LayerMaterialProvider=CompFactory.Trk__LayerMaterialProvider
+       atlasMaterialProvider = Trk__LayerMaterialProvider('AtlasMaterialProvider', LayerMaterialMapName=CoolDataBaseFolder)
+       atlas_geometry_processors += [ atlasMaterialProvider ]
+
+       # Setup DBs
+       result.merge(_setupCondDB(flags, CoolDataBaseFolder))
+    elif  flags.TrackingGeometry.MaterialSource == 'Input':
+      Trk__InputLayerMaterialProvider=CompFactory.Trk__InputLayerMaterialProvider
+      atlasMaterialProvider = Trk__InputLayerMaterialProvider('AtlasMaterialProvider')
+      atlas_geometry_processors += [ atlasMaterialProvider ]
+      
+    if doMaterialValidation:
+      Trk__LayerMaterialInspector=CompFactory.Trk__LayerMaterialInspector
+      atlasLayerMaterialInspector = Trk__LayerMaterialInspector('AtlasLayerMaterialInspector')
+      atlas_geometry_processors += [ atlasLayerMaterialInspector ]
+
+    condAlg = Trk__TrackingGeometryCondAlg( name, GeometryBuilder = atlas_geometry_builder,
+                                    TrackingGeometryWriteKey = atlas_tracking_geometry_name,
+                                    GeometryProcessors = atlas_geometry_processors, 
+                                    BuildGeometryFromTagInfo = True)
+    result.addCondAlgo(condAlg, primary = True)
+
+    return result
+        
+if __name__ == '__main__':
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior=1
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+    from AthenaConfiguration.TestDefaults import defaultTestFiles
+
+    ConfigFlags.Input.Files = defaultTestFiles.RAW
+    ConfigFlags.Detector.GeometryPixel = True     
+    ConfigFlags.Detector.GeometrySCT   = True 
+    ConfigFlags.Detector.GeometryTRT   = True 
+    ConfigFlags.Detector.GeometryLAr   = True     
+    ConfigFlags.Detector.GeometryTile  = True     
+    ConfigFlags.Detector.GeometryMDT   = True 
+    ConfigFlags.Detector.GeometryTGC   = True
+    ConfigFlags.Detector.GeometryCSC   = True     
+    ConfigFlags.Detector.GeometryRPC   = True 
+    ConfigFlags.lock()
+
+    acc = TrackingGeometryCondAlgCfg(ConfigFlags )
+
+    f=open('TrackingGeometryCondAlgCfg.pkl','wb')
+    acc.store(f)
+    f.close()
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
new file mode 100644
index 00000000000..572bfdb7c6b
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
@@ -0,0 +1,71 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+// Trk includes
+#include "TrkGeometry/TrackingGeometry.h"
+#include "AthenaKernel/IOVSvcDefs.h"
+
+#include "TrackingGeometryCondAlg/TrackingGeometryCondAlg.h"
+
+
+Trk::TrackingGeometryCondAlg::TrackingGeometryCondAlg(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthReentrantAlgorithm(name, pSvcLocator),
+    m_geometryProcessors(this) 
+{
+  declareProperty("GeometryBuilder", m_trackingGeometryBuilder);
+  declareProperty("GeometryProcessors", m_geometryProcessors);
+}
+
+StatusCode Trk::TrackingGeometryCondAlg::initialize()
+{
+  ATH_MSG_DEBUG("initialize " << name());
+
+  // Write Handle
+  ATH_CHECK(m_trackingGeometryWriteKey.initialize());
+  // CondSvc
+  ATH_CHECK(m_condSvc.retrieve());
+  // Register write handle
+  ATH_CHECK(m_condSvc->regHandle(this, m_trackingGeometryWriteKey));
+  // Retrieve tools
+  ATH_CHECK(m_trackingGeometryBuilder.retrieve());
+  if (m_geometryProcessors.retrieve().isFailure()){
+    ATH_MSG_FATAL( "Could not retrieve " << m_geometryProcessors );
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode Trk::TrackingGeometryCondAlg::execute(const EventContext& ctx) const{
+  //Set up write handle
+  SG::WriteCondHandle<Trk::TrackingGeometry> writeHandle{m_trackingGeometryWriteKey, ctx};
+
+
+  if (writeHandle.isValid()) {
+    ATH_MSG_DEBUG("Found valid write handle");
+    return StatusCode::SUCCESS;
+  }
+
+  //Create dummy IOV range covering 0 - inf
+  EventIDRange range;
+
+  std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometryPair = m_trackingGeometryBuilder->trackingGeometry(ctx, std::pair<EventIDRange, const Trk::TrackingVolume*>(range, nullptr));
+  // cast constness away for StoreGate
+  Trk::TrackingGeometry* trackingGeometry = const_cast<Trk::TrackingGeometry*>(trackingGeometryPair.second);
+
+  // loop over the recursive geometry processors
+  auto gpIter  = m_geometryProcessors.begin();
+  auto gpIterE = m_geometryProcessors.end();
+  for ( ; gpIter != gpIterE; ++ gpIter ){
+      if ( (*gpIter)->process(*trackingGeometry).isFailure() ){
+          ATH_MSG_FATAL("Processing of TrackingGeometry did not succeed. Abort." );
+          return StatusCode::FAILURE;
+      } else {
+          ATH_MSG_VERBOSE("Successfully processed the TrackingGeometry with " << (*gpIter) );
+      }
+  }
+  ATH_CHECK(writeHandle.record(trackingGeometryPair.first,trackingGeometry));
+  return StatusCode::SUCCESS;
+}
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/src/components/TrackingGeometryCondAlg_entries.cxx b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/components/TrackingGeometryCondAlg_entries.cxx
new file mode 100644
index 00000000000..cf3e2c0fb66
--- /dev/null
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/components/TrackingGeometryCondAlg_entries.cxx
@@ -0,0 +1,3 @@
+#include "TrackingGeometryCondAlg/TrackingGeometryCondAlg.h"
+
+DECLARE_COMPONENT( Trk::TrackingGeometryCondAlg )
diff --git a/Tracking/TrkConditions/TrkCondTest/CMakeLists.txt b/Tracking/TrkConditions/TrkCondTest/CMakeLists.txt
new file mode 100644
index 00000000000..7540c13fa3d
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/CMakeLists.txt
@@ -0,0 +1,40 @@
+################################################################################
+# Package: TrkCondTest
+################################################################################
+
+# Declare the package name:
+atlas_subdir( TrkCondTest )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs(
+   PUBLIC
+   Control/AthenaBaseComps
+   Control/AthenaKernel
+   GaudiKernel
+   Tracking/TrkDetDescr/TrkDetDescrInterfaces
+   Tracking/TrkDetDescr/TrkDetDescrUtils
+   Tracking/TrkDetDescr/TrkGeometry
+   InnerDetector/InDetDetDescr/InDetReadoutGeometry
+   PRIVATE
+    )
+
+find_package( Eigen )
+
+# Component(s) in the package:
+
+atlas_add_component( TrackingGeometryCondAlgTest
+   TrkCondTest/*.h src/*.cxx src/components/*.cxx
+   INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}
+   LINK_LIBRARIES ${EIGEN_LIBRARIES} 
+   AthenaBaseComps
+   AthenaKernel
+   GaudiKernel 
+   TrkDetDescrInterfaces
+   TrkDetDescrUtils
+   TrkGeometry
+   InDetReadoutGeometry
+    )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+atlas_install_joboptions( share/*.py )
diff --git a/Tracking/TrkConditions/TrkCondTest/TrkCondTest/TrackingGeometryCondAlgTest.h b/Tracking/TrkConditions/TrkCondTest/TrkCondTest/TrackingGeometryCondAlgTest.h
new file mode 100644
index 00000000000..8f3c5a1b562
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/TrkCondTest/TrackingGeometryCondAlgTest.h
@@ -0,0 +1,40 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRACKINGGEOMETRYCONDALG_H
+#define TRACKINGGEOMETRYCONDALG_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "PersistentDataModel/AthenaAttributeList.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkDetDescrInterfaces/IGeometryBuilder.h"
+#include "TrkDetDescrInterfaces/IGeometryProcessor.h"
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaKernel/CLASS_DEF.h"
+
+namespace Trk{
+class TrackingGeometryCondAlgTest : public AthReentrantAlgorithm
+{
+public:
+    TrackingGeometryCondAlgTest(const std::string& name, ISvcLocator* pSvcLocator);
+    virtual ~TrackingGeometryCondAlgTest() override = default;
+
+    virtual StatusCode initialize() override;
+    virtual StatusCode execute(const EventContext& ctx)const override;
+    virtual StatusCode finalize() override {return StatusCode::SUCCESS;}
+
+private:
+
+  /// Input conditions object.
+  SG::ReadCondHandleKey<TrackingGeometry> m_trackingGeometryReadKey{this, "TrackingGeometryReadKey", "AlignedTrackingGeometry", "Key of input TrackingGeometry"};
+  mutable std::vector<Amg::Vector3D> m_worldVolumeCenterCollection;
+};
+}
+#endif //TRACKINGGEOMETRYCONDALG_H
diff --git a/Tracking/TrkConditions/TrkCondTest/share/TrackingGeometryTest_jobOptions.py b/Tracking/TrkConditions/TrkCondTest/share/TrackingGeometryTest_jobOptions.py
new file mode 100644
index 00000000000..7ac5625c865
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/share/TrackingGeometryTest_jobOptions.py
@@ -0,0 +1,105 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+###############################################################
+#
+# Job options 
+#
+#==============================================================
+
+#--------------------------------------------------------------
+# ATLAS default Application Configuration options
+#--------------------------------------------------------------
+
+# Use McEventSelector so we can run with AthenaMP
+
+#--------------------------------------------------------------
+# Private Application Configuration options
+#--------------------------------------------------------------
+
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+athenaCommonFlags.FilesInput = ["/afs/cern.ch/work/r/rlangenb/public/data18_13TeV.00363979.physics_Main.daq.ESD/100evts10lumiblocks.ESD.root"]
+
+import AthenaPoolCnvSvc.ReadAthenaPool
+
+# build GeoModel
+import AthenaPython.ConfigLib as apcl
+cfg = apcl.AutoCfg(name = 'TrackingGeometryTest', input_files=athenaCommonFlags.FilesInput())
+
+cfg.configure_job()
+
+from AthenaCommon.GlobalFlags import globalflags
+if len(globalflags.ConditionsTag())!=0:
+  from IOVDbSvc.CondDB import conddb
+  conddb.setGlobalTag(globalflags.ConditionsTag())
+from AtlasGeoModel.InDetGMJobProperties import InDetGeometryFlags
+InDetGeometryFlags.useDynamicAlignFolders=True
+
+import MagFieldServices.SetupField
+
+# the global detflags
+from AthenaCommon.DetFlags import DetFlags
+DetFlags.ID_setOn()
+DetFlags.Calo_setOn()
+DetFlags.Muon_setOn()
+DetFlags.TRT_setOn()
+
+# Full job is a list of algorithms
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+from AtlasGeoModel import SetGeometryVersion 
+from AtlasGeoModel import GeoModelInit 
+
+# switch the material loading off
+from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+TrkDetFlags.MaterialSource           = 'None'
+TrkDetFlags.MaterialVersion          = 16
+TrkDetFlags.ConfigurationOutputLevel = VERBOSE
+
+
+TrkDetFlags.PixelBuildingOutputLevel     = VERBOSE
+TrkDetFlags.SCT_BuildingOutputLevel      = VERBOSE
+TrkDetFlags.TRT_BuildingOutputLevel      = VERBOSE
+TrkDetFlags.InDetBuildingOutputLevel     = VERBOSE
+TrkDetFlags.ConfigurationOutputLevel     = VERBOSE
+
+
+# load the tracking geometry cond alg
+from TrackingGeometryCondAlg.AtlasTrackingGeometryCondAlg import ConfiguredTrackingGeometryCondAlg
+TrkGeoCondAlg = ConfiguredTrackingGeometryCondAlg('AtlasTrackingGeometryCondAlg')
+from AthenaCommon.AlgSequence import AthSequencer
+condSeq = AthSequencer("AthCondSeq")
+condSeq+= TrkGeoCondAlg
+
+from TrkCondTest.TrackingGeometryCondAlgTestConf import Trk__TrackingGeometryCondAlgTest
+TrkGeomCondAlgTest = Trk__TrackingGeometryCondAlgTest(name = "TrkGeomTest")
+job += TrkGeomCondAlgTest
+
+#--------------------------------------------------------------
+# Set output level threshold (DEBUG, INFO, WARNING, ERROR, FATAL)
+#--------------------------------------------------------------
+
+# Output level for HelloAlg only (note name: instance, not type)
+#TrackingGeometryTest = INFO
+
+# You can set the global output level on the message svc (not
+# recommended) or by using the -l athena CLI parameter
+
+#--------------------------------------------------------------
+# Event related parameters
+#--------------------------------------------------------------
+
+theApp.EvtMax = 22
+
+from AthenaCommon.AppMgr import ServiceMgr
+# output level
+ServiceMgr.MessageSvc.OutputLevel  = INFO
+# increase the number of letter reserved to the alg/tool name from 18 to 30
+ServiceMgr.MessageSvc.Format       = "% F%50W%S%7W%R%T %0W%M"
+# to change the default limit on number of message
+ServiceMgr.MessageSvc.defaultLimit = 9999999  # all messages
+
+#==============================================================
+#
+# End of job options file
+#
+###############################################################
diff --git a/Tracking/TrkConditions/TrkCondTest/src/TrackingGeometryCondAlgTest.cxx b/Tracking/TrkConditions/TrkCondTest/src/TrackingGeometryCondAlgTest.cxx
new file mode 100644
index 00000000000..364faa70720
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/src/TrackingGeometryCondAlgTest.cxx
@@ -0,0 +1,47 @@
+/*
+ *   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Trk includes
+#include "AthenaKernel/IOVSvcDefs.h"
+
+#include "TrkCondTest/TrackingGeometryCondAlgTest.h"
+
+
+Trk::TrackingGeometryCondAlgTest::TrackingGeometryCondAlgTest(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthReentrantAlgorithm(name, pSvcLocator)
+{
+}
+
+StatusCode Trk::TrackingGeometryCondAlgTest::initialize()
+{
+  ATH_MSG_DEBUG("initialize " << name());
+
+  // Read Handle Key
+  ATH_CHECK(m_trackingGeometryReadKey.initialize());
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode Trk::TrackingGeometryCondAlgTest::execute(const EventContext& ctx) const {
+  
+  //Set up read handle
+  SG::ReadCondHandle<Trk::TrackingGeometry> readHandle{m_trackingGeometryReadKey, ctx};
+  if (!readHandle.isValid() || *readHandle == nullptr) {
+    ATH_MSG_WARNING(m_trackingGeometryReadKey.fullKey() << " is not available.");
+    return StatusCode::FAILURE;
+  }
+  const Trk::TrackingGeometry* trkGeom = *readHandle;
+  ATH_MSG_INFO( "eventID: "  << ctx.eventID());
+
+  Amg::Vector3D center = trkGeom->highestTrackingVolume()->center();
+  ATH_MSG_INFO("Center coordinates of highest tracking volume");
+  ATH_MSG_INFO(center);
+  if(m_worldVolumeCenterCollection.size()>=1 && m_worldVolumeCenterCollection.back() != center){
+    ATH_MSG_INFO("hooray, we have moved the world");
+  }
+  m_worldVolumeCenterCollection.push_back(center);
+
+  ATH_MSG_INFO("TrackingGeometry retrieved");
+  return StatusCode::SUCCESS;
+}
diff --git a/Tracking/TrkConditions/TrkCondTest/src/components/TrkCondTest_entries.cxx b/Tracking/TrkConditions/TrkCondTest/src/components/TrkCondTest_entries.cxx
new file mode 100644
index 00000000000..9d545d52446
--- /dev/null
+++ b/Tracking/TrkConditions/TrkCondTest/src/components/TrkCondTest_entries.cxx
@@ -0,0 +1,3 @@
+#include "TrkCondTest/TrackingGeometryCondAlgTest.h"
+
+DECLARE_COMPONENT( Trk::TrackingGeometryCondAlgTest )
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryBuilderCond.h
new file mode 100755
index 00000000000..c0a3e1f20b2
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryBuilderCond.h
@@ -0,0 +1,69 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// IGeometryBuilderCond.hm (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRINTERFACES_IGEOMETRYBUILDERCOND_H
+#define TRKDETDESCRINTERFACES_IGEOMETRYBUILDERCOND_H
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+// Trk - enum
+#include "TrkDetDescrUtils/GeometrySignature.h"
+// STL
+#include <vector>
+
+class EventIDRange;
+namespace Trk {
+
+  class TrackingGeometry;
+  class TrackingVolume;
+
+  /** Interface ID for IGeometryBuilderConds*/  
+  static const InterfaceID IID_IGeometryBuilderCond("IGeometryBuilderCond", 1, 0);
+  
+  /** @class IGeometryBuilderCond
+    
+    Interface class IGeometryBuilderCond,
+    the GeometryBuilder inherits from this one.
+    
+    VolumeBounds can be given optionally to force a specific size/shape/boundary
+
+    This interface class implements protected glue and surface
+    exchange methods, that require friend rights to the classes
+    
+    @author Andreas.Salzburger@cern.ch
+    */
+  class IGeometryBuilderCond : virtual public IAlgTool {
+    
+    public:
+      /**Virtual destructor*/
+      virtual ~IGeometryBuilderCond(){}
+      
+      /** AlgTool and IAlgTool interface methods */
+      static const InterfaceID& interfaceID() { return IID_IGeometryBuilderCond; }
+
+      /** TrackingGeometry Interface methode -
+       *   - Event context
+       *   - pair with EventIDRange and corresponding TrackingVolume, from which
+       *     we retrieve the volume to wrap the TrackingGeometry around. If
+       *     TrackingGeometry is nullptr, range should be infinite (so
+       *     intersecting with another range has no effect)
+       */
+      virtual std::pair<EventIDRange, const TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const = 0;
+
+      /** The unique signature */
+      virtual GeometrySignature geometrySignature() const = 0;
+      
+  };
+
+} // end of namespace
+
+
+#endif // TRKDETDESCRINTERFACES_IGEOMETRYBUILDERCOND_H
+
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h
index 2e79fed6792..01b6bd5d76f 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/IGeometryProcessor.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -40,16 +40,16 @@ namespace Trk {
       static const InterfaceID& interfaceID() { return IID_IGeometryProcessor; }
 
       /** Processor Action to work on TrackingGeometry& tgeo */
-      virtual StatusCode process(const TrackingGeometry& tvol) = 0;
+      virtual StatusCode process(const TrackingGeometry& tvol) const = 0;
 
       /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-      virtual StatusCode process(const TrackingVolume& tvol, size_t level=0) = 0;
+      virtual StatusCode process(const TrackingVolume& tvol, size_t level=0) const = 0;
      
       /** Processor Action to work on Layers */
-      virtual StatusCode process(const Layer& lay, size_t level=0) = 0;
+      virtual StatusCode process(const Layer& lay, size_t level=0) const = 0;
 
       /** Processor Action to work on Surfaces */
-      virtual StatusCode process(const Surface& surf, size_t level=0) = 0;
+      virtual StatusCode process(const Surface& surf, size_t level=0) const = 0;
 
   };
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerBuilderCond.h
new file mode 100755
index 00000000000..c929d43bdb8
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerBuilderCond.h
@@ -0,0 +1,73 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// ILayerBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRINTERFACES_ILAYERBUILDERCOND_H
+#define TRKDETDESCRINTERFACES_ILAYERBUILDERCOND_H
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+#include "TrkSurfaces/Surface.h"
+// STL
+#include <vector>
+#include <string>
+
+namespace Trk {
+
+  class CylinderLayer;
+  class DiscLayer;
+  class PlaneLayer;
+  class Layer;
+
+  /** Interface ID for ILayerBuilderCond*/  
+  static const InterfaceID IID_ILayerBuilderCond("ILayerBuilderCond", 1, 0);
+  
+  /** @class ILayerBuilderCond
+    Interface class ILayerBuilderConds
+    It inherits from IAlgTool. The actual implementation of the AlgTool depends on the SubDetector,
+    more detailed information should be found there.
+    
+    @author Andreas.Salzburger@cern.ch
+    */
+  class ILayerBuilderCond : virtual public IAlgTool {
+    
+    public:
+      /**Virtual destructor*/
+      virtual ~ILayerBuilderCond(){}
+      
+      /** AlgTool and IAlgTool interface methods */
+      static const InterfaceID& interfaceID() { return IID_ILayerBuilderCond; }
+
+      /** LayerBuilder interface method - returning Barrel-like layers */
+      virtual std::pair<EventIDRange, const std::vector< const CylinderLayer* >*> cylindricalLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning Endcap-like layers */
+      virtual std::pair<EventIDRange, const std::vector< const DiscLayer* >*>     discLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning Planar-like layers */
+      virtual std::pair<EventIDRange, const std::vector< const PlaneLayer* >*>    planarLayers(const EventContext& ctx) const = 0;
+
+      /** Name identification */
+      virtual const std::string& identification() const = 0;
+      
+      /** Validation Action:
+          Can be implemented optionally, outside access to internal validation steps */
+      virtual void validationAction() const {}
+
+    protected:
+      /** Protected method to register the Layer to the Surface */
+      void associateLayer(const Layer& lay, const Surface& sf) const { sf.associateLayer(lay); }
+       
+  };
+
+
+} // end of namespace
+
+
+#endif // TRKDETDESCRINTERFACES_ILAYERBUILDERCOND_H
+
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerProviderCond.h b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerProviderCond.h
new file mode 100644
index 00000000000..da5049f8b22
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrInterfaces/TrkDetDescrInterfaces/ILayerProviderCond.h
@@ -0,0 +1,62 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// ILayerProviderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRINTERFACES_ILAYERPROVIDERCOND_H
+#define TRKDETDESCRINTERFACES_ILAYERPROVIDERCOND_H
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventIDRange.h"
+#include "GaudiKernel/EventContext.h"
+// STL
+#include <vector>
+#include <string>
+
+namespace Trk {
+
+  class Layer;
+
+  /** Interface ID for ILayerProviderConds*/  
+  static const InterfaceID IID_ILayerProviderCond("ILayerProviderCond", 1, 0);
+  
+  /** @class ILayerProviderCond
+  
+    Interface class ILayerProviderConds
+    it feeds into the StagedGeometryBuilder
+    
+    @author Andreas.Salzburger@cern.ch
+    */
+  class ILayerProviderCond : virtual public IAlgTool {
+    
+    public:
+      /**Virtual destructor*/
+      virtual ~ILayerProviderCond(){}
+      
+      /** AlgTool and IAlgTool interface methods */
+      static const InterfaceID& interfaceID() { return IID_ILayerProviderCond; }
+
+      /** LayerBuilder interface method - returning the layers at negative side */
+      virtual std::pair<EventIDRange, const std::vector< const Layer* > > negativeLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning the central layers */
+      virtual std::pair<EventIDRange, const std::vector< const Layer* > > centralLayers(const EventContext& ctx) const = 0; 
+      
+      /** LayerBuilder interface method - returning the layers at negative side */
+      virtual std::pair<EventIDRange, const std::vector< const Layer* > > positiveLayers(const EventContext& ctx) const = 0; 
+
+      /** Name identification */
+      virtual const std::string& identification() const = 0;
+             
+  };
+
+} // end of namespace
+
+
+#endif // TRKDETDESCRINTERFACES_ILAYERPROVIDER_H
+
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h
index 831cec3dff9..1ab2e4ecd3f 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryAsciiDumper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -52,15 +52,15 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
-        std::ofstream               m_outputFile;
+        mutable std::ofstream       m_outputFile;
         std::string                 m_outputFileName;  //!< where the tree is written to  
         int                         m_outputPrecision;
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h
index 9a02125c26a..5a70fc1f15c 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryJsonDumper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -52,18 +52,18 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
-        std::ofstream               m_outputFile;
+        mutable std::ofstream       m_outputFile;
         std::string                 m_outputFileName;  //!< where the tree is written to  
         int                         m_outputPrecision;
-        bool                        m_firstLayerWritten;
+        mutable bool                m_firstLayerWritten;
 
     };
 }
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h
index a7fc2e844c7..58cf1359645 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/GeometryTTreeDumper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -45,15 +45,15 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
-        TTree*              m_currentTree; //!< the tree for the currently processed tracking Volume
+        mutable TTree*      m_currentTree; //!< the tree for the currently processed tracking Volume
         std::string         m_treeFolder;  //!< where the tree is written to  
 
     };
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h
index 4a16e07bef8..d3f5d98987b 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/LayerMaterialInspector.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -43,14 +43,14 @@ namespace Trk {
       private:
 
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0);
+        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode processNode(const Layer& lay, size_t level = 0);
+        virtual StatusCode processNode(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode processNode(const Surface& surf, size_t level = 0);
-      
+        virtual StatusCode processNode(const Surface& surf, size_t level = 0) const;
+     
         std::string m_treeFolder;
         
     };
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h
index b5885f61cb7..e6b085000bc 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/RecursiveGeometryProcessor.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -49,28 +49,28 @@ namespace Trk {
         StatusCode finalize();
        
         /** Processor Action to work on TrackingGeometry& tgeo */
-        virtual StatusCode process(const TrackingGeometry& tgeo);
+        virtual StatusCode process(const TrackingGeometry& tgeo) const;
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0);   
+        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode process(const Layer& lay, size_t level = 0);
+        virtual StatusCode process(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode process(const Surface& surf, size_t level = 0);
+        virtual StatusCode process(const Surface& surf, size_t level = 0) const;
      
       protected:
         /** Dedicated action for the different processors */
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0);
+        virtual StatusCode processNode(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode processNode(const Layer& lay, size_t level = 0);
+        virtual StatusCode processNode(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode processNode(const Surface& surf, size_t level = 0);
+        virtual StatusCode processNode(const Surface& surf, size_t level = 0) const;
          
 
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h
index c3ff2245c76..e23b641efb4 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/TrkDetDescrTestTools/TrackingVolumeDisplayer.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -49,13 +49,13 @@ namespace Trk {
       private:
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const TrackingVolume& tvol, size_t level=0);
+        StatusCode processNode(const TrackingVolume& tvol, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Layer& lay, size_t level=0);
+        StatusCode processNode(const Layer& lay, size_t level=0) const;
 
         /** Current implementation: write root visualization to file stream */
-        StatusCode processNode(const Surface&, size_t level=0);
+        StatusCode processNode(const Surface&, size_t level=0) const;
 
         void openFile(std::ofstream& output, const std::string& filename) const;  //!< File handling: open + write header
         void closeFile(std::ofstream& output) const;                              //!< File handling: write footer + close
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx
index afb550433ab..723f5a871d7 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryAsciiDumper.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -57,7 +57,7 @@ StatusCode Trk::GeometryAsciiDumper::finalize()
 
 
 
-StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::TrackingVolume& tvol, size_t level)
+StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::TrackingVolume& tvol, size_t level) const
 {
 
    ATH_MSG_VERBOSE("Dumping information for TrackingVolume.");
@@ -95,7 +95,7 @@ StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::TrackingVolume& tvol
 }
 
 
-StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Layer& lay, size_t level)
+StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Layer& lay, size_t level) const
 {
     
     ATH_MSG_VERBOSE("Dumping information for Layer.");
@@ -121,7 +121,7 @@ StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Layer& lay, size_t l
 }
 
 
-StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Surface& sf, size_t level)
+StatusCode Trk::GeometryAsciiDumper::processNode(const Trk::Surface& sf, size_t level) const
 {
     ATH_MSG_VERBOSE("Dumping information for Surfaces.");
     std::stringstream levelBuffer;
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx
index 264061da392..43d78d6609e 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryJsonDumper.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -59,13 +59,13 @@ StatusCode Trk::GeometryJsonDumper::finalize()
 
 
 
-StatusCode Trk::GeometryJsonDumper::processNode(const Trk::TrackingVolume& /*tvol*/, size_t /*level*/)
+StatusCode Trk::GeometryJsonDumper::processNode(const Trk::TrackingVolume& /*tvol*/, size_t /*level*/) const
 {
    return StatusCode::SUCCESS;
 }
 
 
-StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Layer& lay, size_t /*level*/)
+StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Layer& lay, size_t /*level*/) const
 {
     
     ATH_MSG_VERBOSE("Dumping information for Layer with index " << lay.layerIndex().value());
@@ -112,7 +112,7 @@ StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Layer& lay, size_t /*
 }
 
 
-StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Surface& /*sf*/, size_t /*level*/)
+StatusCode Trk::GeometryJsonDumper::processNode(const Trk::Surface& /*sf*/, size_t /*level*/) const
 {
     ATH_MSG_VERBOSE("Dumping information for Surfaces.");
     
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx
index 361f41fd997..235a3b74adb 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/GeometryTTreeDumper.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -33,7 +33,7 @@ Trk::GeometryTTreeDumper::~GeometryTTreeDumper()
 {}
 
 
-StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::TrackingVolume& tvol, size_t)
+StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::TrackingVolume& tvol, size_t) const
 {
    ATH_MSG_VERBOSE("Dumping information for TrackingVolume.");
    // clean up from the previous event
@@ -73,7 +73,7 @@ StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::TrackingVolume& tvol
 }
 
 
-StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Layer& lay, size_t)
+StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Layer& lay, size_t) const
 {
     
     ATH_MSG_VERBOSE("Dumping information for Layer.");
@@ -90,7 +90,7 @@ StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Layer& lay, size_t)
 }
 
 
-StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Surface& sf, size_t)
+StatusCode Trk::GeometryTTreeDumper::processNode(const Trk::Surface& sf, size_t) const
 {
     ATH_MSG_VERBOSE("Dumping information for Surfaces.");
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx
index 960ee66c1b9..a3efa72db21 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/LayerMaterialInspector.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -33,12 +33,12 @@ Trk::LayerMaterialInspector::LayerMaterialInspector(const std::string& t, const
 Trk::LayerMaterialInspector::~LayerMaterialInspector()
 {}
 
-StatusCode Trk::LayerMaterialInspector::processNode(const Trk::TrackingVolume& , size_t)
+StatusCode Trk::LayerMaterialInspector::processNode(const Trk::TrackingVolume& , size_t) const
 {
   return StatusCode::SUCCESS;
 }  
 
-StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Layer& lay, size_t)
+StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Layer& lay, size_t) const
 {
     
     const Trk::TrackingVolume* tvol = lay.enclosingTrackingVolume();
@@ -152,7 +152,7 @@ StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Layer& lay, size_
     return StatusCode::SUCCESS;    
 }
 
-StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Surface& , size_t)
+StatusCode Trk::LayerMaterialInspector::processNode(const Trk::Surface& , size_t) const
 {
   return StatusCode::SUCCESS;
 }  
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx
index 841be93c2bb..1fe9d38a6c1 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/RecursiveGeometryProcessor.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -43,7 +43,7 @@ StatusCode Trk::RecursiveGeometryProcessor::finalize()
 }
 
 // Processor Action to work on TrackingGeometry 
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingGeometry& tgeo) const {
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -58,7 +58,7 @@ StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingGeometry&
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingVolume& tvol, size_t level) const {
   
   std::stringstream displayBuffer;
   for (size_t il = 0; il < level; ++il) displayBuffer << " ";
@@ -121,7 +121,7 @@ StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::TrackingVolume& t
 }
 
 // Processor Action to work on Layers 
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Layer& lay, size_t level) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Layer& lay, size_t level) const {
 
     std::stringstream displayBuffer;
     for (size_t il = 0; il < level; ++il) displayBuffer << " ";
@@ -155,20 +155,20 @@ StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Layer& lay, size_
 }
 
 // Processor Action to work on Surfaces 
-StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Surface& surf, size_t level) {
+StatusCode Trk::RecursiveGeometryProcessor::process(const Trk::Surface& surf, size_t level) const {
     return processNode(surf, level);
 }
 
 // Processor Action to work on TrackingVolume - to be overloaded 
-StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::TrackingVolume&, size_t ) {
+StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::TrackingVolume&, size_t ) const {
     return StatusCode::SUCCESS;
 }
 
 // Processor Action to work on Layers - to be overloaded 
-StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Layer&, size_t ) {
+StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Layer&, size_t ) const {
     return StatusCode::SUCCESS;
 }
 // Processor Action to work on Surfaces - to be overloaded
-StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Surface&, size_t ) {
+StatusCode Trk::RecursiveGeometryProcessor::processNode(const Trk::Surface&, size_t ) const {
     return StatusCode::SUCCESS;
 }
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx
index 6cecce2e0fa..a90f95cfec6 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTestTools/src/TrackingVolumeDisplayer.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -125,7 +125,7 @@ void Trk::TrackingVolumeDisplayer::closeFile(std::ofstream& out) const
 }
 
 
-StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::TrackingVolume& tvol, size_t)
+StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::TrackingVolume& tvol, size_t) const
 {
 
     ATH_MSG_VERBOSE("Writing display information for TrackingVolume.");
@@ -163,7 +163,7 @@ StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::TrackingVolume&
 }
 
 
-StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Layer& lay, size_t)
+StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Layer& lay, size_t) const
 {
     
     ATH_MSG_VERBOSE("Writing display information for Layer.");
@@ -256,7 +256,7 @@ StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Layer& lay, size
 }
 
 
-StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Surface& sf, size_t)
+StatusCode Trk::TrackingVolumeDisplayer::processNode(const Trk::Surface& sf, size_t) const
 {
 
     ++s_displaySurfaces;
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GenericGeometryBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GenericGeometryBuilderCond.h
new file mode 100644
index 00000000000..0e3e2aa1c92
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GenericGeometryBuilderCond.h
@@ -0,0 +1,83 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GenericGeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRTOOLS_GENERICGEOMETRYBUILDERCOND_H
+#define TRKDETDESCRTOOLS_GENERICGEOMETRYBUILDERCOND_H
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+
+// Gaudi & Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+
+class IEnvelopeDefSvc;
+
+namespace Trk {
+
+    class TrackingGeometry;
+    class TrackingVolume;
+    class ITrackingVolumeCreator;   
+    class ITrackingVolumeHelper;   
+
+    /** @class GenericGeometryBuilderCond
+
+      A TrackingGeometry builder that takes the EnvelopSvc and creates 
+      a very simple generic tracking geoemtry configured with Layers
+      
+      @author Andreas.Salzburger@cern.ch   
+     */
+
+    class GenericGeometryBuilderCond : public AthAlgTool, virtual public IGeometryBuilderCond {
+
+      public:
+        /** Constructor */
+        GenericGeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+        
+        /** Destructor */
+        virtual ~GenericGeometryBuilderCond();
+
+        /** AlgTool initialize method */
+        StatusCode initialize();
+        
+        /** AlgTool finalize method */
+        StatusCode finalize();
+        
+        /** TrackingGeometry Interface method - optionally a pointer to Bounds */
+        std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const;
+
+        /** The unique signature */
+        GeometrySignature geometrySignature() const;
+
+      private:
+        ServiceHandle<IEnvelopeDefSvc>          m_enclosingEnvelopeSvc;         //!< The service that determines the outermost boundaries
+        int                                     m_enclosingEnvelope;            //!< define which service you wanna have
+                                                                                
+        ToolHandle<Trk::ITrackingVolumeCreator> m_trackingVolumeCreator;        //!< Helper Tool to create TrackingVolumes
+                                                                                
+        int                                     m_geometrySignature;            //!< should hopefully correspond soon to the enclosing envelope
+        std::string                             m_geometryName;                 //!< name for the volumes
+        int                                     m_geometryColorCode;            //!< ->registerColorCode()
+        
+        double                                  m_barrelFraction;               //!< Barrel configuration                                                                        
+        int                                     m_barrelLayers;                 //!< Barrel configuration
+        int                                     m_endcapLayers;                 //!< Endcap configuration
+        mutable bool                            m_extendedEndcap;               //!< extended Endcap configuration
+        int                                     m_extendedEndcapLayers;         //!< extended Endcap configuration
+
+    };
+    
+    inline GeometrySignature GenericGeometryBuilderCond::geometrySignature() const { return (GeometrySignature)m_geometrySignature; }
+
+} // end of namespace
+
+#endif // TRKDETDESCRTOOLS_GENERICGEOMETRYBUILDERCOND_H
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GeometryBuilderCond.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GeometryBuilderCond.h
new file mode 100755
index 00000000000..15aea0b5cac
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/GeometryBuilderCond.h
@@ -0,0 +1,107 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GeometryBuilderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRTOOLS_GEOMETRYBUILDERCOND_H
+#define TRKDETDESCRTOOLS_GEOMETRYBUILDERCOND_H
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// Trk
+#include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
+#include "TrkDetDescrUtils/GeometrySignature.h"
+#include "TrkGeometry/TrackingVolumeManipulator.h"
+#include "TrkGeometry/Material.h"
+// Gaudi & Athena
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#ifdef TRKDETDESCR_MEMUSAGE   
+#include "TrkDetDescrUtils/MemoryLogger.h"
+#endif  
+
+namespace Trk {
+
+    class TrackingGeometry;
+    class TrackingVolume;
+    class ITrackingVolumeBuilder;
+    class ITrackingVolumeHelper;
+    class ITrackingVolumeArrayCreator;
+
+    /** @class GeometryBuilderCond
+
+      The Trk::TrackingGeometry Builder for ATLAS Geometry
+
+      It retrieves Trk::TrackingGeometry builders for the subdetectors and joins them together 
+      to a single Trk::TrackingGeometry.
+
+      @author Andreas.Salzburger@cern.ch   
+     */
+
+    class GeometryBuilderCond : public AthAlgTool,
+                            public TrackingVolumeManipulator,
+                    virtual public IGeometryBuilderCond {
+
+      public:
+        /** Constructor */
+        GeometryBuilderCond(const std::string&,const std::string&,const IInterface*);
+        
+        /** Destructor */
+        virtual ~GeometryBuilderCond();
+
+        /** AlgTool initialize method */
+        StatusCode initialize();
+        
+        /** AlgTool finalize method */
+        StatusCode finalize();
+        
+        /** TrackingGeometry Interface method - optionally a pointer to Bounds */
+        std::pair<EventIDRange, const Trk::TrackingGeometry*> trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> tVolPair) const;
+
+        /** The unique signature */
+        GeometrySignature geometrySignature() const { return Trk::Global; }
+
+      private:
+
+        /** TrackingGeometry for ATLAS setup */
+        std::pair<EventIDRange, const Trk::TrackingGeometry*> atlasTrackingGeometry(const EventContext& ctx) const;
+
+#ifdef TRKDETDESCR_MEMUSAGE         
+        MemoryLogger                        m_memoryLogger;                //!< in case the memory is logged
+#endif      
+
+        bool                                m_createWorld;                 //!< Boolean Switch to create World manually
+        int                                 m_navigationLevel;             //!< NavigationLevel
+
+        std::vector< double >               m_worldDimension;              //!< The dimensions of the manually created world
+        std::vector< double >               m_worldMaterialProperties;     //!< The material properties of the created world
+        Material                            m_worldMaterial;               //!< the world material
+
+        // -------------------------- Tools for geometry building ------------------------------------------------------ //
+
+        ToolHandle<ITrackingVolumeArrayCreator>   m_trackingVolumeArrayCreator;       //!< Helper Tool to create TrackingVolume Arrays
+
+        ToolHandle<ITrackingVolumeHelper>         m_trackingVolumeHelper;             //!< Helper Tool to create TrackingVolumes
+
+        //bool                                      m_inDetGeometry;                     //!< switch on TrackingGeometry for the InnerDetector
+        ToolHandle<IGeometryBuilderCond>              m_inDetGeometryBuilderCond;              //!< GeometryBuilderCond for the InnerDetector
+
+        bool                                      m_caloGeometry;                     //!< switch on TrackingGeometry for the Calorimeters
+        ToolHandle<IGeometryBuilderCond>              m_caloGeometryBuilderCond;              //!< GeometryBuilderCond for the Calorimeters
+
+        bool                                      m_muonGeometry;                     //!< GeometryBuilderCond for the Muon System
+        ToolHandle<IGeometryBuilderCond>              m_muonGeometryBuilderCond;              //!< GeometryBuilderCond for the Muon System
+        
+        bool                                      m_compactify;                       //!< optimize event memory usage: register all surfaces with TG
+        bool                                      m_synchronizeLayers;                //!< synchronize contained layer dimensions to volumes
+
+    };
+
+} // end of namespace
+
+#endif // TRKDETDESCRTOOLS_GEOMETRYBUILDERCOND_H
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h
index 55ca754bfdf..12ee4de10dd 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/InputLayerMaterialProvider.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -45,16 +45,16 @@ namespace Trk {
         virtual StatusCode initialize();
 
         /** Processor Action to work on TrackingGeometry& tgeo */
-        virtual StatusCode process(const TrackingGeometry& tgeo);
+        virtual StatusCode process(const TrackingGeometry& tgeo) const;
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0);   
+        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode process(const Layer& lay, size_t level = 0);
+        virtual StatusCode process(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode process(const Surface& surf, size_t level = 0);
+        virtual StatusCode process(const Surface& surf, size_t level = 0) const;
 
       private:
          bool               m_constantMaterialToAllLayers;  //!< just assign a dummy material to all layers
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h
index 90e1553759c..69f164d1fee 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerMaterialProvider.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -42,23 +42,25 @@ namespace Trk {
         virtual ~LayerMaterialProvider();
 
         /** Processor Action to work on TrackingGeometry& tgeo */
-        virtual StatusCode process(const TrackingGeometry& tgeo);
+        virtual StatusCode process(const TrackingGeometry& tgeo) const;
        
         /** Processor Action to work on TrackingVolumes - the level is for the hierachy tree*/
-        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0);   
+        virtual StatusCode process(const TrackingVolume& tvol, size_t level = 0) const;
        
         /** Processor Action to work on Layers */
-        virtual StatusCode process(const Layer& lay, size_t level = 0);
+        virtual StatusCode process(const Layer& lay, size_t level = 0) const;
        
         /** Processor Action to work on Surfaces */
-        virtual StatusCode process(const Surface& surf, size_t level = 0);
+        virtual StatusCode process(const Surface& surf, size_t level = 0) const;
 
       private:
           
-        StatusCode loadMaterialMap();               //!< reatrieve the Material map from the detector store
+        StatusCode loadMaterialMap() const;               //!< reatrieve the Material map from the detector store
 
         //!< boolean switch for assignLayerMaterial
-        mutable const LayerMaterialMap*             m_layerMaterialMap;
+
+        mutable std::once_flag                      m_loadMapOnceFlag ATLAS_THREAD_SAFE;
+        mutable const LayerMaterialMap*             m_layerMaterialMap ATLAS_THREAD_SAFE;
         std::string                                 m_layerMaterialMapName;
                         
         
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerProviderCond.h b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerProviderCond.h
new file mode 100644
index 00000000000..95850128548
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/TrkDetDescrTools/LayerProviderCond.h
@@ -0,0 +1,72 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// LayerProviderCond.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef TRKDETDESCRTOOLS_LAYERPROVIDERCOND_H
+#define TRKDETDESCRTOOLS_LAYERPROVIDERCOND_H
+
+// Trk
+#include "TrkDetDescrInterfaces/ILayerProviderCond.h"
+// Gaudi & Athena
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthAlgTool.h"
+
+
+namespace Trk {
+
+    class Layer;
+    class ILayerBuilderCond;
+
+
+    /** @class LayerProviderCond
+
+      Wrapper around an ILayerBuilderCond to feed into the StagedGeometryBuilder
+
+      @author Andreas.Salzburger@cern.ch
+     */
+
+    class LayerProviderCond :  public AthAlgTool, virtual public ILayerProviderCond {
+     
+      public:
+        /** Constructor */
+        LayerProviderCond(const std::string&,const std::string&,const IInterface*);
+
+        /** Destructor */
+        virtual ~LayerProviderCond();
+        
+        /** initialize */
+        StatusCode initialize();
+        
+        /** finalize */
+        StatusCode finalize();
+
+        /** LayerBuilder interface method - returning the layers at negative side */
+        std::pair<EventIDRange, const std::vector< const Layer* > > negativeLayers(const EventContext& ctx) const; 
+      
+        /** LayerBuilder interface method - returning the central layers */
+        std::pair<EventIDRange, const std::vector< const Layer* > > centralLayers(const EventContext& ctx) const; 
+      
+        /** LayerBuilder interface method - returning the layers at negative side */
+        std::pair<EventIDRange, const std::vector< const Layer* > > positiveLayers(const EventContext& ctx) const; 
+
+        /** Name identification */
+        const std::string& identification() const;
+
+      private:
+        /** LayerBuilder interface method - returning the layers at negative side */
+        std::pair<EventIDRange, const std::vector< const Layer* > > discLayers(const EventContext& ctx, int posneg) const;   
+      
+        ToolHandle<ILayerBuilderCond>           m_layerBuilder;
+        mutable std::vector<const Trk::Layer*>  m_layerCache;
+        
+    };
+
+
+} // end of namespace
+
+#endif // TRKDETDESCRTOOLS_LAYERPROVIDERCOND_H
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/GenericGeometryBuilderCond.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GenericGeometryBuilderCond.cxx
new file mode 100644
index 00000000000..f65cdef1ce2
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GenericGeometryBuilderCond.cxx
@@ -0,0 +1,281 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GenericGeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// EnvelopeDefinitionService
+#include "SubDetectorEnvelopes/IEnvelopeDefSvc.h"
+// Trk include
+#include "TrkDetDescrTools/GenericGeometryBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/Material.h"
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// STD
+#include <map>
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+
+// constructor
+Trk::GenericGeometryBuilderCond::GenericGeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p)
+: AthAlgTool(t,n,p),
+  m_enclosingEnvelopeSvc("AtlasEnvelopeDefSvc", n),      
+  m_enclosingEnvelope(0),         
+  m_trackingVolumeCreator(""),
+  m_geometrySignature(0),
+  m_geometryName("Undefined"),
+  m_geometryColorCode(8),
+  m_barrelFraction(0.75),         
+  m_barrelLayers(10),         
+  m_endcapLayers(20),       
+  m_extendedEndcap(false),            
+  m_extendedEndcapLayers(5)
+{
+    // declare the interface
+    declareInterface<Trk::IGeometryBuilderCond>(this);
+    // Tools & Services
+    declareProperty("EnvelopeDefinitionSvc",        m_enclosingEnvelopeSvc);      
+    declareProperty("Envelope",                     m_enclosingEnvelope);         
+    declareProperty("TrackingVolumeCreator",        m_trackingVolumeCreator);  
+    // configuration                                
+    declareProperty("GeometrySignature",            m_geometrySignature);
+    declareProperty("GeometryName",                 m_geometryName);
+    declareProperty("GeometryColorCode",            m_geometryColorCode);
+    // Barrel Layer configuration                   
+    declareProperty("BarrelFraction",               m_barrelFraction);              
+    declareProperty("BarrelLayers",                 m_barrelLayers);              
+    // Endcap Layer configuration                   
+    declareProperty("EndcapLayers",                 m_endcapLayers);             
+    // Extended endcap Layer configuration 
+    declareProperty("ExtendedEndcap",               m_extendedEndcap);            
+    declareProperty("ExtendedEndcapLayers",         m_extendedEndcapLayers);      
+}
+
+// destructor
+Trk::GenericGeometryBuilderCond::~GenericGeometryBuilderCond()
+{}
+
+// Athena standard methods - initialize
+StatusCode Trk::GenericGeometryBuilderCond::initialize()
+{
+    // Retrieve the volume array creator  ----------------------------------------------------
+    if (m_enclosingEnvelopeSvc.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve EnvelopeSvc " << m_enclosingEnvelopeSvc );
+        return StatusCode::FAILURE;
+    } else 
+        ATH_MSG_INFO( "Retrieved " << m_enclosingEnvelopeSvc );
+
+    // Retrieve the tracking volume creator  --------------------------------------------------    
+    if (m_trackingVolumeCreator.retrieve().isFailure()) {
+        ATH_MSG_FATAL("Failed to retrieve tool " << m_trackingVolumeCreator );
+        return StatusCode::FAILURE;
+    } else 
+        ATH_MSG_INFO( "Retrieved tool " << m_trackingVolumeCreator );
+
+    ATH_MSG_INFO( " initialize() successful" );
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode Trk::GenericGeometryBuilderCond::finalize()
+{
+    ATH_MSG_INFO( "finalize() successful." );
+    return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Trk::GenericGeometryBuilderCond::trackingGeometry(const EventContext& /*ctx*/, std::pair< EventIDRange, const Trk::TrackingVolume*> innerVolPair) const
+{
+
+    ATH_MSG_VERBOSE("Starting to build TrackingGeometry for GeometrySignature : " << m_geometrySignature );
+
+    // the geometry to be constructed
+    const Trk::TrackingGeometry* tGeometry = 0;
+    
+    double innerVolumeRadius             = 0.;
+    double innerVolumeHalfZ              = 0.;
+    double enclosingVolumeRadius         = 0.;
+    double enclosingVolumeHalfZ          = 0.;
+    double enclosingExtendedVolumeRadius = 0.;
+    double enclosingExtendedVolumeHalfZ  = 0.;
+
+    // vacuum
+    Trk::Material vacuum;
+    
+    RZPairVector envelopeDefs;  
+    // build the inner detector if configured
+    if (m_geometrySignature == Trk::ID){
+        // get the dimensions from the envelope service 
+        envelopeDefs = m_enclosingEnvelopeSvc->getInDetRZValues();
+        ATH_MSG_VERBOSE("       -> retrieved Inner Detector envelope definitions at size " << envelopeDefs.size());
+    } else if ( m_geometrySignature == Trk::Calo  ){
+        // get the dimensions from the envelope service 
+        envelopeDefs = m_enclosingEnvelopeSvc->getCaloRZValues();
+        ATH_MSG_VERBOSE("       -> retrieved Calorimeter envelope definitions at size " << envelopeDefs.size());
+    } else if ( m_geometrySignature == Trk::MS ) {
+        // get the dimensions from the envelope service 
+        envelopeDefs = m_enclosingEnvelopeSvc->getMuonRZValues();
+        ATH_MSG_VERBOSE("       -> retrieved Muon System envelope definitions at size " << envelopeDefs.size());
+    } else {
+        ATH_MSG_WARNING("No geometry signature found, return 0.");
+        //dummy infinite range
+        EventIDRange range;
+        return std::make_pair(range,tGeometry);
+    }
+
+    // ------------------------------- overall dimensions ----------------------------------------------
+    // get the maximum extend in R
+    for ( auto& rzIter : envelopeDefs){
+        if ( rzIter.first > enclosingVolumeRadius ) {
+            // maximal r-extend
+            enclosingVolumeRadius = rzIter.first;
+            enclosingVolumeHalfZ  = fabs(rzIter.second);            
+        }
+    }
+    ATH_MSG_VERBOSE("       -> Overall dimensions estimated as (r,hZ) = " << enclosingVolumeRadius << ", " << enclosingVolumeHalfZ);
+    
+    // we need to build extended barrels ---------------------------------------------------------------
+    if ( m_extendedEndcap && envelopeDefs.size() > 4){
+        ATH_MSG_VERBOSE("       -> configured to build extended Barrel, checking for RZpair direction.");
+        // find out the direction of the rz points point
+        Amg::Vector3D p1(envelopeDefs[0].second,envelopeDefs[0].first, 0.);
+        Amg::Vector3D p2(envelopeDefs[1].second,envelopeDefs[1].first, 0.);
+        int clockwise = p1.cross(p2).z() < 0. ? 1 : -1;
+        ATH_MSG_VERBOSE("       -> determined " << ( clockwise>0 ? "clockwise" : "anti-clockwise") << " direction from (z1,r1) = " 
+            << envelopeDefs[0].second << ", " << envelopeDefs[0].first << " and " << envelopeDefs[1].second << ", " << envelopeDefs[1].first );
+        // now parse for the extended barrel  
+        size_t irz = 0;  
+        for ( auto& rzIter : envelopeDefs){
+            if (irz > 1 && rzIter.second > 0 && rzIter.first >= enclosingVolumeRadius ) {
+                // maximal r-extend
+                enclosingExtendedVolumeRadius = envelopeDefs[irz-clockwise*2].first;
+                enclosingExtendedVolumeHalfZ  = envelopeDefs[irz-clockwise*2].second;            
+            }
+            ++irz;
+        }
+        ATH_MSG_VERBOSE("       -> Extended dimensions estimated as (r,hZ) = " << enclosingExtendedVolumeRadius << ", " << enclosingExtendedVolumeHalfZ);
+            
+    } else {
+        ATH_MSG_WARNING("Could not parse dimensions for extended Barrel, ignoring it.");
+        m_extendedEndcap = false;
+    }
+    // --------------------------------------------------------------------------------------------------
+
+    //generic detector has infinite alignment validity range or if exists of input volume
+    EventIDRange range;
+
+    // get the inner radius and half length if a volume is provided
+    const Trk::CylinderVolumeBounds* cvb = 0;
+    const Trk::TrackingVolume* innerVol = innerVolPair.second;
+    if (innerVol){
+        range = innerVolPair.first;
+        cvb = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(innerVol->volumeBounds()));
+        if (cvb){
+            innerVolumeRadius = cvb->outerRadius();
+            innerVolumeHalfZ  = cvb->halflengthZ();
+            ATH_MSG_VERBOSE("       -> inner cylindrical volume found with (r,hZ) = " << innerVolumeRadius << ", " << innerVolumeHalfZ);
+        } 
+    }
+    if (!cvb){
+       // if no suitable inner volume is given, divide into the configured barrel fraction
+       innerVolumeHalfZ = m_barrelFraction*0.5*enclosingVolumeHalfZ;
+       ATH_MSG_VERBOSE("       -> no (suitable) inner volume found, setting barrel/endcap fraction as configured.");
+       
+    }
+
+    // now create the barrel-type volume wrapping around the  inner volume
+    const Trk::TrackingVolume* cSector = m_trackingVolumeCreator->createGapTrackingVolume(vacuum,
+                                                                                         innerVolumeRadius, enclosingVolumeRadius,
+                                                                                         -innerVolumeHalfZ, innerVolumeHalfZ,
+                                                                                         m_barrelLayers,
+                                                                                         true,
+                                                                                         m_geometryName+"::Generic::Barrel");
+    cSector->registerColorCode(m_geometryColorCode);
+    // wrap the inner volume into a centralSector 
+    if (cvb){ 
+        auto centralVolumes = std::vector<const Trk::TrackingVolume*>{innerVol, cSector};
+        // override barrelVolume if enclosing is needed -> memory ownership shifted to container
+        cSector = m_trackingVolumeCreator->createContainerTrackingVolume(centralVolumes,
+                                                                         vacuum,
+                                                                         m_geometryName+"::Containers::Central");
+    }
+    // create the two endcaps
+    const Trk::TrackingVolume* nSector = m_trackingVolumeCreator->createGapTrackingVolume(vacuum,
+                                                                                         0., enclosingVolumeRadius,
+                                                                                         -enclosingVolumeHalfZ, -innerVolumeHalfZ,
+                                                                                         m_endcapLayers,
+                                                                                         false,
+                                                                                         m_geometryName+"::Generic::NegativeEndcap");
+    nSector->registerColorCode(m_geometryColorCode);
+    // create the two endcaps
+    const Trk::TrackingVolume* pSector = m_trackingVolumeCreator->createGapTrackingVolume(vacuum,
+                                                                                         0., enclosingVolumeRadius,
+                                                                                         innerVolumeHalfZ, enclosingVolumeHalfZ,
+                                                                                         m_endcapLayers,
+                                                                                         false,
+                                                                                         m_geometryName+"::Generic::PositiveEndcap");
+    pSector->registerColorCode(m_geometryColorCode);
+    
+    auto allVolumes = std::vector<const Trk::TrackingVolume*>();
+    // if extended barrel is to be built
+    auto extendedVolumes = std::vector<const Trk::TrackingVolume*>();
+    if ( m_extendedEndcap){
+        auto names = std::vector<std::string>{ "Negative", "Positive"};
+        for ( size_t it = 0; it < 2; ++it){ 
+          // which side we are
+          double minZ = !it ? -enclosingExtendedVolumeHalfZ : enclosingVolumeHalfZ;
+          double maxZ = !it ? -enclosingVolumeHalfZ : enclosingExtendedVolumeHalfZ;  
+          // create the extended volume (bottom part)
+          const Trk::TrackingVolume* exVolume = m_trackingVolumeCreator->createGapTrackingVolume(
+                                                                                vacuum,
+                                                                                0., enclosingExtendedVolumeRadius,
+                                                                                minZ, maxZ,
+                                                                                m_extendedEndcapLayers,
+                                                                                false,
+                                                                                m_geometryName+"::Generic::Extended"+names[it]);
+          exVolume->registerColorCode(m_geometryColorCode);
+          // create the extended volume (ring part)
+          const Trk::TrackingVolume* exrVolume = m_trackingVolumeCreator->createGapTrackingVolume(
+                                                                                vacuum,
+                                                                                enclosingExtendedVolumeRadius, enclosingVolumeRadius,
+                                                                                minZ, maxZ,
+                                                                                m_extendedEndcapLayers,
+                                                                                false,
+                                                                                m_geometryName+"::Generic::RingExtended"+names[it]);
+          // sign it with one higher volume id 
+          exrVolume->sign( Trk::GeometrySignature(int(geometrySignature())+1) );
+          // pack it into a container
+          auto exVolumes = std::vector<const Trk::TrackingVolume*>{exVolume, exrVolume};
+          const Trk::TrackingVolume* exSector = m_trackingVolumeCreator->createContainerTrackingVolume(exVolumes,
+                                                                                                       vacuum,
+                                                                                                       m_geometryName+"::Generic::"+names[it]+"ExtendedEndcap");
+          // for the overall geometry                                                                     
+          extendedVolumes.push_back(exSector);                                                                    
+       }
+    }
+    // and now create the triple
+    allVolumes = extendedVolumes.size() ?  std::vector<const Trk::TrackingVolume*>{extendedVolumes[0],nSector,cSector,pSector,extendedVolumes[1]} : 
+                                           std::vector<const Trk::TrackingVolume*>{nSector,cSector,pSector};
+    const Trk::TrackingVolume* tVolume = m_trackingVolumeCreator->createContainerTrackingVolume(allVolumes,
+                                                                                                vacuum,
+                                                                                                m_geometryName+"::Container");                                                                                      
+    // now create the TrackingGeometry from the highest volume
+    if (tVolume) {
+      tGeometry = new Trk::TrackingGeometry(tVolume);
+      tGeometry->indexStaticLayers(geometrySignature());   
+    }
+
+
+    return std::make_pair(range, tGeometry);
+
+}
+
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/GeometryBuilderCond.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GeometryBuilderCond.cxx
new file mode 100755
index 00000000000..c0d068d95a2
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/GeometryBuilderCond.cxx
@@ -0,0 +1,451 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// GeometryBuilderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// Trk include
+#include "TrkDetDescrTools/GeometryBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeBuilder.h"
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeArrayCreator.h"
+#include "TrkDetDescrInterfaces/ITrackingVolumeHelper.h"
+#include "TrkVolumes/CylinderVolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkGeometry/TrackingGeometry.h"
+#include "TrkGeometry/GlueVolumesDescriptor.h"
+
+#ifdef TRKDETDESCR_MEMUSAGE                            
+#include <unistd.h>
+#endif
+
+// Amg
+#include "GeoPrimitives/GeoPrimitives.h"
+// STD
+#include <map>
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+
+// constructor
+Trk::GeometryBuilderCond::GeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p)
+: AthAlgTool(t,n,p),
+  TrackingVolumeManipulator(),
+#ifdef TRKDETDESCR_MEMUSAGE      
+  m_memoryLogger(),
+#endif 
+  m_createWorld(true),
+  m_navigationLevel(2),
+  m_worldDimension(),
+  m_worldMaterialProperties(),
+  m_trackingVolumeArrayCreator("Trk::TrackingVolumeArrayCreator/TrackingVolumeArrayCreator"),
+  m_trackingVolumeHelper("Trk::TrackingVolumeHelper/TrackingVolumeHelper"),
+  m_inDetGeometryBuilderCond("", this),
+  m_caloGeometry{},
+  m_caloGeometryBuilderCond("", this),
+  m_muonGeometry{},
+  m_muonGeometryBuilderCond("", this),
+  m_compactify(true),
+  m_synchronizeLayers(true)
+{
+    declareInterface<IGeometryBuilderCond>(this);
+    // by hand declarations
+    declareProperty("CreateWorldManually",                  m_createWorld);
+    declareProperty("NavigationLevel",                      m_navigationLevel);
+    // (1) dimension & material
+    declareProperty("WorldDimension",                       m_worldDimension);
+    declareProperty("WorldMaterialProperties",              m_worldMaterialProperties);
+    // tool declarations ----------------------------------------------------------------
+    declareProperty("TrackingVolumeArrayCreator",           m_trackingVolumeArrayCreator);
+    declareProperty("TrackingVolumeHelper",                 m_trackingVolumeHelper);
+    declareProperty("InDetTrackingGeometryBuilder",         m_inDetGeometryBuilderCond);
+    declareProperty("CaloTrackingGeometryBuilder",          m_caloGeometryBuilderCond);
+    declareProperty("MuonTrackingGeometryBuilder",          m_muonGeometryBuilderCond);
+    // optimize layer dimension & memory usage -------------------------------
+    declareProperty("Compactify",                           m_compactify );
+    declareProperty("SynchronizeLayers",                    m_synchronizeLayers );
+}
+
+// destructor
+Trk::GeometryBuilderCond::~GeometryBuilderCond()
+{}
+
+
+// Athena standard methods
+// initialize
+StatusCode Trk::GeometryBuilderCond::initialize()
+{
+
+    // Retrieve the volume array creator  ----------------------------------------------------
+    ATH_CHECK(m_trackingVolumeArrayCreator.retrieve()); 
+
+    // Retrieve the tracking volume helper  --------------------------------------------------    
+    ATH_CHECK (m_trackingVolumeHelper.retrieve()); 
+    // Geometries =============================================================================
+    // (I) Inner Detector ---------------------------------------------------------------------
+    if (!m_inDetGeometryBuilderCond.empty()) {
+        ATH_CHECK(m_inDetGeometryBuilderCond.retrieve());
+    }
+    // (C) Calorimeter --------------------------------------------------------------------------
+    if (!m_caloGeometryBuilderCond.empty()) {
+        ATH_CHECK (m_caloGeometryBuilderCond.retrieve());
+    }
+    // (M) Muon System -------------------------------------------------------------------------
+    if (!m_muonGeometryBuilderCond.empty()) {
+        ATH_CHECK(m_muonGeometryBuilderCond.retrieve());
+    }
+
+    // if no world dimensions are declared, take default ones
+    if (!m_worldDimension.size())
+        m_worldDimension = std::vector<double>{0.*Gaudi::Units::meter, 10.*Gaudi::Units::meter, 15.*Gaudi::Units::meter};
+
+    // if no world materials are declared, take default ones - set vacuum 
+    if (m_worldMaterialProperties.size() < 5) 
+        m_worldMaterialProperties = std::vector<double>{10.e10,10.e10,0., 0., 0.};
+
+    m_worldMaterial = Trk::Material(m_worldMaterialProperties[0],
+				    m_worldMaterialProperties[1],
+				    m_worldMaterialProperties[2],
+				    m_worldMaterialProperties[3],
+				    m_worldMaterialProperties[4]);
+
+    ATH_MSG_DEBUG( " initialize() successful" );
+
+    return StatusCode::SUCCESS;
+}
+
+// finalize
+StatusCode Trk::GeometryBuilderCond::finalize()
+{
+    ATH_MSG_DEBUG( "finalize() successful." );
+    return StatusCode::SUCCESS;
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Trk::GeometryBuilderCond::trackingGeometry(const EventContext& ctx, std::pair<EventIDRange, const Trk::TrackingVolume*> /*tVolPair*/) const
+{
+
+    // the geometry to be constructed
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> tGeometry;
+    if ( m_inDetGeometryBuilderCond.empty() && m_caloGeometryBuilderCond.empty() && m_muonGeometryBuilderCond.empty() ) {
+
+        ATH_MSG_VERBOSE( "Configured to only create world TrackingVolume." );
+
+        Trk::VolumeBounds* worldBounds = new Trk::CylinderVolumeBounds(m_worldDimension[0],
+                                                                       m_worldDimension[1],
+                                                                       m_worldDimension[2]);
+
+        Trk::TrackingVolume* worldVolume = new Trk::TrackingVolume(0,
+                                                                   worldBounds,
+                                                                   m_worldMaterial,
+                                                                   (const LayerArray*) 0,
+                                                                   (const TrackingVolumeArray*) 0,
+                                                                   "EmptyWorldVolume");
+        //dummy infinite IOV range
+        EventIDRange range;
+
+        // create a new geometry
+        tGeometry = std::make_pair(range, new Trk::TrackingGeometry(worldVolume));
+    } else
+        tGeometry = atlasTrackingGeometry(ctx);
+    // sign it before you return anything
+    tGeometry.second->sign(geometrySignature());
+    return tGeometry;
+
+}
+
+
+std::pair<EventIDRange, const Trk::TrackingGeometry*> Trk::GeometryBuilderCond::atlasTrackingGeometry(const EventContext& ctx) const
+{
+    // the return geometry
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> atlasTrackingGeometry;
+    //Set IOV range covering 0 - inf
+    EventIDRange range;
+
+    // A ------------- INNER DETECTOR SECTION --------------------------------------------------------------------------------
+    // get the Inner Detector and/or Calorimeter trackingGeometry
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> inDetTrackingGeometry;
+    std::pair<EventIDRange, const Trk::TrackingGeometry*> caloTrackingGeometry ;
+
+    // the volumes to be given to higher level tracking geometry builders
+    const Trk::TrackingVolume* inDetVolume    = 0;
+    const Trk::TrackingVolume* caloVolume     = 0;
+
+    // mark the highest volume
+    const Trk::TrackingVolume* highestVolume  = 0;
+
+#ifdef TRKDETDESCR_MEMUSAGE       
+    m_memoryLogger.refresh(getpid());
+    ATH_MSG_INFO( "[ memory usage ] Start of TrackingGeometry building: "  );    
+    ATH_MSG_INFO( m_memoryLogger );                     
+#endif  
+
+    // ========================== INNER DETECTOR PART =================================================
+    if (!m_inDetGeometryBuilderCond.empty()) {
+        // debug output
+        ATH_MSG_VERBOSE( "ID Tracking Geometry is going to be built." );
+        // build the geometry
+        inDetTrackingGeometry = m_inDetGeometryBuilderCond->trackingGeometry(ctx, std::pair<EventIDRange, const Trk::TrackingVolume*>(range, nullptr));
+        // check
+        if (inDetTrackingGeometry.second) {
+            // sign it
+            inDetTrackingGeometry.second->sign(m_inDetGeometryBuilderCond->geometrySignature());
+            // check whether the world has to be created or not
+            if (m_createWorld || m_caloGeometry || m_muonGeometry) {
+                // checkout the highest InDet volume
+                inDetVolume = inDetTrackingGeometry.second->checkoutHighestTrackingVolume();
+                // assign it as the highest volume
+                highestVolume = inDetVolume;
+                range = inDetTrackingGeometry.first;
+                // cleanup
+                delete inDetTrackingGeometry.second;
+            } else // -> Take the exit and return ID stand alone
+                atlasTrackingGeometry = inDetTrackingGeometry;
+        }
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After InDet TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+    }
+
+    // ========================== CALORIMETER PART =================================================
+    // if a Calo Geometry Builder is present -> wrap it around the ID
+    if (!m_caloGeometryBuilderCond.empty()) {
+        if (inDetVolume)
+            ATH_MSG_VERBOSE( "Calorimeter Tracking Geometry is going to be built with enclosed ID." );
+        else 
+            ATH_MSG_VERBOSE( "Calorimeter Tracking Geometry is going to be built stand-alone." );
+        // get the InnerDetector TrackingGeometry
+        caloTrackingGeometry = m_caloGeometryBuilderCond->trackingGeometry(ctx, std::make_pair(inDetTrackingGeometry.first, inDetVolume));
+        // if you have to create world or there is a Muon geometry builder ...
+        if (caloTrackingGeometry.second) {
+            // sign it
+            caloTrackingGeometry.second->sign(m_caloGeometryBuilderCond->geometrySignature());
+            if (m_createWorld || m_muonGeometry){
+                // check out the highest Calo volume
+                caloVolume = caloTrackingGeometry.second->checkoutHighestTrackingVolume();
+                // assign it as the highest volume (overwrite ID)
+                highestVolume = caloVolume;
+                range = caloTrackingGeometry.first;
+                // cleanup
+                delete caloTrackingGeometry.second;
+            } else // -> Take the exit and return Calo back
+                atlasTrackingGeometry = caloTrackingGeometry;
+        }
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After Calo TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+    }
+
+    // ========================== MUON SYSTEM PART =================================================
+    // if Muon Geometry Builder is present -> wrap either ID or Calo
+    if (!m_muonGeometryBuilderCond.empty()) {
+
+        std::string enclosed = "stand-alone.";
+        if (inDetVolume && caloVolume)
+            enclosed = "with encloded ID/Calo.";
+        else if (inDetVolume || caloVolume)
+            enclosed = (inDetVolume) ? "with encloded ID." : "with encloded Calo.";                  
+        ATH_MSG_VERBOSE( "Muon System Tracking Geometry is going to be built "<< enclosed );
+        // there's nothing outside the muons -- wrap the calo if it exists
+        if (inDetVolume && !caloVolume)
+            atlasTrackingGeometry = m_muonGeometryBuilderCond->trackingGeometry(ctx, std::make_pair(inDetTrackingGeometry.first, inDetVolume));
+        else
+            atlasTrackingGeometry = m_muonGeometryBuilderCond->trackingGeometry(ctx, std::make_pair(caloTrackingGeometry.first, caloVolume));
+
+        // sign it
+        if (atlasTrackingGeometry.second)
+            atlasTrackingGeometry.second->sign(m_muonGeometryBuilderCond->geometrySignature());
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After Muon TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+        // ========================== WRAPPING SECTION FOR ID/CALO ====================================
+    } else if (m_createWorld && highestVolume) {
+        // wrapping and world creation has been switched on
+        ATH_MSG_VERBOSE( "Enclosing world is going to be built for: " << highestVolume->volumeName() );
+        // get the glue volumes
+        const Trk::GlueVolumesDescriptor& innerGlueVolumes = highestVolume->glueVolumesDescriptor();
+        // some screen output
+        ATH_MSG_VERBOSE( "Retrieved with following glue volumes: " << innerGlueVolumes );
+        // at negative face
+        const std::vector<const Trk::TrackingVolume*>& innerNegativeFaceVolumes = innerGlueVolumes.glueVolumes(Trk::negativeFaceXY);
+        // at cylinder cover
+        const std::vector<const Trk::TrackingVolume*>& innerCentralFaceVolumes = innerGlueVolumes.glueVolumes(Trk::cylinderCover);
+        // at positive face
+        const std::vector<const Trk::TrackingVolume*>& innerPositiveFaceVolumes = innerGlueVolumes.glueVolumes(Trk::positiveFaceXY);
+
+        // get the dimensions
+        // cast them to CylinderVolumeBounds
+        const Trk::CylinderVolumeBounds* innerVolumeBounds = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(highestVolume->volumeBounds()));
+        if (!innerVolumeBounds) ATH_MSG_WARNING( "atlasTrackingGeometry() ... dynamic cast to innerVolumeBounds failed!" );
+        double innerVolumeOuterR      = innerVolumeBounds ? innerVolumeBounds->outerRadius() : 0;
+        double innerVolumeHalflengthZ = innerVolumeBounds ? innerVolumeBounds->halflengthZ() : 0;
+        // Hierarchy after enclosing
+        //
+        // AtlasWorldVolume:
+        //    AtlasInnerCylinder
+        //       AtlasInnerNegativeSector
+        //       InnerEnclosedVolume (can be ID/Calo)
+        //       AtlasOuterNegativeSector
+        //    AtlasOuterTube
+        // B -------------- BUILD WORLD AROUND for ID stand alone applications
+
+        double innerCylinderSectorHalflengthZ = 0.5*(m_worldDimension[2] - innerVolumeHalflengthZ);
+        Trk::CylinderVolumeBounds* innerCylinderSectorBounds =
+                new Trk::CylinderVolumeBounds(0., innerVolumeOuterR, innerCylinderSectorHalflengthZ);
+
+        double innerCylinderSectorPositionZ = fabs(m_worldDimension[2]-innerCylinderSectorHalflengthZ);
+
+        // the AtlasInnerNegativeSector
+        Amg::Transform3D* atlasInnerNegativeSectorTransf = new Amg::Transform3D;
+                        (*atlasInnerNegativeSectorTransf) = Amg::Translation3D(0.,0.,-innerCylinderSectorPositionZ);
+        Trk::TrackingVolume* atlasInnerNegativeSector = new Trk::TrackingVolume(
+                               atlasInnerNegativeSectorTransf,
+                               innerCylinderSectorBounds,
+                               m_worldMaterial,
+                               (const LayerArray*) 0,
+                               (const TrackingVolumeArray*) 0,
+                               "AtlasInnerNegativeSector");
+
+        // the AtlasInnerPositiveSector
+        Amg::Transform3D* atlasInnerPositiveSectorTransf = new Amg::Transform3D;
+                        (*atlasInnerPositiveSectorTransf) = Amg::Translation3D(0.,0.,innerCylinderSectorPositionZ);
+        Trk::TrackingVolume* atlasInnerPositiveSector = new Trk::TrackingVolume(
+                               atlasInnerPositiveSectorTransf,
+                               innerCylinderSectorBounds->clone(),
+                               m_worldMaterial,
+                               (const LayerArray*) 0,
+                               (const TrackingVolumeArray*) 0,
+                               "AtlasInnerPositiveSector");
+
+        ATH_MSG_VERBOSE( "Inner Negative/Positive Sectors built successfully." );
+
+        // create the subvolume Array
+        auto atlasInnerSectorVolumes = std::vector<const Trk::TrackingVolume*>{atlasInnerNegativeSector,highestVolume,atlasInnerPositiveSector}; 
+
+        ATH_MSG_VERBOSE( "Create the Atlas Inner Sector volumes. " );
+        Trk::BinnedArray<Trk::TrackingVolume>* atlasInnerSectorVolumeArray = m_trackingVolumeArrayCreator ?
+                m_trackingVolumeArrayCreator->cylinderVolumesArrayInZ(atlasInnerSectorVolumes) : 0;
+
+
+        // Atlas inner Sector bounds
+        Trk::CylinderVolumeBounds* innerSectorBounds =
+                new Trk::CylinderVolumeBounds(0., innerVolumeOuterR, m_worldDimension[2]);
+        // build the Tracking volumes
+        Trk::TrackingVolume* atlasInnerSector = new Trk::TrackingVolume(0,
+                                                                        innerSectorBounds,
+                                                                        m_worldMaterial,
+                                                                        0,atlasInnerSectorVolumeArray,
+                                                                        "AtlasInnerSector");
+
+        // Atlas outer Sector
+        Trk::CylinderVolumeBounds* outerSectorBounds =
+                new Trk::CylinderVolumeBounds(innerVolumeOuterR, m_worldDimension[1], m_worldDimension[2]);
+        Trk::TrackingVolume* atlasOuterSector = new Trk::TrackingVolume(0,
+                                                                        outerSectorBounds,
+                                                                        m_worldMaterial,
+                                                                        (const LayerArray*) 0,
+                                                                        (const TrackingVolumeArray*) 0,
+                                                                        "AtlasOuterSector");
+
+        ATH_MSG_VERBOSE( "Atlas Inner/Outer Sectors built successfully." );
+
+        // create the array of Inner and Outer sector
+        auto atlasVolumes =  std::vector<const Trk::TrackingVolume*>{atlasInnerSector, atlasOuterSector};
+
+        Trk::BinnedArray<Trk::TrackingVolume>* atlasVolumeArray = m_trackingVolumeArrayCreator ?
+                m_trackingVolumeArrayCreator->cylinderVolumesArrayInR(atlasVolumes) : 0;
+
+        // create the Atlas volume bounds
+        Trk::CylinderVolumeBounds* atlasBounds = new Trk::CylinderVolumeBounds(0., m_worldDimension[1], m_worldDimension[2]);
+
+        // create the Atlas TrackingVolume
+        Trk::TrackingVolume* atlasVolume = new Trk::TrackingVolume(0,
+                                                                   atlasBounds,
+                                                                   m_worldMaterial,
+                                                                   0,atlasVolumeArray,
+                                                                   "Atlas");
+
+        ATH_MSG_VERBOSE( "Atlas Tracking World volume built successfully." );
+
+
+        // glue the inner sector to be complete
+        m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerNegativeSector, Trk::positiveFaceXY,
+                                                      innerNegativeFaceVolumes, Trk::negativeFaceXY );
+
+        m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerPositiveSector, Trk::negativeFaceXY,
+                                                      innerPositiveFaceVolumes, Trk::positiveFaceXY );
+
+        ATH_MSG_VERBOSE( "Atlas Inner Sector glued successfully together." );
+
+        // iterators to the face volumes
+        auto volIter    = innerCentralFaceVolumes.begin();
+        auto volIterEnd = innerCentralFaceVolumes.end();
+
+        // glue outer and inner sector together
+        std::vector<const Trk::TrackingVolume*> atlasInnerOuterVolumes;
+        atlasInnerOuterVolumes.push_back(atlasInnerNegativeSector);
+        for ( ; volIter != volIterEnd; ++volIter)
+            if (*volIter) atlasInnerOuterVolumes.push_back(*volIter);
+        atlasInnerOuterVolumes.push_back(atlasInnerPositiveSector);
+
+        m_trackingVolumeHelper->glueTrackingVolumes(*atlasOuterSector, Trk::tubeInnerCover,
+                                                     atlasInnerOuterVolumes, Trk::tubeOuterCover);
+
+        ATH_MSG_VERBOSE( "Atlas Inner/Outer Sector glued successfully together." );
+
+        // job done -> create the TrackingGeometry
+        atlasTrackingGeometry.second = new Trk::TrackingGeometry(atlasVolume);
+
+        atlasTrackingGeometry.first = range;
+        
+        // detailed information about this tracking geometry
+        ATH_MSG_VERBOSE( "Atlas TrackingGeometry built with following parameters : ");
+        //ATH_MSG_VERBOSE( " - TrackingVolume containers            : " << atlasTrackingGeometry->numberOfContainerVolumes() );
+        //ATH_MSG_VERBOSE( " - TrackingVolume at navigation level   : " << atlasTrackingGeometry->numberOfContainerVolumes() );
+        //ATH_MSG_VERBOSE( " - Contained static layers              : " << atlasTrackingGeometry->boundaryLayers().size());        
+        ATH_MSG_VERBOSE( " - Unique material layers on boundaries : " << atlasTrackingGeometry.second->boundaryLayers().size());        
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+        m_memoryLogger.refresh(getpid());
+        ATH_MSG_INFO( "[ memory usage ] After Outer Sector TrackingGeometry building: "  );
+        ATH_MSG_INFO( m_memoryLogger );
+#endif
+
+    }
+
+    if (atlasTrackingGeometry.second) {
+        if (m_navigationLevel < 3)
+            atlasTrackingGeometry.second->registerNavigationLevel( Trk::NavigationLevel(m_navigationLevel));
+    }
+    else ATH_MSG_WARNING( "atlasTrackingGeometry() ... atlasTrackingGeometry = 0, could not call registerNavigationLevel and propagateMagneticFieldProperties" );
+
+#ifdef TRKDETDESCR_MEMUSAGE            
+    m_memoryLogger.refresh(getpid());
+    ATH_MSG_INFO( "[ memory usage ] End of TrackingGeometry building: "  );    
+    ATH_MSG_INFO( m_memoryLogger );                     
+#endif
+
+    // synchronize the layers
+    if (atlasTrackingGeometry.second) {
+    if (m_synchronizeLayers) atlasTrackingGeometry.second->synchronizeLayers(msg());
+
+    // compactify if configured to do so
+    if (m_compactify) atlasTrackingGeometry.second->compactify(msg());
+    }
+    return atlasTrackingGeometry;
+} 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx
index b17891b7150..f45dbb13139 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/InputLayerMaterialProvider.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -56,7 +56,7 @@ StatusCode Trk::InputLayerMaterialProvider::initialize() {
 }
 
 // Processor Action to work on TrackingGeometry 
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) const {
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -71,7 +71,7 @@ StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingGeometry&
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) const {
   
   std::stringstream displayBuffer;
   for (size_t il = 0; il < level; ++il) displayBuffer << " ";
@@ -118,7 +118,7 @@ StatusCode Trk::InputLayerMaterialProvider::process(const Trk::TrackingVolume& t
 }
 
 // Processor Action to work on Layers 
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Layer& lay, size_t level) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Layer& lay, size_t level) const {
     
     // skip Layers w/o material
     if (!lay.layerMaterialProperties()) 
@@ -142,7 +142,7 @@ StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Layer& lay, size_
 }
 
 // Processor Action to work on Surfaces 
-StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Surface&, size_t) {
+StatusCode Trk::InputLayerMaterialProvider::process(const Trk::Surface&, size_t) const {
     return StatusCode::SUCCESS;
 }
 
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx
index ecd20cec315..6054b6d539c 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerMaterialProvider.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -36,7 +36,7 @@ Trk::LayerMaterialProvider::~LayerMaterialProvider()
 
 
 // Processor Action to work on TrackingGeometry 
-StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo) const{
   
   ATH_MSG_VERBOSE("Start processing the TrackingGeometry recursively");
   // retrieve the highest tracking volume
@@ -81,14 +81,16 @@ StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingGeometry& tgeo
 }
 
 // Processor Action to work on TrackingVolumes
-StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol, size_t level) const {
   
   // load the material map if not done yet
-  if (!m_layerMaterialMap){ 
-      if (loadMaterialMap().isFailure()){
-            ATH_MSG_DEBUG( "Problems loading hte LayerMaterialMap - check name or call sequence." );
-            return StatusCode::FAILURE;
-      }
+  bool loadMapFailed = false;
+  std::call_once(m_loadMapOnceFlag, [&](){
+      loadMapFailed = loadMaterialMap().isFailure();
+  });
+  if (loadMapFailed){
+      ATH_MSG_DEBUG( "Problems loading the LayerMaterialMap - check name or call sequence." );
+      return StatusCode::FAILURE;
   }
   
   std::stringstream displayBuffer;
@@ -148,14 +150,16 @@ StatusCode Trk::LayerMaterialProvider::process(const Trk::TrackingVolume& tvol,
 }
 
 // Processor Action to work on Layers 
-StatusCode Trk::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::Layer& lay, size_t level) const {
 
     // load the material map if not done yet
-    if (!m_layerMaterialMap){ 
-        if (loadMaterialMap().isFailure()){
-              ATH_MSG_WARNING( "Problems loading the LayerMaterialMap - check name or call sequence." );
-              return StatusCode::FAILURE;
-        }
+    bool loadMapFailed = false;
+    std::call_once(m_loadMapOnceFlag, [&](){
+        loadMapFailed = loadMaterialMap().isFailure();
+    });
+    if (loadMapFailed){
+        ATH_MSG_DEBUG( "Problems loading the LayerMaterialMap - check name or call sequence." );
+        return StatusCode::FAILURE;
     }
     // is the pointer still null?
     if (!m_layerMaterialMap) {
@@ -190,12 +194,12 @@ StatusCode Trk::LayerMaterialProvider::process(const Trk::Layer& lay, size_t lev
 }
 
 // Processor Action to work on Surfaces 
-StatusCode Trk::LayerMaterialProvider::process(const Trk::Surface&, size_t) {
+StatusCode Trk::LayerMaterialProvider::process(const Trk::Surface&, size_t) const{
     return StatusCode::SUCCESS;
 }
 
 // load the material map from StoreGate
-StatusCode Trk::LayerMaterialProvider::loadMaterialMap() {
+StatusCode Trk::LayerMaterialProvider::loadMaterialMap() const {
     
     // -------------------------------------------------------------------------------
     if (detStore()->retrieve(m_layerMaterialMap, m_layerMaterialMapName).isFailure()){
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerProviderCond.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerProviderCond.cxx
new file mode 100644
index 00000000000..350c99121c5
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/LayerProviderCond.cxx
@@ -0,0 +1,114 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// LayerProviderCond.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// STL
+#include <sstream>
+// Trk include
+#include "TrkDetDescrTools/LayerProviderCond.h"
+#include "TrkDetDescrInterfaces/ILayerBuilderCond.h"
+#include "TrkGeometry/Layer.h"
+#include "TrkGeometry/CylinderLayer.h"
+#include "TrkGeometry/DiscLayer.h"
+
+// constructor
+Trk::LayerProviderCond::LayerProviderCond(const std::string& t, const std::string& n, const IInterface* p)
+: AthAlgTool(t,n,p)
+{
+    declareInterface<Trk::ILayerProviderCond>(this);
+    
+    // Name specification from outside
+    declareProperty("LayerBuilder", m_layerBuilder);
+    
+}
+
+// destructor
+Trk::LayerProviderCond::~LayerProviderCond()
+{}
+
+// initialize
+StatusCode Trk::LayerProviderCond::initialize()
+{
+    if (m_layerBuilder.retrieve().isFailure()){
+        ATH_MSG_WARNING("Could not retrieve layer builder");
+    }
+    return StatusCode::SUCCESS;
+}
+
+/** LayerBuilderCond interface method - returning the layers at negative side */
+std::pair<EventIDRange, const std::vector< const Trk::Layer*>  > Trk::LayerProviderCond::negativeLayers(const EventContext& ctx) const
+{
+    // this will fill the cache with positive layers
+    return discLayers(ctx, -1);
+}    
+
+/** LayerBuilderCond interface method - returning the central layers */
+std::pair<EventIDRange, const std::vector< const Trk::Layer* > > Trk::LayerProviderCond::centralLayers(const EventContext& ctx) const
+{
+    // central layers
+    std::vector< const Trk::Layer* >            cLayers;
+    // retrieving the cylinder layers from the layer builder
+    std::pair<EventIDRange, const std::vector< const Trk::CylinderLayer* >* >  cylinderLayersPair = m_layerBuilder->cylindricalLayers(ctx);
+    auto cylinderLayers = cylinderLayersPair.second;
+    // loop over it and push into the return vector;
+    if (cylinderLayers){
+        for (auto& cL : (*cylinderLayers))
+            cLayers.push_back(cL);
+    }
+    // memory cleanup
+    delete cylinderLayers;
+    // and return
+    return std::make_pair(cylinderLayersPair.first, cLayers);
+} 
+
+/** LayerBuilderCond interface method - returning the layers at negative side */
+std::pair<EventIDRange,const std::vector< const Trk::Layer*> > Trk::LayerProviderCond::positiveLayers(const EventContext& ctx) const
+{
+    // this will fill the cache with negative layers
+    return discLayers(ctx, 1);
+}
+
+/** LayerBuilderCond interface method - returning the layers at negative side */
+std::pair<EventIDRange, const std::vector< const Trk::Layer* > > Trk::LayerProviderCond::discLayers(const EventContext& ctx, int posneg) const
+{
+    // get the disc layers
+    std::vector < const Trk::Layer* >   dLayers;
+    // retrieving the cylinder layers from the layer builder
+    std::pair<EventIDRange, const std::vector<const Trk::DiscLayer*>*>  discLayersPair = m_layerBuilder->discLayers(ctx);
+    auto discLayers = discLayersPair.second;
+    // loop and fill either cache or dLayers
+    if (discLayers){
+        // loop over and push into the return/cache vector 
+        for (auto& dL : (*discLayers) ){
+            // get the center posituion 
+            double zpos = dL->surfaceRepresentation().center().z();
+            if (posneg > 0){
+                // configured to provide positive and cache negative
+                if (zpos > 0.) dLayers.push_back(dL);
+            } else {
+                // configured to provide negative and cache positive
+                if (zpos < 0.) dLayers.push_back(dL);
+            }
+        }
+    }
+    // memory cleanup
+    delete discLayers;
+    // and return
+    return std::make_pair(discLayersPair.first, dLayers);   
+}
+
+
+// finalize
+StatusCode Trk::LayerProviderCond::finalize()
+{
+    return StatusCode::SUCCESS;
+}
+
+const std::string& Trk::LayerProviderCond::identification() const
+{
+    return m_layerBuilder->identification();
+}
diff --git a/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx b/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx
index 0cff6b5e051..3a1fa376857 100644
--- a/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrTools/src/components/TrkDetDescrTools_entries.cxx
@@ -12,6 +12,10 @@
 #include "TrkDetDescrTools/TrackingVolumeArrayCreator.h"
 #include "TrkDetDescrTools/TrackingVolumeHelper.h"
 
+#include "TrkDetDescrTools/GeometryBuilderCond.h"
+#include "TrkDetDescrTools/GenericGeometryBuilderCond.h"
+#include "TrkDetDescrTools/LayerProviderCond.h"
+
 using namespace Trk;
 
 DECLARE_COMPONENT( CylinderVolumeCreator )
@@ -28,3 +32,6 @@ DECLARE_COMPONENT( InputLayerMaterialProvider )
 DECLARE_COMPONENT( TrackingVolumeArrayCreator )
 DECLARE_COMPONENT( TrackingVolumeHelper )
 
+DECLARE_COMPONENT( GeometryBuilderCond )
+DECLARE_COMPONENT( GenericGeometryBuilderCond )
+DECLARE_COMPONENT( LayerProviderCond )
diff --git a/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h b/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
index 02efbc103fc..71b577d0532 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
+++ b/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
@@ -60,6 +60,9 @@ namespace Trk {
     /** Give the GeometryBuilder friend rights */  
     friend class GeometryBuilder;
     friend class IGeometryBuilder;
+    
+    friend class GeometryBuilderCond;
+    friend class IGeometryBuilderCond;
   
     public :
       /** Constructor */
@@ -212,5 +215,8 @@ namespace Trk {
 } // end of namespace
 
 CLASS_DEF(Trk::TrackingGeometry, 167645219, 1)
+#include "AthenaKernel/CondCont.h" 
+CONDCONT_DEF( Trk::TrackingGeometry , 119021535 );
+
 
 #endif //TRKGEOMETRY_TRACKINGGEOMETRY_H
-- 
GitLab