diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h
index 0c5ab281e83407ac706a1be7d6138921583c834d..c73fd919b118d41a4d420b0aa586563c35a1c52d 100644
--- a/DDCore/include/DD4hep/Objects.h
+++ b/DDCore/include/DD4hep/Objects.h
@@ -309,6 +309,12 @@ namespace dd4hep {
     Property property(const char* name)  const;
     /// Access to tabular properties of the material
     Property property(const std::string& name)  const;
+    /// Access string property value from the material table
+    std::string propertyRef(const std::string& name, const std::string& default_value="");
+    /// Access to tabular properties of the material
+    double constProperty(const std::string& name)  const;
+    /// Access string property value from the material table
+    std::string constPropertyRef(const std::string& name, const std::string& default_value="");
 #endif
   };
 
diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h
index dcac69985616dacad84d572af3610e7040481828..68bad1fb27a01550756723b88037c9bee8a9a4f9 100644
--- a/DDCore/include/DD4hep/Volumes.h
+++ b/DDCore/include/DD4hep/Volumes.h
@@ -317,28 +317,24 @@ namespace dd4hep {
     Handle<NamedObject> sens_det;
     /// Reference to the reflected volume (or to the original volume for reflections)
     Handle<TGeoVolume>  reflected;
-    
+    /// Reference to properties
+    using Properties = std::map<std::string, std::string>;
+    std::unique_ptr<Properties> properties;
+
     /// Default destructor
     virtual ~VolumeExtension();
     /// Default constructor
     VolumeExtension();
     /// No move
     VolumeExtension(VolumeExtension&& copy) = delete;
-    /// No copy
-    VolumeExtension(const VolumeExtension& copy) = default;
+    /// Copy constructor
+    VolumeExtension(const VolumeExtension& copy);
     /// No move assignment
     VolumeExtension& operator=(VolumeExtension&& copy) = delete;
-    /// No copy assignment
-    VolumeExtension& operator=(const VolumeExtension& copy) = default;
+    /// Copy assignment
+    VolumeExtension& operator=(const VolumeExtension& copy);
     /// Copy the object
-    void copy(const VolumeExtension& c) {
-      magic      = c.magic;
-      region     = c.region;
-      limits     = c.limits;
-      vis        = c.vis;
-      sens_det   = c.sens_det;
-      referenced = c.referenced;
-    }
+    void copy(const VolumeExtension& c);
     /// TGeoExtension overload: Method called whenever requiring a pointer to the extension
     virtual TGeoExtension *Grab()  override;
     /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
@@ -688,6 +684,15 @@ namespace dd4hep {
     /// Access to the Volume material
     Material material() const;
 
+    /// Check for existence of properties
+    bool hasProperties()  const;
+
+    /// Add Volume property (name-value pair)
+    void addProperty(const std::string& nam, const std::string& val)  const;
+
+    /// Access property value. Returns default_value if the property is not present
+    std::string getProperty(const std::string& nam, const std::string& default_val="")  const;
+
     /// Auto conversion to underlying ROOT object
     operator TGeoVolume*() const {
       return m_element;
diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp
index 99bb8ede96b851d4f07cb9224237c0be8f7e4bf2..67b1ccc539562a8db17cf617c34a8b242053e576 100644
--- a/DDCore/src/Objects.cpp
+++ b/DDCore/src/Objects.cpp
@@ -266,6 +266,31 @@ Material::Property Material::property(const char* nam)  const    {
 Material::Property Material::property(const std::string& nam)  const   {
   return access()->GetMaterial()->GetProperty(nam.c_str());
 }
+
+/// Access string property value from the material table
+std::string Material::propertyRef(const std::string& name, const std::string& default_value)    {
+  auto* o = access()->GetMaterial();
+  const char* p = o->GetPropertyRef(name.c_str());
+  if ( p ) return p;
+  return default_value;
+}
+
+/// Access to tabular properties of the optical surface
+double Material::constProperty(const std::string& nam)  const   {
+  Bool_t err = kFALSE;
+  auto* o = access()->GetMaterial();
+  double value = o->GetConstProperty(nam.c_str(), &err);
+  if ( err != kTRUE ) return value;
+  throw runtime_error("Attempt to access non existing material const property: "+nam);
+}
+
+/// Access string property value from the material table
+std::string Material::constPropertyRef(const std::string& name, const std::string& default_value)    {
+  auto* o = access()->GetMaterial();
+  const char* p = o->GetConstPropertyRef(name.c_str());
+  if ( p ) return p;
+  return default_value;
+}
 #endif
 
 /// String representation of this object
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index 582428c600d460ab03d9812eba783550bafdd990..dd6e430f67ca3a6e83116975090955b5753df92b 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -528,6 +528,32 @@ VolumeExtension::~VolumeExtension() {
   DECREMENT_COUNTER;
 }
 
+/// Copy constructor
+VolumeExtension::VolumeExtension(const VolumeExtension& c)   {
+  this->copy(c);
+}
+
+/// Copy assignment
+VolumeExtension& VolumeExtension::operator=(const VolumeExtension& c)   {
+  this->copy(c);
+  return *this;
+}
+
+/// Copy the object
+void VolumeExtension::copy(const VolumeExtension& c) {
+  if ( this != &c )   {
+    magic      = c.magic;
+    region     = c.region;
+    limits     = c.limits;
+    vis        = c.vis;
+    sens_det   = c.sens_det;
+    referenced = c.referenced;
+    if ( c.properties )  {
+      properties = std::make_unique<Properties>(*c.properties);
+    }
+  }
+}
+
 /// TGeoExtension overload: Method called whenever requiring a pointer to the extension
 TGeoExtension* VolumeExtension::Grab()  {
   VolumeExtension* ext = const_cast<VolumeExtension*>(this);
@@ -647,7 +673,7 @@ bool Volume::isReflected()   const    {
 }
 
 /// Divide volume into subsections (See the ROOT manuloa for details)
-Volume Volume::divide(const std::string& divname, int iaxis, int ndiv,
+Volume Volume::divide(const string& divname, int iaxis, int ndiv,
                       double start, double step, int numed, const char* option)   {
   TGeoVolume* p = m_element;
   if ( p )  {
@@ -1229,6 +1255,39 @@ bool Volume::isSensitive() const {
   return _data(*this)->sens_det.isValid();
 }
 
+/// Check for existence of properties
+bool Volume::hasProperties()  const   {
+  return _data(*this)->properties.get() != nullptr;
+}
+
+/// Add Volume property (name-value pair)
+void Volume::addProperty(const string& nam, const string& val) const  {
+  auto* o = _data(*this);
+  if ( !o->properties.get() )   {
+    o->properties = make_unique<VolumeExtension::Properties>();
+  }
+  auto ip = o->properties->find(nam);
+  if ( ip == o->properties->end() )   {
+    o->properties->emplace(nam, val);
+    return;
+  }
+  except("Volume::addProperty", "Volume: '%s' Property '%s' is already set!",
+	 ptr()->GetName(), nam.c_str());
+}
+
+/// Access property value. Returns default_value if the property is not present
+string Volume::getProperty(const string& nam, const string& default_val)   const {
+  const auto* o = _data(*this);
+  if ( !o->properties.get() )   {
+    return default_val;
+  }
+  auto ip = o->properties->find(nam);
+  if ( ip == o->properties->end() )   {
+    return default_val;
+  }
+  return (*ip).second;
+}
+
 /// Constructor to be used when creating a new assembly object
 Assembly::Assembly(const string& nam) {
   m_element = _createTGeoVolumeAssembly(nam);
@@ -1255,7 +1314,7 @@ void VolumeMulti::verifyVolumeMulti()   {
 }
 
 /// Output mesh vertices to string
-std::string dd4hep::toStringMesh(PlacedVolume place, int prec)   {
+string dd4hep::toStringMesh(PlacedVolume place, int prec)   {
   Volume       vol   = place->GetVolume();
   TGeoMatrix*  mat   = place->GetMatrix();
   Solid        sol   = vol.solid();
diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index 131ce83c0b7d2d8d52f2fbec320ad0cdc13a0db6..b7fb67e7ee346a76ce78f7d661c38a3e5e2cd9ad 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -518,6 +518,14 @@ template <> void Converter<Material>::operator()(xml_h e) const {
                  "++            material %-16s  add constant property: %s  ->  %s.",
                  mat->GetName(), prop_nam.c_str(), ref.c_str());
       }
+      else if ( p.hasAttr(_U(option)) )   {
+        string prop_nam = p.attr<string>(_U(name));
+	string prop_typ = p.attr<string>(_U(option));
+        mat->AddConstProperty(prop_nam.c_str(), prop_typ.c_str());
+        printout(s_debug.materials ? ALWAYS : DEBUG, "Compact",
+                 "++            material %-16s  add constant property: %s  ->  %s.",
+                 mat->GetName(), prop_nam.c_str(), prop_typ.c_str());
+      }
     }
     /// In case there were material properties specified: convert them here
     for(xml_coll_t properties(x_mat, _U(property)); properties; ++properties) {
diff --git a/DDG4/include/DDG4/Factories.h b/DDG4/include/DDG4/Factories.h
index 3e87259e12da8faf0484b36a34b0b7f2e65b9bd7..e5094c385f4c690fb2c84861869631866e1f48cf 100644
--- a/DDG4/include/DDG4/Factories.h
+++ b/DDG4/include/DDG4/Factories.h
@@ -25,6 +25,10 @@
 #include <map>
 
 // Forward declarations
+class TGeoVolume;
+class G4VSolid;
+class G4Material;
+class G4LogicalVolume;
 class G4ParticleDefinition;
 class G4VSensitiveDetector;
 class G4MagIntegratorStepper;
@@ -40,6 +44,8 @@ class G4VProcess;
 namespace dd4hep {
 
   class DetElement;
+  class Material;
+  class Volume;
   class Detector;
 
   /// Namespace for implementation details of the AIDA detector description toolkit
@@ -69,6 +75,18 @@ namespace dd4hep {
     static G4VSensitiveDetector* create(const str_t& name, dd4hep::Detector& description);
   };
 
+  /// Templated factory method to G4ExtendedMaterial objects
+  template <typename T> class Geant4MaterialFactory : public PluginFactoryBase {
+  public:
+    static G4Material* create(dd4hep::Detector& description, dd4hep::Material mat, G4Material* base_material);
+  };
+
+  /// Templated factory method to G4ExtendedMaterial objects
+  template <typename T> class Geant4LogicalVolumeFactory : public PluginFactoryBase {
+  public:
+    static G4LogicalVolume* create(dd4hep::Detector& description, dd4hep::Volume vol, G4VSolid* sol, G4Material* mat);
+  };
+
 }
 
 namespace {
@@ -89,13 +107,22 @@ namespace {
     ret = result;
     return long(&ret);
   }
+
+  /// Factory to create "special" Geant4 logical volumes
+  DD4HEP_PLUGIN_FACTORY_ARGS_4(G4LogicalVolume*,dd4hep::Detector*,dd4hep::Volume,G4VSolid*,G4Material*)
+  {    return dd4hep::Geant4LogicalVolumeFactory<P>::create(*a0, a1, a2, a3);  }
+
+  /// Factory to create Geant4 extended materials
+  DD4HEP_PLUGIN_FACTORY_ARGS_3(G4Material*,dd4hep::Detector*,dd4hep::Material,G4Material*)
+  {    return dd4hep::Geant4MaterialFactory<P>::create(*a0,a1,a2);             }
+
   /// Factory to create Geant4 sensitive detectors
   DD4HEP_PLUGIN_FACTORY_ARGS_2(G4VSensitiveDetector*,std::string,dd4hep::Detector*)
-  {    return dd4hep::Geant4SensitiveDetectorFactory<P>::create(a0,*a1);  }
+  {    return dd4hep::Geant4SensitiveDetectorFactory<P>::create(a0,*a1);       }
 
   /// Factory to create Geant4 sensitive detectors
   DD4HEP_PLUGIN_FACTORY_ARGS_4(DS::Geant4Sensitive*,_ns::CT*,std::string,dd4hep::DetElement*,dd4hep::Detector*)
-  {    return new P(a0, a1, *a2, *a3);  }
+  {    return new P(a0, a1, *a2, *a3);                                         }
 
   /// Factory to create Geant4 action objects
   DD4HEP_PLUGIN_FACTORY_ARGS_2(DS::Geant4Action*,_ns::CT*, std::string)
@@ -158,9 +185,22 @@ namespace {
 #define DECLARE_GEANT4SENSITIVEDETECTOR(id)               __IMPLEMENT_GEANT4SENSDET(id,new id)
 #define DECLARE_GEANT4SENSITIVEDETECTOR_NS(ns,id)         __IMPLEMENT_GEANT4SENSDET(id,new ns::id)
 
+#define DECLARE_GEANT4EXTENDEDMATERIAL(name)               \
+  DD4HEP_PLUGINSVC_FACTORY(name,name,G4Material*(dd4hep::Detector*,dd4hep::Material,G4Material*),__LINE__)
+
+#define DECLARE_GEANT4EXTENDEDMATERIAL_NS(ns,name)    using name_space::name; \
+  DD4HEP_PLUGINSVC_FACTORY(name,name,G4Material*(dd4hep::Detector*,dd4hep::Material,G4Material*),__LINE__)
+
+#define DECLARE_GEANT4LOGICALVOLUME(name)               \
+  DD4HEP_PLUGINSVC_FACTORY(name,name,G4LogicalVolume*(dd4hep::Detector*,dd4hep::Volume,G4VSolid*,G4Material*),__LINE__)
 
-#define DECLARE_GEANT4SENSITIVE_NS(name_space,name) using name_space::name; \
+#define DECLARE_GEANT4LOGICALVOLUME_NS(ns,name)    using name_space::name; \
+  DD4HEP_PLUGINSVC_FACTORY(name,name,G4LogicalVolume*(dd4hep::Detector*,dd4hep::Volume,G4VSolid*,G4Material*),__LINE__)
+
+
+#define DECLARE_GEANT4SENSITIVE_NS(name_space,name)  using name_space::name; \
   DD4HEP_PLUGINSVC_FACTORY(name,name,DS::Geant4Sensitive*(_ns::CT*,std::string,dd4hep::DetElement*,dd4hep::Detector*),__LINE__)
+
 #define DECLARE_GEANT4SENSITIVE(name)      DECLARE_GEANT4SENSITIVE_NS(dd4hep::sim,name)
 
 /// Plugin defintion to create Geant4Action objects
diff --git a/DDG4/include/DDG4/Geant4FastSimHandler.h b/DDG4/include/DDG4/Geant4FastSimHandler.h
index dc63d7ff9d2c67f2668dc4db88b1fcea8d4887fb..1a8091e331402126ff631db8129176683be6a44e 100644
--- a/DDG4/include/DDG4/Geant4FastSimHandler.h
+++ b/DDG4/include/DDG4/Geant4FastSimHandler.h
@@ -48,9 +48,9 @@ namespace dd4hep {
       Geant4FastSimHandler() = delete;
       /// Initializing constructor
       Geant4FastSimHandler(const Geant4FastSimSpot* sp)
-	: Geant4HitHandler(sp->primary, sp->touchable), spot(sp) 
-	{
-	}
+	: Geant4HitHandler(sp->primary, sp->touchable), spot(sp)
+      {
+      }
       /// No copy constructor
       Geant4FastSimHandler(const Geant4FastSimHandler& copy) = delete;
       /// No move constructor
diff --git a/DDG4/include/DDG4/Geant4HitHandler.h b/DDG4/include/DDG4/Geant4HitHandler.h
index 23bccaa86b5dd5c3b5eb795b3406a72cce3fb5a6..8f8ffccf3f531b7f4857f2a4a71cb5657ce15b85 100644
--- a/DDG4/include/DDG4/Geant4HitHandler.h
+++ b/DDG4/include/DDG4/Geant4HitHandler.h
@@ -40,6 +40,7 @@ namespace dd4hep {
      *  \ingroup DD4HEP_SIMULATION
      */
     class Geant4HitHandler {
+    protected:
     public:
       const G4Track* track;
       const G4VTouchable* touchable_ptr;
diff --git a/DDG4/include/DDG4/Geant4StepHandler.h b/DDG4/include/DDG4/Geant4StepHandler.h
index 27d0ab957351627c05818fb1dab2534d5e4a8c66..57590aa3f1ea878923e82851f9774b654f838b9b 100644
--- a/DDG4/include/DDG4/Geant4StepHandler.h
+++ b/DDG4/include/DDG4/Geant4StepHandler.h
@@ -54,10 +54,8 @@ namespace dd4hep {
       /// Initializing constructor
       Geant4StepHandler(const G4Step* s)
 	: Geant4HitHandler(s->GetTrack(), (s->GetPreStepPoint()->GetTouchableHandle())()),
-	step(s)
+	step(s), pre(s->GetPreStepPoint()), post(s->GetPostStepPoint())
       {
-        pre = s->GetPreStepPoint();
-        post = s->GetPostStepPoint();
         applyBirksLaw = false;
       }
       /// No copy constructor
diff --git a/DDG4/plugins/Geant4.10.PhysicsConstructors.h b/DDG4/plugins/Geant4.10.PhysicsConstructors.h
index c334f6fe938eda64eb47da4a4d0779ccb2814070..d6cf18958d44c668348e1a77077f36ca14405f5c 100644
--- a/DDG4/plugins/Geant4.10.PhysicsConstructors.h
+++ b/DDG4/plugins/Geant4.10.PhysicsConstructors.h
@@ -111,4 +111,38 @@ DECLARE_GEANT4_PHYSICS(G4OpticalPhysics)
 #include <G4FastSimulationPhysics.hh>
 DECLARE_GEANT4_PHYSICS(G4FastSimulationPhysics)
 
+// Channeling physics 
+#include <G4Channeling.hh>
+#include <G4ProcessManager.hh>
+namespace {
+
+  /// Channeling physics 
+  /** Channeling physicsconstructor
+   *  (taken from <Geant4>examples/extended/exoticphysics/channeling)
+   *  \author  M.Frank
+   *  \version 1.0
+   */
+  class Geant4ChannelingPhysics : public G4VPhysicsConstructor  {
+  public:
+    Geant4ChannelingPhysics() = default;
+    virtual ~Geant4ChannelingPhysics() = default;
+    virtual void ConstructParticle()  {}
+    virtual void ConstructProcess()   {
+      G4Channeling* channeling = new G4Channeling();
+      auto* iter = G4ParticleTable::GetParticleTable()->GetIterator();
+      iter->reset();
+    
+      while( (*iter)() ){
+        G4ParticleDefinition* p = iter->value();
+        G4double charge = p->GetPDGCharge();
+        if (charge != 0) {
+	  G4ProcessManager* m = p->GetProcessManager();
+	  m->AddDiscreteProcess(channeling);
+        }
+      }
+    }
+  };
+}
+DECLARE_GEANT4_PHYSICS(Geant4ChannelingPhysics)
+
 #endif
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index 1c10dbb27da145550fb6521de19057d330527f27..629d5e19cc975248ac7f1fcffa4daf8a01ea9b61 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -85,6 +85,7 @@ using namespace std;
 
 static constexpr const double CM_2_MM = (CLHEP::centimeter/dd4hep::centimeter);
 static constexpr const char* GEANT4_TAG_IGNORE = "Geant4-ignore";
+static constexpr const char* GEANT4_TAG_PLUGIN = "Geant4-plugin";
 
 namespace {
   static string indent = "";
@@ -301,10 +302,10 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
   Geant4GeometryInfo& info = data();
   G4Material*         mat  = info.g4Materials[medium];
   if ( !mat )  {
-    PrintLevel lvl = debugMaterials ? ALWAYS : outputLevel;
+    PrintLevel    lvl      = debugMaterials ? ALWAYS : outputLevel;
     TGeoMaterial* material = medium->GetMaterial();
-    G4State state   = kStateUndefined;
-    double  density = material->GetDensity() * (CLHEP::gram / CLHEP::cm3);
+    G4State       state    = kStateUndefined;
+    double        density  = material->GetDensity() * (CLHEP::gram / CLHEP::cm3);
     if ( density < 1e-25 )
       density = 1e-25;
     switch ( material->GetState() ) {
@@ -353,6 +354,7 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
       mat = new G4Material(name, z, a, density, state, 
                            material->GetTemperature(), material->GetPressure());
     }
+    string plugin_name;
 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,17,0)
     /// Attach the material properties if any
     G4MaterialPropertiesTable* tab = 0;
@@ -415,6 +417,7 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
         printout(lvl, name, "  Geant4: %s %8.3g [MeV]  TGeo: %8.3g [GeV] Conversion: %8.3g",
                  named->GetName(), bins[i], v->bins[i], conv.first);
     }
+
     /// Attach the material properties if any
     TListIter cpropIt(&material->GetConstProperties());
     for(TObject* obj=cpropIt.Next(); obj; obj = cpropIt.Next())  {
@@ -434,6 +437,14 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
                  named->GetName(), named->GetTitle());
         continue;
       }
+      cptr = ::strstr(named->GetName(), GEANT4_TAG_PLUGIN);
+      if ( 0 != cptr )   {
+        printout(INFO, name, "++ Ignore CONST property %s [%s]  --> Plugin.",
+                 named->GetName(), named->GetTitle());
+	plugin_name = named->GetTitle();
+        continue;
+      }
+
       double v = info.manager->GetProperty(named->GetTitle(),&err);
       if ( err != kFALSE )   {
         except(name,
@@ -476,6 +487,15 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
     else
       str << "              log(MEE): UNKNOWN";
     printout(lvl, name, "++ Created G4 material %s", str.str().c_str());
+    if ( !plugin_name.empty() )    {
+      /// Call plugin to create extended material if requested
+      Detector* det = const_cast<Detector*>(&m_detDesc);
+      G4Material* extended_mat = PluginService::Create<G4Material*>(plugin_name, det, medium, mat);
+      if ( !extended_mat )   {
+	except("G4Cnv::material["+name+"]","++ FATAL Failed to call plugin to create material.");
+      }
+      mat = extended_mat;
+    }
     info.g4Materials[medium] = mat;
   }
   return mat;
@@ -670,14 +690,29 @@ void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume
                lim.name(), _v.name());
     }
 
-    G4VisAttributes* vattr = vis.isValid() ? (G4VisAttributes*)handleVis(vis.name(), vis) : nullptr;
-    G4LogicalVolume* g4vol = new G4LogicalVolume(solid, medium, n, 0, 0, limits);
+    G4LogicalVolume* g4vol = nullptr;
+    if ( _v.hasProperties() && !_v.getProperty(GEANT4_TAG_PLUGIN,"").empty() )   {
+      Detector* det = const_cast<Detector*>(&m_detDesc); 
+      string plugin = _v.getProperty(GEANT4_TAG_PLUGIN,"");
+      g4vol = PluginService::Create<G4LogicalVolume*>(plugin, det, _v, solid, medium);
+      if ( !g4vol )    {
+	except("G4Cnv::volume["+name+"]","++ FATAL Failed to call plugin to create logical volume.");
+      }
+    }
+    else  {
+      g4vol = new G4LogicalVolume(solid, medium, n, nullptr, nullptr, nullptr);
+    }
+
+    if ( limits )   {
+      g4vol->SetUserLimits(limits);
+    }
     if ( region )   {
       printout(lvl, "Geant4Converter", "++ Volume     + Apply REGION settings: %s to volume %s.",
                reg.name(), _v.name());
       g4vol->SetRegion(region);
       region->AddRootLogicalVolume(g4vol);
     }
+    G4VisAttributes* vattr = vis.isValid() ? (G4VisAttributes*)handleVis(vis.name(), vis) : nullptr;
     if ( vattr )   {
       g4vol->SetVisAttributes(vattr);
     }
diff --git a/examples/ClientTests/src/SingleShape_geo.cpp b/examples/ClientTests/src/SingleShape_geo.cpp
index d478b2a80bb67b20fdaa3f7038b7078d2e2917e3..c6b556ff0b6aad0b468ced72d3565247f668fc41 100644
--- a/examples/ClientTests/src/SingleShape_geo.cpp
+++ b/examples/ClientTests/src/SingleShape_geo.cpp
@@ -23,7 +23,6 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s
   xml_comp_t xshape (x_det.child(_U(shape)));
   xml_dim_t  xpos   (x_det.child(_U(position), false));
   xml_elt_t  xmat   (x_det.child(_U(material)));
-  xml_dim_t  xshpos (xshape.child(_U(position)));
   xml_dim_t  xbox   (x_det.child(_U(box)));
   DetElement d_det(x_det.nameStr(),x_det.id());
   Volume assembly(x_det.nameStr()+"_vol", Box(xbox.x(), xbox.y(), xbox.z()), description.air());
@@ -34,12 +33,24 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s
   Volume vol = Volume(x_det.nameStr()+"_vol", sh, mat);
   PlacedVolume pv;
 
+  for(xml_coll_t c(xshape,_U(property)); c; ++c)   {
+    xml_elt_t ec = c;
+    vol.addProperty(ec.attr<std::string>(_U(name)), ec.attr<std::string>(_U(value)));
+  }
+
   sens.setType("calorimeter");
   vol.setVisAttributes(description, x_det.visStr());
   vol.setSensitiveDetector(sens);
-  
+
+  int ipos = 0;
+  for(xml_coll_t c(xshape, _U(position)); c; ++c)   {
+    xml_dim_t  xp = c;
+    Position   vol_pos(xp.x(), xp.y(), xp.z());
+    pv = assembly.placeVolume(vol, vol_pos);
+    pv.addPhysVolID("module", ++ipos);
+  }
+
   assembly.setVisAttributes(description, xbox.attr<std::string>(_U(vis)));
-  assembly.placeVolume(vol,Position(xshpos.x(),xshpos.y(),xshpos.z()));
   pv = description.pickMotherVolume(d_det).placeVolume(assembly, pos);
   pv.addPhysVolID("system",x_det.id());
   d_det.setPlacement(pv);
diff --git a/examples/DDG4/CMakeLists.txt b/examples/DDG4/CMakeLists.txt
index dd5273d58875c5b95cc805baed44d8bb1b212d1b..ddeac00ec5d4cc6b1a49cea6eaddc73cfb1820f6 100644
--- a/examples/DDG4/CMakeLists.txt
+++ b/examples/DDG4/CMakeLists.txt
@@ -45,6 +45,7 @@ if (DD4HEP_USE_GEANT4)
   #
   #
   dd4hep_install_dir(data    DESTINATION ${CMAKE_INSTALL_PREFIX}/examples/DDG4 )
+  dd4hep_install_dir(compact DESTINATION ${CMAKE_INSTALL_PREFIX}/examples/DDG4 )
   dd4hep_install_dir(scripts DESTINATION ${CMAKE_INSTALL_PREFIX}/examples/DDG4 )
   #
   dd4hep_configure_scripts (DDG4 DEFAULT_SETUP WITH_TESTS)