diff --git a/DDCore/include/DD4hep/Factories.h b/DDCore/include/DD4hep/Factories.h
index e2fac36a798c7b239c3ec50dc41ef501e4d123af..161f7b0090f5f8e16c36a90a5456dc817fdeb779 100644
--- a/DDCore/include/DD4hep/Factories.h
+++ b/DDCore/include/DD4hep/Factories.h
@@ -62,6 +62,18 @@ namespace DD4hep {
       static Ref_t create(LCDD& lcdd, const XML::Handle_t& e);
     };
 
+    /** @class XMLDocumentReaderFactory Factories.h DDCore/Factories.h
+     *  Read an arbitrary XML document and analyze it's content
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     *  @date    2012/07/31
+     */
+    template <typename T> class XMLDocumentReaderFactory  {
+    public:
+      static long create(LCDD& lcdd, const XML::Handle_t& e);
+    };
+
     /** @class DetElementFactory Factories.h DDCore/Factories.h
      *  Standard factory to create Detector elements from the compact
      *  XML representation.
@@ -104,6 +116,19 @@ namespace {
   };
 
 
+  template < typename P > class Factory<P, long(DD4hep::Geometry::LCDD*,const DD4hep::XML::Handle_t*)> {
+  public:
+    typedef DD4hep::Geometry::LCDD  LCDD;
+    typedef DD4hep::XML::Handle_t   xml_h;
+    static void Func(void *retaddr, void*, const std::vector<void*>& arg, void*) {
+      LCDD*  lcdd = (LCDD* )arg[0];
+      xml_h* elt  = (xml_h*)arg[1];
+      long ret = DD4hep::Geometry::XMLDocumentReaderFactory<P>::create(*lcdd,*elt);
+      new(retaddr) (long)(ret);
+    }
+  };
+
+
   template < typename P > class Factory<P, TNamed*(DD4hep::Geometry::LCDD*,const DD4hep::XML::Handle_t*,DD4hep::Geometry::SensitiveDetector*)> {
   public:
     typedef DD4hep::Geometry::LCDD  LCDD;
@@ -117,6 +142,8 @@ namespace {
       *(void**)retaddr = handle.ptr();
     }
   };
+
+
 }
 
 #define DECLARE_DETELEMENT_FACTORY(x) \
@@ -142,6 +169,12 @@ namespace {
   template <> Ref_t XMLElementFactory<xml_element_##name>::create(LCDD& l,const XML::Handle_t& e) {return func(l,e);} }}\
   PLUGINSVC_FACTORY_WITH_ID(xml_element_##name,std::string(#name),TNamed*(DD4hep::Geometry::LCDD*,const DD4hep::XML::Handle_t*))
 
+#define DECLARE_XML_DOC_READER(name,func) \
+  namespace DD4hep { namespace Geometry { namespace { struct xml_document_##name {}; }               \
+  using DD4hep::Geometry::xml_document_##name;					                     \
+  template <> long XMLDocumentReaderFactory<xml_document_##name>::create(LCDD& l,const XML::Handle_t& e) {return func(l,e);} }}\
+  PLUGINSVC_FACTORY_WITH_ID(xml_document_##name,std::string(#name "_XML_reader"),long(DD4hep::Geometry::LCDD*,const DD4hep::XML::Handle_t*))
+
 #define DECLARE_DETELEMENT(name,func) \
   namespace DD4hep { namespace Geometry { namespace { struct det_element_##name {}; }                                       \
   using DD4hep::Geometry::det_element_##name;                                                                               \
diff --git a/DDCore/include/DD4hep/FieldTypes.h b/DDCore/include/DD4hep/FieldTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..54f1f118e903b9a26060c2060b4af0e90516ee98
--- /dev/null
+++ b/DDCore/include/DD4hep/FieldTypes.h
@@ -0,0 +1,90 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#ifndef DD4HEP_GEOMETRY_FIELDTYPES_H
+#define DD4HEP_GEOMETRY_FIELDTYPES_H
+
+// Framework include files
+#include "DD4hep/Fields.h"
+#include <vector>
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geoemtry namespace declaration
+   */
+  namespace Geometry  {
+
+    /** @class ConstantField FieldTypes.h
+     *  
+     *  Generic constant uniform field
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    class ConstantField : public CartesianField::Object {
+    public:
+      /// Field direction
+      Direction direction;
+    public:
+      /// Initializing constructor
+      ConstantField() : direction() { }
+      /// Call to access the field components at a given location
+      virtual void fieldComponents(const double* /* pos */, double* field);
+    };
+
+    /** @class SolenoidField FieldTypes.h DD4hep/FieldTypes.h
+     *  
+     *  Generic solonoid magnetic field
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    class SolenoidField : public CartesianField::Object {
+    public:
+      double innerField;
+      double outerField;
+      double minZ;
+      double maxZ;
+      double innerRadius;
+      double outerRadius;
+
+    public:
+      /// Initializing constructor
+      SolenoidField();
+      /// Call to access the field components at a given location
+      virtual void fieldComponents(const double* pos, double* field);
+    };
+
+    /** @class DipoleField FieldTypes.h DD4hep/FieldTypes.h
+     *  
+     *  Generic solonoid magnetic field
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    class DipoleField  : public CartesianField::Object  {
+    public:
+      double              zmax;
+      double              zmin;
+      double              rmax;
+      std::vector<double> coefficents;
+    public:
+      /// Initializing constructor
+      DipoleField();
+      /// Call to access the field components at a given location
+      virtual void fieldComponents(const double* pos, double* field);
+    };
+
+  }       /* End namespace Geometry           */
+}         /* End namespace DD4hep             */
+#endif    /* DD4HEP_GEOMETRY_FIELDTYPES_H     */
diff --git a/DDCore/include/DD4hep/Fields.h b/DDCore/include/DD4hep/Fields.h
new file mode 100644
index 0000000000000000000000000000000000000000..e859078829b00064616b70e207c36897ea2c0c5c
--- /dev/null
+++ b/DDCore/include/DD4hep/Fields.h
@@ -0,0 +1,203 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#ifndef DD4HEP_GEOMETRY_FIELDS_H
+#define DD4HEP_GEOMETRY_FIELDS_H
+
+// Framework include files
+#include "DD4hep/Objects.h"
+
+// C/C++ include files
+#include <vector>
+#include <map>
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geoemtry namespace declaration
+   */
+  namespace Geometry  {
+
+    /** @class CartesianField Fields.h
+     *  
+     *  Generic structure describing any field type (electric or magnetic)
+     *  with field components in Cartesian coordinates.
+     *
+     *  The actual behaviour is solely implemented in the underlying object
+     *  class.
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    struct CartesianField : public Ref_t {
+      enum FieldType { UNKNOWN=0, ELECTRIC=0x1, MAGNETIC=0x2 };
+      typedef std::map<std::string,std::string> PropertyValues;
+      typedef std::map<std::string,PropertyValues>  Properties;
+
+      /// Internal data class shared by all handles of a given type
+      struct Object {
+	/// Field type
+	int type;
+	/// Field extensions
+	Properties properties;
+	/// Default constructor
+	Object() : type(UNKNOWN) {}
+	/// Call to access the field components at a given location
+	virtual void fieldComponents(const double* pos, double* field) = 0;
+      };
+
+      /// Default constructor
+      CartesianField() : Ref_t() {}
+
+      /// Constructor to be used when reading the already parsed DOM tree
+      CartesianField(const CartesianField& e) : Ref_t(e)  {}
+
+      /// Constructor to be used when reading the already parsed DOM tree
+      template <typename Q> CartesianField(const Handle<Q>& e) : Ref_t(e)  {}
+
+      /// Access the field type
+      int fieldType()  const {  return data<Object>()->type; }
+
+      /// Access the field type (string)
+      const char* type() const;
+
+      /// Does the field change the energy of charged particles?
+      bool changesEnergy() const;
+
+      /// Returns the 3 field components (x, y, z).
+      void value(const Position& pos, Direction& field) const { value(pos,&field.x); }
+
+      /// Returns the 3 field components (x, y, z).
+      void value(const Position& pos, double* val) const      { value(&pos.x,val);   }
+
+      /// Returns the 3 field components (x, y, z).
+      void value(const double* pos, double* val)   const;
+
+      /// Access to properties container
+      Properties& properties()  const;
+    };
+
+    typedef CartesianField ElectricField;
+    typedef CartesianField MagneticField;
+
+
+    /** @class OverlayedField Fields.h
+     *  
+     *  Generic structure describing any field type (electric or magnetic)
+     *  with field components in Cartesian coordinates.
+     *
+     *  The actual behaviour is solely implemented in the underlying object
+     *  class.
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    struct OverlayedField : public Ref_t {
+      enum FieldType { ELECTRIC=0x1, MAGNETIC=0x2 };
+      typedef std::map<std::string,std::string> PropertyValues;
+      typedef std::map<std::string,PropertyValues>  Properties;
+
+      struct Object   {
+	int                          type;
+	CartesianField               electric;
+	CartesianField               magnetic;
+	std::vector<CartesianField>  electric_components;
+	std::vector<CartesianField>  magnetic_components;
+	/// Field extensions
+	Properties                   properties;
+	Object() : type(0), electric(), magnetic() {}
+      };
+
+      /// Default constructor
+      OverlayedField() : Ref_t() {}
+
+      /// Constructor to be used when reading the already parsed DOM tree
+      template <typename Q> 
+      OverlayedField(const Handle<Q>& e) : Ref_t(e)  {}
+
+      /// Object constructor
+      OverlayedField(const std::string& name);
+
+      /// Access the field type
+      int type()  const {  return data<Object>()->type; }
+
+      /// Does the field change the energy of charged particles?
+      bool changesEnergy() const;
+
+      /// Add a new field component
+      void add(CartesianField field);
+
+      /// Returns the 3 electric field components (x, y, z) if many components are present
+      void combinedElectric(const Position& pos, double* field)  const  {
+	combinedElectric(&pos.x,field);
+      }
+
+      /// Returns the 3 electric field components (x, y, z) if many components are present
+      void combinedElectric(const double* pos, double* field) const;
+
+      /// Returns the 3 magnetic field components (x, y, z) if many components are present
+      void combinedMagnetic(const Position& pos, double* field)  const  {
+	combinedMagnetic(&pos.x,field);
+      }
+
+      /// Returns the 3 magnetic field components (x, y, z) if many components are present
+      void combinedMagnetic(const double* pos, double* field)  const;
+
+      /// Returns the 3 electric field components (x, y, z).
+      void electricField(const Position& pos, Direction& field)   const   {
+	electricField(&pos.x, &field.x);
+      }
+
+      /// Returns the 3 electric field components (x, y, z).
+      void electricField(const Position& pos, double* field)    const     {
+	electricField(&pos.x, field);
+      }
+
+      /// Returns the 3 electric field components (x, y, z).
+      void electricField(const double* pos, double* field)     const    {
+	CartesianField f = data<Object>()->electric;
+	f.isValid() ? f.value(pos,field) : combinedElectric(pos,field);
+      }
+
+      /// Returns the 3 magnetic field components (x, y, z).
+      void magneticField(const Position& pos, Direction& field)   const   {
+	magneticField(&pos.x, &field.x);
+      }
+
+      /// Returns the 3  magnetic field components (x, y, z).
+      void magneticField(const Position& pos, double* field)    const     {
+	magneticField(&pos.x, field);
+      }
+
+      /// Returns the 3  magnetic field components (x, y, z).
+      void magneticField(const double* pos, double* field)     const    {
+	CartesianField f = data<Object>()->magnetic;
+	f.isValid() ? f.value(pos,field) : combinedMagnetic(pos,field);
+      }
+
+      /// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]).
+      void electromagneticField(const Position& pos, double* val)  const   {
+	electromagneticField(&pos.x,val);
+      }
+
+      /// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]).
+      void electromagneticField(const double* pos, double* val)   const;
+
+      /// Access to properties container
+      Properties& properties()  const;
+    };
+
+    typedef OverlayedField ElectroMagneticField;
+
+  }       /* End namespace Geometry           */
+}         /* End namespace DD4hep             */
+#endif    /* DD4HEP_GEOMETRY_FIELDS_H         */
diff --git a/DDCore/include/DD4hep/GeoHandler.h b/DDCore/include/DD4hep/GeoHandler.h
index 11e037d1e229fa4e8ba88a542d1066cb024069b4..63486c6b5f7e130716ccfc0f766f47359ac4f53e 100644
--- a/DDCore/include/DD4hep/GeoHandler.h
+++ b/DDCore/include/DD4hep/GeoHandler.h
@@ -48,6 +48,7 @@ namespace DD4hep {
       typedef std::map<const TNamed*,ConstVolumeSet>             LimitVolumes;
       typedef std::map<int, std::set<const TGeoNode*> >          Data;
       typedef std::set<TNamed*>                                  VisRefs;
+      typedef std::set<TNamed*>                                  Fields;
       typedef LCDD::HandleMap                                    DefinitionSet;
 
       typedef Geometry::LCDD              LCDD;
@@ -61,6 +62,7 @@ namespace DD4hep {
 	VolumeSet          volumes;
 	TransformSet       trafos;
 	VisRefs            vis;
+	Fields             fields;
 	MaterialSet        materials;
 	// SensitiveVolumes   sensitives;
 	// RegionVolumes      regions;
diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h
index 0441804bd1a1cffa2e40b463e20a43034f8579c6..b5efb49dcdb46167219b8a05690581774e5dc0e1 100644
--- a/DDCore/include/DD4hep/Handle.h
+++ b/DDCore/include/DD4hep/Handle.h
@@ -56,19 +56,43 @@ namespace DD4hep {
     
     bool           _toBool  (const std::string& value);
     int            _toInt   (const std::string& value);
+    long           _toLong  (const std::string& value);
     float          _toFloat (const std::string& value);
     double         _toDouble(const std::string& value);
     
     inline bool    _toBool(bool value)       {  return value; }
     inline int     _toInt(int value)         {  return value; }
+    inline long    _toLong(long value)       {  return value; }
     inline float   _toFloat(float value)     {  return value; }
     inline double  _toDouble(double value)   {  return value; }
 
+    template<class T> T _multiply(const std::string& left, T right);
+    template<class T> T _multiply(T left, const std::string& right);
     template<class T> T _multiply(const std::string& left, const std::string& right);
-    template <> int    _multiply<int>(const std::string& left, const std::string& right);
-    template <> long   _multiply<long>(const std::string& left, const std::string& right);
-    template <> float  _multiply<float>(const std::string& left, const std::string& right);
-    template <> double _multiply<double>(const std::string& left, const std::string& right);
+
+    template <>        int     _multiply<int>(const std::string& left, const std::string& right);
+    template <> inline int     _multiply<int>(int left, const std::string& right)
+      { return left * _toInt(right);    }
+    template <> inline int     _multiply<int>(const std::string& left, int right)
+      { return _toInt(left) * right;    }
+
+    template <>        long    _multiply<long>(const std::string& left, const std::string& right);
+    template <> inline long    _multiply<long>(long left, const std::string& right)
+      { return left * _toLong(right);   }
+    template <> inline long    _multiply<long>(const std::string& left, long right)
+      { return _toLong(left) * right;   }
+
+    template <>        float   _multiply<float>(const std::string& left, const std::string& right);
+    template <> inline float   _multiply<float>(float left, const std::string& right)
+      { return left * _toFloat(right);  }
+    template <> inline float   _multiply<float>(const std::string& left, float right)
+      { return _toFloat(left) * right;  }
+
+    template <>        double  _multiply<double>(const std::string& left, const std::string& right);
+    template <> inline double  _multiply<double>(const std::string& left, double right)
+      { return _toDouble(left) * right; }
+    template <> inline double  _multiply<double>(double left, const std::string& right)
+      { return left * _toDouble(right); }
     
     void _toDictionary(const std::string& name, const std::string& value);
     
@@ -99,33 +123,30 @@ namespace DD4hep {
       typedef T Implementation;
       typedef Handle<Implementation> handle_t;
       T* m_element;
-      Handle() : m_element(0)                 {                         }
-      Handle(T* e) : m_element(e)             {                         }
-      Handle(const Handle<T>& e) : m_element(e.m_element) {             }
+      Handle() : m_element(0)                 {                                 }
+      Handle(T* e) : m_element(e)             {                                 }
+      Handle(const Handle<T>& e) : m_element(e.m_element) {                     }
       template<typename Q> Handle(Q* e)
-      : m_element((T*)e)                    {  verifyObject();        }
+      : m_element((T*)e)                      {  verifyObject();                }
       template<typename Q> Handle(const Handle<Q>& e) 
-      : m_element((T*)e.m_element)          {  verifyObject();        }
+      : m_element((T*)e.m_element)            {  verifyObject();                }
       
-      T* ptr() const                          {  return m_element;      }
-      template <typename Q> Q* _ptr() const   {  return (Q*)m_element;  }
-      bool isValid() const                    {  return 0 != m_element; }
-      bool operator!() const                  {  return 0 == m_element; }
-      T* operator->() const                   {  return  m_element;     }
-      operator T& ()  const                   {  return *m_element;     }
-      T& operator*()  const                   {  return *m_element;     }
-      
-      template <typename Q> Q* data() const  {
-	return (Value<T,Q>*)m_element;
-      }
+      bool isValid() const                    {  return 0 != m_element;         }
+      bool operator!() const                  {  return 0 == m_element;         }
+      T* operator->() const                   {  return  m_element;             }
+      operator T& ()  const                   {  return *m_element;             }
+      T& operator*()  const                   {  return *m_element;             }
+      T* ptr() const                          {  return m_element;              }
+      template <typename Q> Q* _ptr() const   {  return (Q*)m_element;          }
+      template <typename Q> Q* data() const   {  return (Value<T,Q>*)m_element; }
       void verifyObject() const {
         increment_object_validations();
         if ( m_element && dynamic_cast<T*>(m_element) == 0 )  {
           bad_assignment(typeid(*m_element),typeid(T));
         }
       }
-      static void bad_assignment(const std::type_info& from, const std::type_info& to);
       const char* name() const;
+      static void bad_assignment(const std::type_info& from, const std::type_info& to);
       void  assign(Implementation* n, const std::string& nam, const std::string& title);
     };
     typedef Handle<>       Elt_t;
diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h
index 751a4a88dc6bf9c458fd8255857ea2d2d9f1f7dd..74c7a4175994d7ac0d326ac905b7ce8613e86912 100644
--- a/DDCore/include/DD4hep/LCDD.h
+++ b/DDCore/include/DD4hep/LCDD.h
@@ -7,11 +7,12 @@
 //
 //====================================================================
 
-#ifndef DD4hep_LCDD_LCDD_H
-#define DD4hep_LCDD_LCDD_H
+#ifndef DD4HEP_LCDD_LCDD_H
+#define DD4HEP_LCDD_LCDD_H
 
 // Framework includes
 #include "DD4hep/Handle.h"
+#include "DD4hep/Fields.h"
 #include "DD4hep/Objects.h"
 #include "DD4hep/Shapes.h"
 #include "DD4hep/Volumes.h"
@@ -39,14 +40,19 @@ namespace DD4hep {
      */
     struct LCDD {
       typedef std::map<std::string,Handle<> > HandleMap;
+      typedef std::map<std::string,std::string> PropertyValues;
+      typedef std::map<std::string,PropertyValues>  Properties;
 
+      /// Destructor
       virtual ~LCDD() {}
 
-      virtual void create() = 0;
+      /// Initialize geometry
       virtual void init() = 0;
+      /// Finalize the geometry
       virtual void endDocument() = 0;
-      virtual void addStdMaterials() = 0;
 
+      /// Access to properties map
+      virtual Properties& properties() const = 0;
       /// Return handle to material describing air
       virtual Material air() const = 0;
       /// Return handle to material describing vacuum
@@ -61,6 +67,9 @@ namespace DD4hep {
       /// Return handle to the world volume containing the volume with the tracking devices
       virtual Volume   trackingVolume() const = 0;
 
+      /// Return handle to the combined electromagentic field description.
+      virtual OverlayedField field() const = 0;
+
       /// Accessor to the map of header entries
       virtual const HandleMap& header()  const = 0;
       /// Accessor to the map of constants
@@ -79,6 +88,8 @@ namespace DD4hep {
       virtual const HandleMap& limitsets()  const = 0;
       /// Accessor to the map of aligment entries
       virtual const HandleMap& alignments()  const = 0;
+      /// Accessor to the map of field entries, which together form the global field
+      virtual const HandleMap& fields()  const = 0;
 
       virtual Volume            pickMotherVolume(const DetElement& sd)     const = 0;
 
@@ -101,6 +112,8 @@ namespace DD4hep {
       /// Retrieve a sensitive detector by it's name from the detector description
       virtual SensitiveDetector sensitiveDetector(const std::string& name) const = 0;
       /// Retrieve a subdetector element by it's name from the detector description
+      virtual CartesianField    field(const std::string& name)             const = 0;
+      /// Retrieve a field component by it's name from the detector description
       virtual DetElement        detector(const std::string& name)          const = 0;
 
       /// Add a new constant to the detector description
@@ -121,6 +134,8 @@ namespace DD4hep {
       virtual LCDD& add(DetElement detector)  = 0;
       /// Add alignment entry to the detector description
       virtual LCDD& add(AlignmentEntry entry) = 0;
+      /// Add a field component to the detector description
+      virtual LCDD& add(CartesianField entry) = 0;
 
       /// Add a new constant by named reference to the detector description
       virtual LCDD& addConstant(const Ref_t& element) = 0;
@@ -142,18 +157,19 @@ namespace DD4hep {
       virtual LCDD& addDetector(const Ref_t& detector) = 0;
       /// Add alignment entry by named reference to the detector description
       virtual LCDD& addAlignment(const Ref_t& alignment) = 0;
+      /// Add a field component by named reference to the detector description
+      virtual LCDD& addField(const Ref_t& field) = 0;
 
       /// Read compact geometry description or alignment file
       virtual void fromCompact(const std::string& fname) = 0;
-      /// Apply & lock realigments
-      virtual void applyAlignment() = 0;
-
-      /// Dump geometry description
+      /// Read any geometry description or alignment file
+      virtual void fromXML(const std::string& fname) = 0;
+      /// 
       virtual void dump() const = 0;
-      
+
       ///---Factory method-------
       static LCDD& getInstance(void);
     };
   }       /* End namespace Geometry  */
 }         /* End namespace DD4hep   */
-#endif    /* DD4hep_LCDD_LCDD_H     */
+#endif    /* DD4HEP_LCDD_LCDD_H     */
diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h
index d8ef32c59aa9c86b0fc1387d30889418660a7085..6cc21e510ae86331dddb3d0fc349b64b8a5599f9 100644
--- a/DDCore/include/DD4hep/Objects.h
+++ b/DDCore/include/DD4hep/Objects.h
@@ -7,8 +7,8 @@
 //
 //====================================================================
 
-#ifndef DD4hep_GEOMETRY_OBJECTS_H
-#define DD4hep_GEOMETRY_OBJECTS_H
+#ifndef DD4HEP_GEOMETRY_OBJECTS_H
+#define DD4HEP_GEOMETRY_OBJECTS_H
 
 // Framework include files
 #include "DD4hep/Handle.h"
@@ -30,14 +30,13 @@ class TGeoPhysicalNode;
 #ifndef M_PI
   #define M_PI 3.14159265358979323846
 #endif
+
+
 /*
  *   DD4hep namespace declaration
  */
 namespace DD4hep {
 
-  // Forward declarations
-  class IDDescriptor;
-
   /*
    *   Geoemtry namespace declaration
    */
@@ -45,6 +44,8 @@ namespace DD4hep {
 
     // Forward declarations
     struct LCDD;
+    class IDDescriptor;
+
 
     /** @class Author Objects.h
      *  
@@ -90,9 +91,9 @@ namespace DD4hep {
       template <typename Q> 
       Constant(const Handle<Q>& e) : Ref_t(e)  {}
       /// Constructor to be used when creating a new DOM tree
-      Constant(LCDD& doc, const std::string& name);
+      Constant(const std::string& name);
       /// Constructor to be used when creating a new DOM tree
-      Constant(LCDD& doc, const std::string& name, const std::string& val);
+      Constant(const std::string& name, const std::string& val);
       /// String representation of this object
       std::string toString()  const;
     };
@@ -268,7 +269,7 @@ namespace DD4hep {
       template <typename Q> 
       Atom(const Handle<Q>& e) : Handle<TGeoElement>(e) {}
       /// Constructor to be used when reading the already parsed DOM tree
-      Atom(LCDD& doc, const std::string& name, const std::string& formula, int Z, int N, double density);
+      Atom(const std::string& name, const std::string& formula, int Z, int N, double density);
     };
 
     /** @class Material Objects.h
@@ -283,7 +284,7 @@ namespace DD4hep {
       template <typename Q> 
       Material(const Handle<Q>& e) : Handle<TGeoMaterial>(e) {}
       /// Constructor to be used when reading the already parsed DOM tree
-      Material(LCDD& doc, const std::string& name);
+      Material(const std::string& name);
       /// String representation of this object
       std::string toString()  const;
     };
@@ -319,7 +320,7 @@ namespace DD4hep {
       /// Copy constructor for handle
       VisAttr(const VisAttr& e) : Ref_t(e) {}
       /// Constructor to be used when creating a new registered visualization object
-      VisAttr(LCDD& doc, const std::string& name);
+      VisAttr(const std::string& name);
       /// Additional data accessor
       Object& _data()   const {  return *data<Object>();  }
 
@@ -373,7 +374,7 @@ namespace DD4hep {
       template <typename Q> 
       AlignmentEntry(const Handle<Q>& h) : Base(h) {}
       /// Constructor to be used when creating a new aligment entry
-      AlignmentEntry(LCDD& doc, const std::string& path);
+      AlignmentEntry(const std::string& path);
       /// Align the PhysicalNode (translation only)
       int align(const Position& pos, bool check=false, double overlap=0.001);
       /// Align the PhysicalNode (rotation only)
@@ -484,5 +485,5 @@ namespace DD4hep {
     };
 
   }       /* End namespace Geometry           */
-}         /* End namespace DD4hep            */
-#endif    /* DD4hep_GEOMETRY_OBJECTS_H       */
+}         /* End namespace DD4hep             */
+#endif    /* DD4HEP_GEOMETRY_OBJECTS_H        */
diff --git a/DDCore/src/compact/Conversions.h b/DDCore/include/XML/Conversions.h
similarity index 64%
rename from DDCore/src/compact/Conversions.h
rename to DDCore/include/XML/Conversions.h
index df18a0a54153ae98f7c26d8cec9bd226b204d253..2597dd1ddec3e7b765d1a28c5136cf243cd88c00 100644
--- a/DDCore/src/compact/Conversions.h
+++ b/DDCore/include/XML/Conversions.h
@@ -28,10 +28,10 @@ namespace DD4hep {
   /*
    *   XML namespace declaration
    */
-  namespace Geometry  {
+  //namespace Geometry  {
 
     // Function prototypes used for object conversions
-    template <typename T> Ref_t    toRefObject(LCDD& lcdd, const XML::Handle_t& xml);
+    //template <typename T> Ref_t    toRefObject(LCDD& lcdd, const XML::Handle_t& xml);
 
     /** @class Converter Conversions.h  DD4hep/compact/Conversions.h
       *
@@ -39,9 +39,12 @@ namespace DD4hep {
       *  @version  1.0
       */
     template <typename T> struct Converter {
-      typedef T to_type;
-      LCDD&  lcdd;
-      Converter(LCDD& l) : lcdd(l) {}
+      typedef T        to_type;
+      typedef void*    user_param;
+      Geometry::LCDD&  lcdd;
+      user_param       param;
+      Converter(Geometry::LCDD& l) : lcdd(l), param(0) {}
+      Converter(Geometry::LCDD& l, user_param p) : lcdd(l), param(p) {}
       void operator()(const XML::Handle_t& xml) const;
     };
 
@@ -52,13 +55,13 @@ namespace DD4hep {
       */
     template <typename T> struct PrintMap {
       typedef T item_type;
-      typedef const LCDD::HandleMap cont_type;
+      typedef const Geometry::LCDD::HandleMap cont_type;
 
-      const LCDD&   lcdd;
-      std::ostream& os;
-      std::string   text;
-      cont_type&    cont;
-      PrintMap(const LCDD& l, std::ostream& stream, cont_type& c, const std::string& t="") 
+      const Geometry::LCDD&   lcdd;
+      std::ostream&           os;
+      std::string             text;
+      cont_type&              cont;
+      PrintMap(const Geometry::LCDD& l, std::ostream& stream, cont_type& c, const std::string& t="") 
 	: lcdd(l), os(stream), text(t), cont(c)  {}
       void operator()() const;
     };
@@ -69,15 +72,15 @@ namespace DD4hep {
       *  @version  1.0
       */
     template <typename T> struct Printer  {
-      const LCDD&   lcdd;
-      std::ostream& os;
-      std::string   prefix;
-      Printer(const LCDD& l, std::ostream& stream, const std::string& p="") 
+      const Geometry::LCDD&   lcdd;
+      std::ostream&           os;
+      std::string             prefix;
+      Printer(const Geometry::LCDD& l, std::ostream& stream, const std::string& p="") 
 	: lcdd(l), os(stream), prefix(p) {}
       void operator()(const T& value) const;
     };
     inline const char* yes_no(bool value) { return value ? "YES" : "NO "; }
 
-  }       /* End namespace Geometry  */
+    //}       /* End namespace Geometry  */
 }         /* End namespace DD4hep   */
 #endif    /* DD4hep_COMPACT_CONVERSION_H    */
diff --git a/DDCore/include/XML/XMLDetector.h b/DDCore/include/XML/XMLDetector.h
index 1cfc04d3f2cbab8569ec92548b6cbb4ffebb3a4f..c0823f2c681b40a57ab3527bc7bc986c8adc3cac 100644
--- a/DDCore/include/XML/XMLDetector.h
+++ b/DDCore/include/XML/XMLDetector.h
@@ -53,10 +53,13 @@ namespace DD4hep {
       double zhalf() const;
       double deltaphi() const;
 
-      double outer_z() const;
+      double outer_radius() const;
       double outer_r() const;
-      double inner_z() const;
+      double outer_z() const;
+      double inner_radius() const;
       double inner_r() const;
+      double inner_z() const;
+
       double z_length() const;
       double length() const;
       double width() const;
@@ -70,6 +73,7 @@ namespace DD4hep {
       double crossing_angle() const;
 
       double zmin() const;
+      double zmax() const;
 
       double radius() const;
       double offset() const;
@@ -132,6 +136,8 @@ namespace DD4hep {
       std::string visStr() const;
       std::string regionStr() const;
       std::string limitsStr() const;
+      double inner_field() const;
+      double outer_field() const;
       Dimension dimensions()  const;
       bool isTracker() const;
       bool isCalorimeter() const;
diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h
index 8c376b6883521b1e0b18f35b20bd1ee914c863f9..559b8fd5c8198a9d44f56e82419ac1dab087916f 100644
--- a/DDCore/include/XML/XMLElements.h
+++ b/DDCore/include/XML/XMLElements.h
@@ -6,11 +6,12 @@
 //  Author     : M.Frank
 //
 //====================================================================
-#ifndef DD4hep_HandleS_H
-#define DD4hep_HandleS_H
+#ifndef DD4HEP_XMLELEMENTS_H
+#define DD4HEP_XMLELEMENTS_H
 
 #include <cmath>
 #include <string>
+#include <vector>
 #include <stdexcept>
 #include "xercesc/util/XMLString.hpp"
 #include "xercesc/dom/DOMElement.hpp"
@@ -32,8 +33,12 @@ namespace DD4hep {
   template<class T> void deletePtr(T*& p) { if(p) delete p; p=0; }
   namespace XML  {
 
-    typedef xercesc::DOMAttr*  Attribute;
-    typedef const std::string& CSTR;
+    typedef xercesc::DOMNodeList* NodeList;
+    typedef xercesc::DOMAttr*     Attribute;
+    typedef const std::string&    CSTR;
+
+    /// Dump DOM tree of a document
+    void dumpTree(xercesc::DOMDocument* doc);
 
     std::string _toString(const Attribute attr);
     std::string _toString(const XMLCh *toTranscode);
@@ -43,99 +48,211 @@ namespace DD4hep {
     std::string _toString(float  d, const char* fmt="%f");
     std::string _toString(double d, const char* fmt="%f");
     void        _toDictionary(const XMLCh* name, const XMLCh* value);
-    bool   _toBool(const XMLCh* value);
-    int    _toInt(const XMLCh* value);
-    long   _toLong(const XMLCh* value);
-    float  _toFloat(const XMLCh* value);
-    double _toDouble(const XMLCh* value);
-    void dumpTree(xercesc::DOMDocument* doc);
-
 
+    /// Conversion function from raw unicode string to bool
+    bool        _toBool(const XMLCh* value);
+    /// Conversion function from raw unicode string to int
+    int         _toInt(const XMLCh* value);
+    /// Conversion function from raw unicode string to long
+    long        _toLong(const XMLCh* value);
+    /// Conversion function from raw unicode string to float
+    float       _toFloat(const XMLCh* value);
+    /// Conversion function from raw unicode string to double
+    double      _toDouble(const XMLCh* value);
+
+    /** @class Strng_t XMLElements.h XML/XMLElements.h
+     * 
+     *  Helper class to encapsulate a unicode string
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
     struct Strng_t  {
       XMLCh* m_xml;
       Strng_t(const XMLCh* c)        { m_xml=xercesc::XMLString::replicate(c);          }
       Strng_t(const char* c)         { m_xml=xercesc::XMLString::transcode(c);          }
-      Strng_t(CSTR c)                { m_xml=xercesc::XMLString::transcode(c.c_str());  }
+      Strng_t(const std::string& c)  { m_xml=xercesc::XMLString::transcode(c.c_str());  }
       ~Strng_t()                     { if (m_xml) xercesc::XMLString::release(&m_xml);  }
-      operator const XMLCh*() const { return m_xml;                           }
-      const XMLCh* ptr() const      { return m_xml;                           }
+      operator const XMLCh*() const  { return m_xml;                                    }
+      const XMLCh* ptr() const       { return m_xml;                                    }
       Strng_t& operator=(const char* s);
       Strng_t& operator=(const Strng_t& s);
       Strng_t& operator=(const std::string& s);
     };
     
+    /// Unicode string concatenation of a normal ASCII string from right side
     Strng_t operator+(const Strng_t& a,     const char* b);
+    /// Unicode string concatenation of a normal ASCII string from left side
     Strng_t operator+(const char* a,        const Strng_t& b);
+    /// Unicode string concatenation of a encapsulated and raw unicode string from right side
     Strng_t operator+(const Strng_t& a,     const XMLCh* b);
+    /// Unicode string concatenation of a encapsulated and raw unicode string from left side
     Strng_t operator+(const XMLCh* a,       const Strng_t& b);
+    /// Unicode string concatenation of a raw unicode and an STL string from the right
     Strng_t operator+(const XMLCh* a,       const std::string& b);
+    /// Unicode string concatenation of a raw unicode and an STL string from the left
     Strng_t operator+(const std::string& a, const XMLCh* b);
 
+    /** @class Tag_t XMLElements.h XML/XMLElements.h
+     * 
+     *  Helper class to easily convert between 
+     *  -- unicode
+     *  -- std::string
+     *  -- const char*.
+     *  Internally a copy representation as an std::string is kept.
+     *  
+     *  @author  M.Frank
+     *  @version 1.0
+     */
     struct Tag_t : public Strng_t {
+      /// STL string buffer
       std::string m_str;
-      Tag_t(CSTR s) : Strng_t(s), m_str(s) {  }
-      Tag_t(const char* s) : Strng_t(s), m_str(s) {  }
+
+      /// Constructor from normal ASCII string
+      Tag_t(const char* s) : Strng_t(s), m_str(s) {               }
+      /// Constructor from unicode string
+      Tag_t(const XMLCh*  s) : Strng_t(s), m_str(_toString(s)) {  }
+      /// Constructor from internal XML string
       Tag_t(const Strng_t& s) : Strng_t(s), m_str(_toString(s)) { }
-      Tag_t(const XMLCh*  s) : Strng_t(s), m_str(_toString(s)) { }
-      ~Tag_t()                            {  }
+      /// Constructor from STL string
+      Tag_t(const std::string& s) : Strng_t(s), m_str(s) {        }
+      /// Destructor
+      ~Tag_t()                            {                       }
+
+      /// Assignment of a normal ASCII string
       Tag_t& operator=(const char* s);
+      /// Assignment of a tag object
       Tag_t& operator=(const Tag_t& s);
+      /// Assignment of a internal XML string
       Tag_t& operator=(const Strng_t& s);
+      /// Assignment of a STL string
       Tag_t& operator=(const std::string& s);
-      operator CSTR () const    { return m_str; }
-      CSTR str()  const         { return m_str; }
+
+      /// Automatic conversion to STL string
+      operator const std::string& () const    { return m_str; }
+      /// Access writable STL string
+      const std::string& str()  const         { return m_str; }
+      /// Access data buffer of STL string
       const char* c_str() const { return m_str.c_str(); }
     };
+    
+    /// Tag/string concatenation with a normal ASCII string from right side
     Tag_t   operator+(const Tag_t& a, const char* b);
+    /// Tag/string concatenation with a normal ASCII string from left side
     Tag_t   operator+(const char* a,  const Tag_t& b);
+    /// Tag/string concatenation with a unicode string from right side
     Tag_t   operator+(const Tag_t& a, const XMLCh* b);
+    /// Tag/string concatenation with a internal XML string from right side
     Tag_t   operator+(const Tag_t& a, const Strng_t& b);
+    /// Tag/string concatenation with a STL string from right side
     Tag_t   operator+(const Tag_t& a, const std::string& b);
-
-    inline bool operator==(CSTR c, const Tag_t& b)         {  return c == b.m_str;                       }
-
+    /// Equality operator between tag object and STL string
+    inline bool operator==(const std::string& c, const Tag_t& b)  {  return c == b.m_str;                }
+
+    /** @class Handle_t XMLElements.h XML/XMLElements.h
+     * 
+     *  Helper class to easily access the properties of single DOMElements.
+     *
+     *  Note: The assignmant operator as well as the copy constructor
+     *  do not have to be implemented, they are aut-generated by the compiler!
+     *  
+     *  @author  M.Frank
+     *  @version 1.0
+     */
     struct Handle_t  {
-      mutable xercesc::DOMElement* m_node;
-      Handle_t(xercesc::DOMElement* e=0) : m_node(e) {}
-      xercesc::DOMElement* operator->() const               { return m_node;                              }
-      operator xercesc::DOMElement* () const                { return m_node;                              }
-      xercesc::DOMElement* ptr() const                      { return m_node;                              }
+      // Abbreviation for internal use
+      typedef  xercesc::DOMElement* Elt_t;
+
+      /// The pointer to the DOMElement
+      mutable Elt_t m_node;
+
+      /// Initializing constructor
+      Handle_t(Elt_t e=0) : m_node(e) {}
+      /// Direct access to the DOMElement using the operator->
+      Elt_t operator->() const                              { return m_node;                              }
+      /// Direct access to the DOMElement by dereferencing
+      operator Elt_t() const                                { return m_node;                              }
+      /// Direct access to the DOMElement by function
+      Elt_t ptr() const                                     { return m_node;                              }
+      /// Clone the DOMelement - with the option of a deep copy
       Handle_t clone(xercesc::DOMDocument* new_doc, bool deep) const;
+
+      /// Unicode text access to the element's tag
+      const XMLCh* rawTag() const                           { return m_node->getTagName();                }
+      /// Unicode text access to the element's text
+      const XMLCh* rawText() const                          { return m_node->getTextContent();            }
+      /// Unicode text access to the element's value
+      const XMLCh* rawValue() const                         { return m_node->getNodeValue();              }
+      /// Text access to the element's tag
+      std::string tag() const                               { return _toString(rawTag());                 }
+      /// Text access to the element's text
+      std::string text() const                              { return _toString(rawText());                }
+      /// Text access to the element's value
+      std::string value() const                             { return _toString(rawValue());               }
+
+      /*** DOM Attribute handling 
+       */
+      /// Access attribute name (throws exception if not present)
+      const XMLCh* attr_name(const Attribute attr)  const;
+      /// Access attribute value by the attribute  (throws exception if not present)
+      const XMLCh* attr_value(const Attribute attr)  const;
+      /// Access attribute value by the attribute's unicode name (throws exception if not present)
+      const XMLCh* attr_value(const XMLCh* attr)  const;
+      /// Access attribute value by the attribute's unicode name (no exception thrown if not present)
+      const XMLCh* attr_value_nothrow(const XMLCh* attr)  const;
+
+      /// Access attribute pointer by the attribute's unicode name (throws exception if not present)
+      Attribute attr_ptr(const XMLCh* attr)  const;
+      /// Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
+      Attribute attr_nothrow(const XMLCh* tag)  const       { return m_node->getAttributeNode(tag);       }
+
+      /// Retrieve a collection of all attributes of this DOM element
+      std::vector<Attribute> attributes()  const;
+      /// Check for the existence of a named attribute
       bool hasAttr(const XMLCh* t) const                    { return 0 != m_node->getAttributeNode(t);    }
-      bool hasAttr(const char* t) const                     { return 0 != m_node->getAttributeNode(Strng_t(t));}
-      template <class T> T attr(const Attribute a)  const;
-      template <class T> T attr(const XMLCh* t)  const;
-      template <class T> T attr(const char* t)  const       { return this->attr<T>(Strng_t(t));            }
+      /// Check for the existence of a named attribute
+      bool hasAttr(const char* t) const                     { return hasAttr(Strng_t(t));                 }
+      /// Access typed attribute value by the DOMAttr
+      template <class T> T attr(const Attribute a)  const   { return this->attr<T>(this->attr_name(a));   }
+      /// Access typed attribute value by it's name      
+      template <class T> T attr(const char* name)   const   { return this->attr<T>(Strng_t(name));        }
+      /// Access typed attribute value by it's unicode name
+      template <class T> T attr(const XMLCh* name)  const;
+
       void setAttrs(Handle_t e) const;
+
+      /// Generic attribute setter with unicode value
       Attribute setAttr(const XMLCh* t, const XMLCh* v) const;
+      /// Generic attribute setter with DOMAttr value
       Attribute setAttr(const XMLCh* t, const Attribute v) const;
+      /// Generic attribute setter with integer value
       Attribute setAttr(const XMLCh* t, int val)  const;
+      /// Generic attribute setter with boolen value
       Attribute setAttr(const XMLCh* t, bool val)  const;
+      /// Generic attribute setter with floating point value
       Attribute setAttr(const XMLCh* t, float val)  const;
+      /// Generic attribute setter with double precision floating point value
       Attribute setAttr(const XMLCh* t, double val)  const;
+      /// Generic attribute setter with text value
       Attribute setAttr(const XMLCh* t, const char* v) const;
 
-      const XMLCh* rawTag() const                           { return m_node->getTagName(); }
-      const XMLCh* rawText() const                          { return m_node->getTextContent(); }
-      const XMLCh* rawValue() const                         { return m_node->getNodeValue(); }
-      std::string tag() const                               { return _toString(rawTag());     }
-      std::string text() const                              { return _toString(rawText()); }
-      std::string value() const                             { return _toString(rawValue());       }
-
+      /*** DOM Element child handling 
+       */
+      /// Check the existence of a child with a given tag name
       bool hasChild(const XMLCh* tag) const;
-      Handle_t firstChild(const XMLCh* tag) const;
+      /// Access a single child by it's tag name (unicode)
       Handle_t child(const XMLCh* tag, bool throw_exception=true) const;
-      xercesc::DOMNodeList* children(const XMLCh* tag) const{ return m_node->getElementsByTagName (tag);   }
+      /// Access a group of children identified by the same tag name
+      NodeList children(const XMLCh* tag) const{ return m_node->getElementsByTagName (tag);   }
+      /// Access the number of children of this DOM element with a given tag name
       size_t numChildren(const XMLCh* tag, bool throw_exception) const;
-      Handle_t remove(xercesc::DOMElement* node)  const;
+      /// Remove a single child node identified by it's handle from the tree of the element
+      Handle_t remove(Handle_t e)  const;
+      /// Remove children with a given tag name from the DOM node
       void removeChildren(const XMLCh* tag)  const;
-      void append(xercesc::DOMElement* e) const { m_node->appendChild(e); }
-      const XMLCh* attr_value(const XMLCh* attr)  const;
-      const XMLCh* attr_value(const Attribute attr)  const;
-      const XMLCh* attr_value_nothrow(const XMLCh* attr)  const;
+      /// Append a DOM element to the current node
+      void append(Handle_t e) const { m_node->appendChild(e.ptr()); }
 
-      Attribute attr_ptr(const XMLCh* attr)  const;
-      Attribute attr_nothrow(const XMLCh* tag)  const { return m_node->getAttributeNode(tag);  }
     };
 
 #define INLINE inline
@@ -160,7 +277,7 @@ namespace DD4hep {
 
     template<> INLINE std::string Handle_t::attr<std::string>(const XMLCh* tag)  const  
       {      return _toString(attr_nothrow(tag));        }
-
+#if 0
     template<> INLINE bool Handle_t::attr<bool>(const Attribute tag)  const  
       {      return _toBool(attr_value(tag));            }
 
@@ -175,23 +292,54 @@ namespace DD4hep {
 
     template<> INLINE std::string Handle_t::attr<std::string>(const Attribute tag)  const  
       {      return _toString(attr_value(tag));          }
+#endif
 
-    struct Collection_t : public Handle_t {
-      mutable XMLSize_t     m_index;
-      xercesc::DOMElement*  m_element;
-      xercesc::DOMNodeList* m_children;
 
-      Collection_t(xercesc::DOMElement* node, const XMLCh* tag);
-      Collection_t(xercesc::DOMElement* node, const char*  tag);
-      Collection_t(xercesc::DOMElement* node, xercesc::DOMNodeList* children);
+    /** @class Collection_t XMLElements.h XML/XMLElements.h
+     * 
+     *  Helper class to easily access collections of DOMNodes (or DOMElements)
+     *  
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    struct Collection_t : public Handle_t {
+      /// Iteration type. See NodeType enumeration for details
+      xercesc::DOMNode::NodeType m_type;
+      /// Current iteration index
+      mutable XMLSize_t          m_index;
+      /// Reference to the list of child nodes
+      NodeList                   m_children;
+
+      /// Constructor to initialize loop over children with a given node type
+      Collection_t(Elt_t node, xercesc::DOMNode::NodeType typ);
+      /// Constructor over DOMElements with a given tag name
+      Collection_t(Elt_t node, const XMLCh* tag);
+      /// Constructor over DOMElements with a given tag name
+      Collection_t(Elt_t node, const char* tag);
+      /// Constructor over DOMElements in a node list
+      Collection_t(NodeList children);
+      /// Constructor over arbitrary DOMNodes in a node list
+      Collection_t(NodeList children, xercesc::DOMNode::NodeType typ);
+      /// Reset the collection object to restart the iteration
       Collection_t& reset();
+      /// Access the collection size
       size_t size()  const;
+      /// Operator to advance the collection (pre increment)
       void operator++()  const;
-      xercesc::DOMElement* current() const           { return m_node;                              }
+      /// Operator to advance the collection (post increment)
+      void operator++(int)  const;
+      /// Operator to advance the collection (pre decrement)
+      void operator--()  const;
+      /// Operator to advance the collection (post decrement)
+      void operator--(int)  const;
+      /// Access to current element
+      Elt_t current() const { return m_node; }
+      /// Loop processor using function object
       template <class T> void for_each(T oper) const  {
         for(const Collection_t& c=*this; c; ++c)
           oper(*this);
       }
+      /// Loop processor using function object
       template <class T> void for_each(const XMLCh* tag, T oper) const  {
         for(const Collection_t& c=*this; c; ++c)
           Collection_t(c.m_node, tag).for_each(oper);
@@ -199,55 +347,93 @@ namespace DD4hep {
     };
 
 
+    /** @class Document XMLElements.h XML/XMLElements.h
+     * 
+     *  User class encapsulating a DOM document
+     *  
+     *  @author  M.Frank
+     *  @version 1.0
+     */
     struct Document  {
-      xercesc::DOMDocument     *m_doc;
-      Document(xercesc::DOMDocument* d) : m_doc(d) {}
-      operator xercesc::DOMDocument*() const   {  return m_doc; }
-      xercesc::DOMDocument* operator->() const {  return m_doc; }
-      xercesc::DOMElement* createElt(const XMLCh* tag) const;
+      typedef xercesc::DOMDocument* DOC;
+      DOC m_doc;
+
+      /// Constructor
+      Document(DOC d) : m_doc(d) {}
+      /// Auto-conversion to DOM document
+      operator DOC() const   {  return m_doc; }
+      /// Accessot to DOM document behaviour using arrow operator
+      DOC operator->() const {  return m_doc; }
+      /// Access the ROOT eleemnt of the DOM document
+      Handle_t  root() const;
+
+      /// Create DOM element
+      Handle_t  createElt(const XMLCh* tag) const;
+      /// Create DOM attribute (name/value pair)
       Attribute createAttr(const XMLCh* name, const XMLCh* value)  const;
-      Handle_t clone(Handle_t source,bool deep)  const;
-      Handle_t root() const;
+      /// Clone a DOM element / sub-tree depending on deep_copy flag
+      Handle_t  clone(Handle_t source, bool deep_copy)  const;
     };
 
     struct DocumentHolder : public Document {
-      DocumentHolder(xercesc::DOMDocument* d) : Document(d) {}
+      DocumentHolder(DOC d) : Document(d) {}
       virtual ~DocumentHolder();
     };
 
+    /** @class Document XMLElements.h XML/XMLElements.h
+     * 
+     *  User class encapsulating a DOM element 
+     *  using the Handle helper
+     *  
+     *  @author  M.Frank
+     *  @version 1.0
+     */
     struct Element  {
+      typedef Handle_t::Elt_t Elt_t;
       Handle_t m_element;
+
+      /// Constructor from DOMElement handle
       Element(const Handle_t& e) : m_element(e) {                 }
+      /// Constructor from DOM document entity
       Element(const Document& document, const XMLCh* type);
-      operator bool() const                  {  return 0 != m_element.ptr(); }
-      bool operator!() const                 {  return 0 == m_element.ptr(); }
-      operator Handle_t () const             {  return m_element; }
-      operator xercesc::DOMElement*() const  {  return m_element; }
-      xercesc::DOMElement* ptr() const       {  return m_element; }
+      /// Access the hosting document handle of this DOM element
       Document document() const;
-      const XMLCh* tagName() const  
-      { return m_element.rawTag();              }
-      void append(Handle_t handle) const  
-      {  m_element.append(handle);              }
-      Handle_t clone(const Document& new_doc, bool deep) const  
-      {  return new_doc.clone(m_element,deep);  }
-      size_t numChildren(const XMLCh* tag, bool throw_exception=true) const
-      {  return m_element.numChildren(tag,throw_exception);     }
-      bool hasAttr(const XMLCh* name) const   
-      {  return m_element.hasAttr(name);        }
-      template <class T> T attr(const XMLCh* tag) const 
-      { return m_element.attr<T>(tag);          }
-      void setAttrs(Handle_t e) const
-      {  return m_element.setAttrs(e);          }
-      template <class T> Attribute setAttr(const XMLCh* name,const T& value)  const
-      {  return m_element.setAttr(name,value);  }
+
+      /// operator bool: check handle validity
+      operator bool() const                                     {  return 0 != m_element.ptr();           }
+      /// operator NOT: check handle validity
+      bool operator!() const                                    {  return 0 == m_element.ptr();           }
+      /// Automatic conversion to DOM element handle
+      operator Handle_t () const                                {  return m_element;                      }
+      /// Automatic conversion to DOMElement pointer
+      operator Elt_t() const                                    {  return m_element;                      }
+      /// Access to DOMElement pointer
+      Elt_t ptr() const                                         {  return m_element;                      }
+
+      /// Access the tag name of this DOM element
+      const XMLCh* tagName() const                              {  return m_element.rawTag();             }
+      /// Append a new element to the existing tree
+      void append(Handle_t handle) const                        {  m_element.append(handle);              }
+      /// Clone the DOMelement - with the option of a deep copy
+      Handle_t clone(const Document& new_doc, bool deep) const  {  return new_doc.clone(m_element,deep);  }
+      /// Access the number of children of this DOM element with a given tag name
+      size_t numChildren(const XMLCh* tag, bool exc=true) const {  return m_element.numChildren(tag,exc); }
+      /// Check for the existence of a named attribute
+      bool hasAttr(const XMLCh* name) const                 {  return m_element.hasAttr(name);            }
+
+      template <class T> T attr(const XMLCh* tag) const     {  return m_element.attr<T>(tag);             }
+      void setAttrs(Handle_t e) const                       {  return m_element.setAttrs(e);              }
+      template <class T> 
+      Attribute setAttr(const XMLCh* nam,const T& val) const{  return m_element.setAttr(nam,val);         }
+      /// Retrieve a collection of all attributes of this DOM element
+      std::vector<Attribute> attributes()  const            {  return m_element.attributes();             }
       Attribute getAttr(const XMLCh* name)  const;
+
       Handle_t clone(Handle_t h, bool deep) const;
       Handle_t addChild(const XMLCh* tag)  const;
       Handle_t setChild(const XMLCh* tag)  const;
       Handle_t child(const Strng_t& tag, bool throw_exception=true) const;
-      Handle_t remove(Handle_t node)  const     
-      { return m_element.remove(node);          }
+      Handle_t remove(Handle_t node)  const                 { return m_element.remove(node);              }
       Attribute setRef(const XMLCh* tag, const XMLCh* refname)  const;
       const XMLCh* getRef(const XMLCh* tag)  const;
     };
@@ -272,4 +458,4 @@ namespace DD4hep {
 
   }
 }         /* End namespace DD4hep   */
-#endif    /* DD4hep_HandleS_H    */
+#endif    /* DD4HEP_XMLELEMENTS_H   */
diff --git a/DDCore/include/XML/XMLTags.h b/DDCore/include/XML/XMLTags.h
index 893b587be7e28bdfab7371ea28019a29d6f0fd0e..8cb7beabb6ba507740af0b620a202de8dcadad01 100644
--- a/DDCore/include/XML/XMLTags.h
+++ b/DDCore/include/XML/XMLTags.h
@@ -25,6 +25,8 @@ namespace DD4hep   { namespace XML  {
   extern const Tag_t Tag_radian;
   extern const Tag_t Tag_mm;
   extern const Tag_t Tag_cm;
+  extern const Tag_t Attr_global;
+  extern const Tag_t Attr_local;
 
 
   extern const Tag_t Attr_overlap;
@@ -45,6 +47,9 @@ namespace DD4hep   { namespace XML  {
   extern const Tag_t Attr_density;
   extern const Tag_t Tag_composite;
   extern const Tag_t Tag_fraction;
+  extern const Tag_t Tag_strength;
+  extern const Tag_t Tag_properties;
+  extern const Tag_t Tag_attributes;
 
   extern const Tag_t Tag_define;
   extern const Tag_t Tag_detector;
@@ -67,9 +72,14 @@ namespace DD4hep   { namespace XML  {
   extern const Tag_t Attr_dimensions;
   extern const Tag_t Attr_ecut;
   extern const Tag_t Attr_false;
+  extern const Tag_t Attr_strength;
+  extern const Tag_t Attr_field;
+  extern const Tag_t Attr_inner_field;
+  extern const Tag_t Attr_outer_field;
   extern const Tag_t Attr_field_name;
   extern const Tag_t Attr_hits_collection;
   extern const Tag_t Attr_incoming_r;
+  extern const Tag_t Attr_inner_radius;
   extern const Tag_t Attr_inner_r;
   extern const Tag_t Attr_inner_z;
   extern const Tag_t Attr_layer;
@@ -79,7 +89,10 @@ namespace DD4hep   { namespace XML  {
   extern const Tag_t Attr_name;
   extern const Tag_t Attr_nphi;
   extern const Tag_t Attr_ntheta;
+  extern const Tag_t Attr_funit;
+  extern const Tag_t Tag_dipole_coeff;
   
+  extern const Tag_t Attr_outer_radius;
   extern const Tag_t Attr_outer_r;
   extern const Tag_t Attr_outer_z;
   extern const Tag_t Attr_outgoing_r;
@@ -108,6 +121,7 @@ namespace DD4hep   { namespace XML  {
   extern const Tag_t Tag_color;
   extern const Tag_t Tag_detectors;
   extern const Tag_t Tag_display;
+  extern const Tag_t Tag_field;
   extern const Tag_t Tag_fields;
   extern const Tag_t Tag_gdml;
   extern const Tag_t Tag_header;
@@ -296,6 +310,7 @@ namespace DD4hep   { namespace XML  {
   // Solid:
   // No tags
   extern const Tag_t Attr_zmin;
+  extern const Tag_t Attr_zmax;
 
   // -- ZPlane
   extern const Tag_t Tag_zplane;
diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp
index 30bafd1b459a82402c9e008df9d8778464c92f2f..40aa12a901d389c531f95bd361afb8a374e6e15b 100644
--- a/DDCore/src/Detector.cpp
+++ b/DDCore/src/Detector.cpp
@@ -23,7 +23,7 @@ namespace {
     void  (*destruct)(void*);
     int     id;
   };
-  typedef map<const std::type_info*, ExtensionEntry> ExtensionMap;
+  typedef map<const type_info*, ExtensionEntry> ExtensionMap;
   static int s_extensionID = 0;
   ExtensionMap& detelement_extensions() {
     static ExtensionMap s_map;
@@ -163,7 +163,7 @@ Value<TNamed,DetElement::Object>* DetElement::Object::clone(int new_id, int flag
   // This implicitly assumes that the children do not access the parent's extensions!
   obj->extensions.clear();
   for(DetElement::Extensions::const_iterator i=extensions.begin(); i != extensions.end(); ++i)  {
-    const std::type_info* info = (*i).first;
+    const type_info* info = (*i).first;
     ExtensionMap::const_iterator j = m.find(info);
     const ExtensionEntry& e = (*j).second;
     obj->extensions[info]   = (*(e.copy))((*i).second,det);
@@ -266,7 +266,7 @@ DetElement::DetElement(DetElement parent, const string& name, int id)   {
 }
 
 /// Add an extension object to the detector element
-void* DetElement::i_addExtension(void* ptr, const std::type_info& info, void* (*copy)(const void*,DetElement), void (*destruct)(void*)) {
+void* DetElement::i_addExtension(void* ptr, const type_info& info, void* (*copy)(const void*,DetElement), void (*destruct)(void*)) {
   Object& o = _data();
   Extensions::iterator j = o.extensions.find(&info);
   if ( j == o.extensions.end() )   {
@@ -289,7 +289,7 @@ void* DetElement::i_addExtension(void* ptr, const std::type_info& info, void* (*
 }
 
 /// Access an existing extension object from the detector element
-void* DetElement::i_extension(const std::type_info& info)   const {
+void* DetElement::i_extension(const type_info& info)   const {
   Object& o = _data();
   Extensions::const_iterator j = o.extensions.find(&info);
   if ( j != o.extensions.end() )   {
@@ -300,7 +300,7 @@ void* DetElement::i_extension(const std::type_info& info)   const {
 }
  
 /// Access to the full path to the placed object
-std::string DetElement::placementPath() const {
+string DetElement::placementPath() const {
   if ( isValid() ) {
     Object& o = _data();
     if ( o.placementPath.empty() )   {
@@ -325,7 +325,7 @@ string DetElement::type() const   {
 }
 
 /// Set the type of the sensitive detector
-DetElement& DetElement::setType(const std::string& typ)   {
+DetElement& DetElement::setType(const string& typ)   {
   if ( isValid() )  {
     m_element->SetTitle(typ.c_str());
     return *this;
@@ -373,7 +373,7 @@ const DetElement::Children& DetElement::children() const   {
 }
 
 /// Access to individual children by name
-DetElement DetElement::child(const std::string& name) const {
+DetElement DetElement::child(const string& name) const {
   if ( isValid() )  {
     const Children& c = _data().children;
     Children::const_iterator i = c.find(name);
@@ -484,9 +484,9 @@ DetElement& DetElement::setLimitSet(const LCDD& lcdd, const string& name, const
 }
 
 DetElement& DetElement::setAttributes(const LCDD& lcdd, const Volume& volume,
-                                        const std::string& region, 
-                                        const std::string& limits, 
-                                        const std::string& vis)
+                                        const string& region, 
+                                        const string& limits, 
+                                        const string& vis)
 {
   return setRegion(lcdd,region,volume).setLimitSet(lcdd,limits,volume).setVisAttributes(lcdd,vis,volume);
 }
@@ -563,7 +563,7 @@ SensitiveDetector::Object::~Object() {
 }
 
 /// Constructor
-SensitiveDetector::SensitiveDetector(const std::string& name, const std::string& type)  {
+SensitiveDetector::SensitiveDetector(const string& name, const string& type)  {
   /*
     <calorimeter ecut="0" eunit="MeV" hits_collection="EcalEndcapHits" name="EcalEndcap" verbose="0">
       <global_grid_xy grid_size_x="3.5" grid_size_y="3.5"/>
@@ -576,7 +576,7 @@ SensitiveDetector::SensitiveDetector(const std::string& name, const std::string&
 }
 
 /// Set the type of the sensitive detector
-SensitiveDetector& SensitiveDetector::setType(const std::string& typ)   {
+SensitiveDetector& SensitiveDetector::setType(const string& typ)   {
   if ( isValid() )  {
     m_element->SetTitle(typ.c_str());
     return *this;
@@ -669,7 +669,7 @@ LimitSet SensitiveDetector::limits() const {
 }
 
 /// Add an extension object to the detector element
-void* SensitiveDetector::i_addExtension(void* ptr, const std::type_info& info, void (*destruct)(void*)) {
+void* SensitiveDetector::i_addExtension(void* ptr, const type_info& info, void (*destruct)(void*)) {
   Object& o = _data();
   Extensions::iterator j = o.extensions.find(&info);
   if ( j == o.extensions.end() )   {
@@ -692,7 +692,7 @@ void* SensitiveDetector::i_addExtension(void* ptr, const std::type_info& info, v
 }
 
 /// Access an existing extension object from the detector element
-void* SensitiveDetector::i_extension(const std::type_info& info)   const {
+void* SensitiveDetector::i_extension(const type_info& info)   const {
   Object& o = _data();
   Extensions::const_iterator j = o.extensions.find(&info);
   if ( j != o.extensions.end() )   {
diff --git a/DDCore/src/FieldTypes.cpp b/DDCore/src/FieldTypes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58513d1d1e155738afb6061a6a1ca9efa9611c30
--- /dev/null
+++ b/DDCore/src/FieldTypes.cpp
@@ -0,0 +1,66 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#include "DD4hep/FieldTypes.h"
+#include <cmath>
+
+using namespace std;
+using namespace DD4hep::Geometry;
+
+#ifndef INFINITY
+#define INFINITY (numeric_limits<double>::max())
+#endif
+
+/// Call to access the field components at a given location
+void ConstantField::fieldComponents(const double* /* pos */, double* field) {
+  field[0] += direction.x;
+  field[1] += direction.y;
+  field[2] += direction.z;
+}
+
+/// Initializing constructor
+SolenoidField::SolenoidField() 
+  : innerField(0),  outerField(0), 
+    minZ(-INFINITY), maxZ(INFINITY), 
+    innerRadius(0), outerRadius(INFINITY)
+{
+  type = CartesianField::MAGNETIC; 
+}
+
+/// Call to access the field components at a given location
+void SolenoidField::fieldComponents(const double* pos, double* field) {
+  double radius = sqrt( pos[0] * pos[0] + pos[1] * pos[1] );
+  if ( radius < innerRadius )
+    field[2] += innerField;
+  else if ( radius < outerRadius )
+    field[2] += outerField;
+}
+
+/// Initializing constructor
+DipoleField::DipoleField()
+  : zmax(INFINITY), zmin(-INFINITY), rmax(INFINITY)
+{
+}
+
+/// Call to access the field components at a given location
+void DipoleField::fieldComponents(const double* pos, double* field) {
+  double bx = 0, z = pos[2], r = sqrt(pos[0] * pos[0] + pos[1] * pos[1]);
+
+  // Check if z coordinate is within dipole z bounds.
+  if (z > zmin && z < zmax && r < rmax)    {
+    // Apply all coefficients to this z coordinate.
+    for (size_t i=0; i<coefficents.size(); ++i)
+      bx += coefficents[i] * pow(fabs(z),i);
+
+    // Flip sign for negative z.
+    if (z < 0) bx = -bx;
+    // Add Bx to the input field.
+    field[0] += bx;
+  }
+}
diff --git a/DDCore/src/Fields.cpp b/DDCore/src/Fields.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55f88d095ffecc42b606f899ace1319c8b9efccc
--- /dev/null
+++ b/DDCore/src/Fields.cpp
@@ -0,0 +1,105 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#include "DD4hep/Fields.h"
+
+using namespace std;
+using namespace DD4hep::Geometry;
+
+namespace {
+  void calculate_combined_field(vector<CartesianField>& v, const double* pos, double* field) {
+    for(vector<CartesianField>::iterator i=v.begin(); i!=v.end(); ++i)
+      (*i).value(pos,field);
+  }
+}
+
+/// Access the field type (string)
+const char* CartesianField::type() const {
+  return m_element->GetTitle();
+}
+
+/// Does the field change the energy of charged particles?
+bool CartesianField::changesEnergy() const {
+  return ELECTRIC==(fieldType()&ELECTRIC);
+}
+
+/// Access to properties container
+CartesianField::Properties& CartesianField::properties()  const   {
+  return data<Object>()->properties; 
+}
+
+/// Returns the 3 field components (x, y, z).
+void CartesianField::value(const double* pos, double* val)  const    { 
+  data<Object>()->fieldComponents(pos,val); 
+}
+
+/// Object constructor
+OverlayedField::OverlayedField(const string& name) : Ref_t() {
+  Value<TNamed,Object>* ptr = new Value<TNamed,Object>();
+  assign(ptr,name,"overlay_field");
+}
+
+/// Access to properties container
+OverlayedField::Properties& OverlayedField::properties()  const   {
+  return data<Object>()->properties; 
+}
+
+/// Does the field change the energy of charged particles?
+bool OverlayedField::changesEnergy() const {
+  int field = data<Object>()->type;
+  return CartesianField::ELECTRIC==(field&CartesianField::ELECTRIC);
+}
+
+/// Add a new field component
+void OverlayedField::add(CartesianField field) {
+  if ( field.isValid() ) {
+    Object* o = data<Object>();
+    if ( o ) {
+      int typ = field.fieldType();
+      bool isEle = field.ELECTRIC==(typ&field.ELECTRIC);
+      bool isMag = field.MAGNETIC==(typ&field.MAGNETIC);
+      if ( isEle ) {
+	vector<CartesianField>& v = o->electric_components;
+	v.push_back(field);
+	o->type |= field.ELECTRIC;
+	o->electric = v.size()==1 ? field : CartesianField();
+      }
+      if ( isMag ) {
+	vector<CartesianField>& v = o->magnetic_components;
+	v.push_back(field);
+	o->type |= field.MAGNETIC;
+	o->magnetic = v.size()==1 ? field : CartesianField();
+      }
+      if ( isMag ||isEle ) return;
+      throw runtime_error("OverlayedField::add: Attempt to add an unknown field type.");
+    }
+    throw runtime_error("OverlayedField::add: Attempt to add to an invalid object.");
+  }
+  throw runtime_error("OverlayedField::add: Attempt to add an invalid field.");
+}
+
+/// Returns the 3 electric field components (x, y, z).
+void OverlayedField::combinedElectric(const double* pos, double* field)   const {
+  field[0] = field[1] = field[2] = 0.;
+  calculate_combined_field(data<Object>()->electric_components,pos,field);
+}
+
+/// Returns the 3  magnetic field components (x, y, z).
+void OverlayedField::combinedMagnetic(const double* pos, double* field)   const {
+  field[0] = field[1] = field[2] = 0.;
+  calculate_combined_field(data<Object>()->magnetic_components,pos,field);
+}
+
+/// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]).
+void OverlayedField::electromagneticField(const double* pos, double* field)   const {
+  Object* o = data<Object>();
+  field[0] = field[1] = field[2] = 0.;
+  calculate_combined_field(o->electric_components,pos,field);
+  calculate_combined_field(o->magnetic_components,pos,field+3);
+}
diff --git a/DDCore/src/GeometryTreeDump.cpp b/DDCore/src/GeometryTreeDump.cpp
index 226bcde2d24d813bc17fb31a60018b06240fffb7..eaa62817e3afabcbc9ff9db38d4c9b339ec34236 100644
--- a/DDCore/src/GeometryTreeDump.cpp
+++ b/DDCore/src/GeometryTreeDump.cpp
@@ -39,7 +39,7 @@ namespace {
   string indent = "";
 
   /// Reference to output stream
-  std::ostream& m_output = cout;
+  ostream& m_output = cout;
 
 
   void getAngles(const Double_t* m, Double_t &phi, Double_t &theta, Double_t &psi)  {
diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp
index a898f94aee702a830eac31395810f25c7944e909..f884a5defd633b70742edaa85bb143f3ac0808ac 100644
--- a/DDCore/src/Handle.cpp
+++ b/DDCore/src/Handle.cpp
@@ -39,6 +39,20 @@ int DD4hep::Geometry::_toInt(const string& value)  {
   return (int)result;
 }
 
+long DD4hep::Geometry::_toLong(const string& value)  {
+  string s(value);
+  size_t idx = s.find("(int)");
+  if ( idx != string::npos ) 
+    s.erase(idx,5);
+  while(s[0]==' ')s.erase(0,1);
+  double result = eval.evaluate(s.c_str());
+  if (eval.status() != XmlTools::Evaluator::OK) {
+    cerr << value << ": ";
+    eval.print_error();
+  }
+  return (long)result;
+}
+
 bool   DD4hep::Geometry::_toBool(const string& value)   {
   return value == "true";
 }
@@ -61,19 +75,19 @@ double DD4hep::Geometry::_toDouble(const string& value)   {
   return result;
 }
 
-template <> int    _multiply<int>(const std::string& left, const std::string& right) {
+template <> int    _multiply<int>(const string& left, const string& right) {
   return (int)_toDouble(left+"*"+right);
 }
 
-template <> long   _multiply<long>(const std::string& left, const std::string& right) {
+template <> long   _multiply<long>(const string& left, const string& right) {
   return (long)_toDouble(left+"*"+right);
 }
 
-template <> float  _multiply<float>(const std::string& left, const std::string& right) {
+template <> float  _multiply<float>(const string& left, const string& right) {
   return _toFloat(left+"*"+right);
 }
 
-template <> double _multiply<double>(const std::string& left, const std::string& right) {
+template <> double _multiply<double>(const string& left, const string& right) {
   return _toDouble(left+"*"+right);
 }
 
@@ -129,7 +143,7 @@ namespace DD4hep { namespace Geometry {
     msg += " to ";
     msg += to.name();
     msg += " not possible!!";
-    throw std::runtime_error(msg);
+    throw runtime_error(msg);
   }
   template <typename T> void Handle<T>::assign(T* n, const string& nam, const string& tit) {
     this->m_element = n;
@@ -149,7 +163,7 @@ namespace DD4hep { namespace Geometry {
     msg += " to ";
     msg += to.name();
     msg += " not possible!!";
-    throw std::runtime_error(msg);
+    throw runtime_error(msg);
   }
 }}
 
diff --git a/DDCore/src/IDDescriptor.cpp b/DDCore/src/IDDescriptor.cpp
index 0efbb3792fb0a85300e98dc01d293b3a2f18368a..035c643d31f885306e43d57a565b3ce8dfdc0671 100644
--- a/DDCore/src/IDDescriptor.cpp
+++ b/DDCore/src/IDDescriptor.cpp
@@ -55,7 +55,7 @@ namespace {
 }
 
 /// Initializing constructor
-IDDescriptor::IDDescriptor(const std::string& description) 
+IDDescriptor::IDDescriptor(const string& description) 
 {
   Value<TNamed,Object>* obj = new Value<TNamed,Object>();
   assign(obj,description,"iddescriptor");
diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index fa24ab0a3990dc4ead65750cc1301f947f50dadd..e63b03766646b6f96d6b217af09ff97bb76b4fd4 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -21,21 +21,20 @@
 #include "TGeoVolume.h"
 #include "TGeoShape.h"
 #include "TClass.h"
+#include "Reflex/PluginService.h"
 
 #if DD4HEP_USE_PYROOT
   #include "TPython.h"
 #elif DD4HEP_USE_XERCESC
-  #include "compact/Conversions.h"
   #include "XML/DocumentHandler.h"
 #endif
 
-namespace DD4hep  { namespace Geometry { struct Compact; }}
 using namespace DD4hep::Geometry;
 using namespace DD4hep;
 using namespace std;
 namespace {
   struct TopDetElement : public DetElement {
-    TopDetElement(const std::string& nam, Volume vol) : DetElement(nam,/* "structure", */0) { _data().volume = vol;    }
+    TopDetElement(const string& nam, Volume vol) : DetElement(nam,/* "structure", */0) { _data().volume = vol;    }
   };
 }
 
@@ -44,7 +43,19 @@ LCDD& LCDD::getInstance() {
   return *s_lcdd; 
 }
 
-LCDDImp::LCDDImp() : m_world(), m_trackers(), m_worldVol(), m_trackingVol()  {
+/// Default constructor
+LCDDImp::LCDDImp() : m_world(), m_trackers(), m_worldVol(), m_trackingVol(), m_field("global")  
+{
+  m_properties = new Properties();
+  if ( 0 == gGeoManager ) {
+    gGeoManager = new TGeoManager();
+  }
+}
+
+/// Standard destructor
+LCDDImp::~LCDDImp() {
+  if ( m_properties ) delete m_properties;
+  m_properties = 0;
 }
 
 Volume LCDDImp::pickMotherVolume(const DetElement&) const  {     // throw if not existing
@@ -57,17 +68,14 @@ LCDD& LCDDImp::addDetector(const Ref_t& x)    {
   return *this;
 }
 
-void LCDDImp::convertMaterials(const string& fname)  {
-  //convertMaterials(XML::DocumentHandler().load(fname).root());
-}
-
-void LCDDImp::addStdMaterials()   {
-  convertMaterials("file:../cmt/elements.xml");
-  convertMaterials("file:../cmt/materials.xml");
+/// Add a field component by named reference to the detector description
+LCDD& LCDDImp::addField(const Ref_t& x) {
+  m_field.add(x);
+  m_fields.append(x);
+  return *this;
 }
 
-
-Handle<TObject> LCDDImp::getRefChild(const HandleMap& e, const std::string& name, bool do_throw)  const  {
+Handle<TObject> LCDDImp::getRefChild(const HandleMap& e, const string& name, bool do_throw)  const  {
   HandleMap::const_iterator i = e.find(name);
   if ( i != e.end() )  {
     return (*i).second;
@@ -135,13 +143,13 @@ void LCDDImp::endDocument()  {
     m_trackingVol.setRegion(trackingRegion);
     
     // Set the world volume to invisible.
-    VisAttr worldVis(lcdd,"WorldVis");
+    VisAttr worldVis("WorldVis");
     worldVis.setVisible(false);
     m_worldVol.setVisAttributes(worldVis);
     add(worldVis);
   
     // Set the tracking volume to invisible.
-    VisAttr trackingVis(lcdd,"TrackingVis");
+    VisAttr trackingVis("TrackingVis");
     trackingVis.setVisible(false);               
     m_trackingVol.setVisAttributes(trackingVis);
     add(trackingVis); 
@@ -155,12 +163,6 @@ void LCDDImp::endDocument()  {
   }
 }
 
-void LCDDImp::create()  {
-  if ( 0 == gGeoManager ) {
-    gGeoManager = new TGeoManager();
-  }
-}
-
 void LCDDImp::init()  {
   if ( !m_world.isValid() ) {
     Box worldSolid("world_box","world_x","world_y","world_z");
@@ -182,45 +184,46 @@ void LCDDImp::init()  {
   }
 }
 
-void LCDDImp::fromCompact(const std::string& xmlfile) {
-  create();
+void LCDDImp::fromXML(const string& xmlfile) {
 #if DD4HEP_USE_PYROOT
   string cmd;
   TPython::Exec("import lcdd");
-  cmd = "lcdd.fromCompact('" + xmlfile + "')";
+  cmd = "lcdd.fromXML('" + xmlfile + "')";
   TPython::Exec(cmd.c_str());  
 #elif DD4HEP_USE_XERCESC
-  XML::Handle_t compact = XML::DocumentHandler().load(xmlfile).root();
+  const XML::Handle_t xml_root = XML::DocumentHandler().load(xmlfile).root();
+  string tag = xml_root.tag();
   try {
-    Converter<Compact>(*this)(compact);
+    LCDD* lcdd = this;
+    string type = tag + "_XML_reader";
+    long result = ROOT::Reflex::PluginService::Create<long>(type,lcdd,&xml_root);
+    if ( 0 == result ) {
+      throw runtime_error("Failed to locate plugin to interprete files of type"
+			  " \""+tag+"\" - no factory:"+type);
+    }
+    result = *(long*)result;
+    if ( result != 1 ) {
+      throw runtime_error("Failed to parse the XML file "+xmlfile+" with the plugin "+type);
+    }
   }
   catch(const exception& e)  {
     cout << "Exception:" << e.what() << endl;
+    throw runtime_error("Exception:"+string(e.what())+" while parsing "+xmlfile);
   }
   catch(xercesc::DOMException& e)  {
     cout << "XML-DOM Exception:" << XML::_toString(e.msg) << endl;
+    throw runtime_error("XML-DOM Exception:"+XML::_toString(e.msg)+" while parsing "+xmlfile);
   } 
   catch(...)  {
     cout << "UNKNOWN Exception" << endl;
+    throw runtime_error("UNKNOWN excetion while parsing "+xmlfile);
   }
 #endif
 }
 
-void LCDDImp::applyAlignment()   {
-}
-
-#include "SimpleGDMLWriter.h"
-//#include "Geant4Converter.h"
-#include "GeometryTreeDump.h"
-
 void LCDDImp::dump() const  {
   TGeoManager* mgr = gGeoManager;
   mgr->SetVisLevel(4);
   mgr->SetVisOption(1);
   m_worldVol->Draw("ogl");
-
-  // SimpleGDMLWriter handler(cout);
-  // Geant4Converter handler;
-  //GeometryTreeDump handler;
-  //handler.create(m_world);
 }
diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h
index 8bcc7dd79de41ee2523e099a886f623296ae8d58..a3e5a514d58b607d74c547b9302ccf6f6d38f3f2 100644
--- a/DDCore/src/LCDDImp.h
+++ b/DDCore/src/LCDDImp.h
@@ -37,17 +37,6 @@ namespace DD4hep {
       
       struct ObjectHandleMap : public HandleMap  {
         ObjectHandleMap() {}
-#if 0
-        void append_noCheck(const Ref_t& e) { 
-          if ( e.isValid() )  {
-            std::string n = e.name();
-            if ( this->find(n) != this->end() ) {
-              throw InvalidObjectError("Object "+n+" is already present in map!");
-            }
-            this->insert(std::make_pair(n,e.ptr()));
-          }
-        }
-#endif
         void append(const Ref_t& e, bool throw_on_doubles=true) { 
           if ( e.isValid() )  {
             std::string n = e.name();
@@ -58,6 +47,7 @@ namespace DD4hep {
           }
           throw InvalidObjectError("Attempt to add an invalid object.");
         }
+
         template <typename T> void append(const Ref_t& e, bool throw_on_doubles=true) {
           T* obj = dynamic_cast<T*>(e.ptr());
           if ( obj )  {
@@ -67,7 +57,7 @@ namespace DD4hep {
           throw InvalidObjectError("Attempt to add an object, which is of the wrong type.");
         }
       };
-      
+		      
       ObjectHandleMap     m_readouts;
       ObjectHandleMap     m_header;
       ObjectHandleMap     m_idDict;
@@ -91,28 +81,37 @@ namespace DD4hep {
       
       Material            m_materialAir;
       Material            m_materialVacuum;
-      
+
+      OverlayedField      m_field;
       Ref_t               m_setup;
+      Properties*         m_properties;
       
-      void convertMaterials(const std::string& uri);
+      /// Default constructor
       LCDDImp();
 
+      /// Standard destructor
+      virtual ~LCDDImp();
+
 		      
       /// Read compact geometry description or alignment file
-      virtual void fromCompact(const std::string& fname);
+      virtual void fromCompact(const std::string& fname) { fromXML(fname);              }
+      /// Read any XML file
+      virtual void fromXML(const std::string& fname);
+      
+      virtual void dump() const;
+
       /// Apply & lock realigments
-      virtual void applyAlignment();
+      //virtual void applyAlignment();
       
-      virtual void create();
+      //virtual void create();
       virtual void init();
-      virtual void addStdMaterials();
       virtual void endDocument();
       
-      void dump() const;
-
       virtual Handle<TObject> getRefChild(const HandleMap& e, const std::string& name, bool throw_if_not=true)  const;
       virtual Volume          pickMotherVolume(const DetElement& sd) const;
 
+      /// Access to properties
+      Properties&             properties()  const      { return *m_properties;          }
       /// Return handle to material describing air
       virtual Material        air() const              { return m_materialVacuum;       }
       /// Return handle to material describing vacuum
@@ -125,37 +124,43 @@ namespace DD4hep {
       virtual Volume          worldVolume() const      { return m_worldVol;             }
       /// Return handle to the world volume containing the volume with the tracking devices
       virtual Volume          trackingVolume() const   { return m_trackingVol;          }
+      /// Return handle to the combined electromagentic field description.
+      virtual OverlayedField  field() const            { return m_field;                }
+
       
       /// Retrieve a constant by it's name from the detector description
       virtual Constant     constant(const std::string& name) const 
       {  return getRefChild(m_define,name);                                             }
       /// Retrieve a limitset by it's name from the detector description
-      virtual LimitSet     limitSet(const std::string& name)  const
+      virtual LimitSet          limitSet(const std::string& name)  const
       {  return getRefChild(m_limits,name);                                             }  
       /// Retrieve a visualization attribute by it's name from the detector description
-      virtual VisAttr      visAttributes(const std::string& name) const
+      virtual VisAttr           visAttributes(const std::string& name) const
       {  return getRefChild(m_display,name,false);                                      }  
       /// Retrieve a matrial by it's name from the detector description
-      virtual Material     material(const std::string& name)  const 
+      virtual Material          material(const std::string& name)  const 
       {  return getRefChild(m_materials,name);                                          }
       /// Retrieve a region object by it's name from the detector description
-      virtual Region       region(const std::string& name)  const
+      virtual Region            region(const std::string& name)  const
       {  return getRefChild(m_regions,name);                                            }
       /// Retrieve a id descriptor by it's name from the detector description
-      virtual IDDescriptor idSpecification(const std::string& name)  const
+      virtual IDDescriptor      idSpecification(const std::string& name)  const
       {  return getRefChild(m_idDict,name);                                             }
       /// Retrieve a readout object by it's name from the detector description
-      virtual Readout      readout(const std::string& name)  const
+      virtual Readout           readout(const std::string& name)  const
       {  return getRefChild(m_readouts,name);                                           }
       /// Retrieve an alignment entry by it's name from the detector description
-      virtual AlignmentEntry alignment(const std::string& path) const 
+      virtual AlignmentEntry    alignment(const std::string& path) const 
       {  return getRefChild(alignments(),path);                                         }
       /// Retrieve a subdetector element by it's name from the detector description
-      virtual DetElement   detector(const std::string& name)  const
+      virtual DetElement        detector(const std::string& name)  const
       {  return getRefChild(m_detectors,name);                                          }
       /// Retrieve a sensitive detector by it's name from the detector description
       virtual SensitiveDetector sensitiveDetector(const std::string& name)  const
       {  return getRefChild(m_sensitive,name,false);                                    }
+      /// Retrieve a subdetector element by it's name from the detector description
+      virtual CartesianField    field(const std::string& name)  const 
+      {  return getRefChild(m_fields,name,false);                                       }
       
       /// Accessor to the map of header entries
       virtual const HandleMap& header()  const          { return m_header;              }
@@ -175,7 +180,9 @@ namespace DD4hep {
       virtual const HandleMap& detectors()  const       { return m_detectors;           }
       /// Accessor to the map of aligment entries
       virtual const HandleMap& alignments()  const      { return m_alignments;          }
-      
+      /// Accessor to the map of field entries, which together form the global field
+      virtual const HandleMap& fields()  const          { return m_fields;              }
+
 #define __R  return *this
       /// Add a new constant to the detector description
       virtual LCDD& add(Constant x)                     { return addConstant(x);        }
@@ -195,6 +202,8 @@ namespace DD4hep {
       virtual LCDD& add(Readout x)                      { return addReadout(x);         }
       /// Add a new subdetector to the detector description
       virtual LCDD& add(DetElement x)                   { return addDetector(x);        }
+      /// Add a field component to the detector description
+      virtual LCDD& add(CartesianField x)               { return addField(x);           }
       
       /// Add a new constant by named reference to the detector description
       virtual LCDD& addConstant(const Ref_t& x)         { m_define.append(x,false); __R;}
@@ -216,6 +225,8 @@ namespace DD4hep {
       virtual LCDD& addDetector(const Ref_t& x);
       /// Add a new alignment entry by named reference to the detector description
       virtual LCDD& addAlignment(const Ref_t& x)        { m_alignments.append(x);   __R;}
+      /// Add a field component by named reference to the detector description
+      virtual LCDD& addField(const Ref_t& x);
 #undef __R
       
     };
diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp
index e1f839927eb15f0e55099f80742ea47accfe1d47..06da9a57b693c7d1d3d4d57dc8865beeadfeab88 100644
--- a/DDCore/src/Objects.cpp
+++ b/DDCore/src/Objects.cpp
@@ -24,7 +24,6 @@
 
 using namespace std;
 using namespace DD4hep::Geometry;
-using DD4hep::IDDescriptor;
 
 #if 0
 Header& Header::fromCompact(Document doc, Handle_t element, const string& fname)   {
@@ -57,16 +56,14 @@ Header::Header(LCDD& /* lcdd */)   {
 }
 
 /// Constructor to be used when creating a new DOM tree
-Constant::Constant(LCDD& lcdd, const string& nam, const string& val)
+Constant::Constant(const string& nam, const string& val)
 {
   m_element = new TNamed(nam.c_str(),val.c_str());
-  lcdd.add(*this);
 }
 
 /// Constructor to be used when creating a new DOM tree
-Constant::Constant(LCDD& lcdd, const string& name)   {
+Constant::Constant(const string& name)   {
   m_element = new TNamed(name.c_str(),"");
-  lcdd.add(*this);
 }
 
 /// String representation of this object
@@ -78,7 +75,7 @@ string Constant::toString()  const {
 }
 
 /// Constructor to be used when creating a new DOM tree
-Atom::Atom(LCDD& /* lcdd */, const string& name, const string& formula, int Z, int N, double density) {
+Atom::Atom(const string& name, const string& formula, int Z, int N, double density) {
   TGeoElementTable* t = TGeoElement::GetElementTable();
   TGeoElement* e = t->FindElement(name.c_str());
   if ( !e ) {
@@ -89,7 +86,7 @@ Atom::Atom(LCDD& /* lcdd */, const string& name, const string& formula, int Z, i
 }
 
 /// Constructor to be used when creating a new DOM tree
-Material::Material(LCDD& /* lcdd */, const string& name)   {
+Material::Material(const string& name)   {
   TGeoMaterial* mat = gGeoManager->GetMaterial(name.c_str());
   m_element = mat;
 }
@@ -104,7 +101,7 @@ string Material::toString()  const {
 }
 
 /// Constructor to be used when creating a new DOM tree
-VisAttr::VisAttr(LCDD& /* lcdd */, const string& name)    {
+VisAttr::VisAttr(const string& name)    {
   Value<TNamed,Object>* obj = new Value<TNamed,Object>();
   assign(obj, name, "vis");
   obj->color  = 2;
@@ -204,7 +201,7 @@ string VisAttr::toString()  const {
 }
 
 /// Constructor to be used when creating a new aligment entry
-AlignmentEntry::AlignmentEntry(LCDD& /* lcdd */, const string& path)   {
+AlignmentEntry::AlignmentEntry(const string& path)   {
   TGeoPhysicalNode* obj = new TGeoPhysicalNode(path.c_str());
   assign(obj,path,"*");
 }
@@ -242,7 +239,7 @@ int AlignmentEntry::align(const Position& pos, const Rotation& rot, bool check,
     m_element->Align(new_matrix,0,check,overlap);
     return 1;
   }
-  throw std::runtime_error("Callot align non existing physical node.");
+  throw runtime_error("Callot align non existing physical node.");
 }
 
 
@@ -270,7 +267,7 @@ bool Limit::operator< (const Limit& c) const {
 }
 
 /// Conversion to a string representation
-std::string Limit::toString()  const {
+string Limit::toString()  const {
   string res = name + " = " + content;
   if ( !unit.empty() ) res += unit + " ";
   res + " (" + particles + ")";
diff --git a/DDCore/src/Segementations.cpp b/DDCore/src/Segementations.cpp
index d72706489fd3d45c47c146a71288f6ff231b9648..b5503eca986164b040ce4bc67bebc4e110ecd1c0 100644
--- a/DDCore/src/Segementations.cpp
+++ b/DDCore/src/Segementations.cpp
@@ -41,7 +41,7 @@ const string Segmentation::type() const   {
 }
 
 /// Add an extension object to the detector element
-void* Segmentation::i_setExtension(void* ptr, const std::type_info& info, void (*destruct)(void*)) {
+void* Segmentation::i_setExtension(void* ptr, const type_info& info, void (*destruct)(void*)) {
   Object& o = _data();
   o.type = EXTENDED;
   o.data.extension.ptr = ptr;
@@ -51,7 +51,7 @@ void* Segmentation::i_setExtension(void* ptr, const std::type_info& info, void (
 }
 
 /// Access an existing extension object from the detector element
-void* Segmentation::i_extension(const std::type_info& info)   const {
+void* Segmentation::i_extension(const type_info& info)   const {
   if ( isValid() ) {
     Object::Data::Extension& o = _data().data.extension;
     if ( o.ptr )   {
@@ -143,13 +143,13 @@ GridXY::GridXY()
 : Segmentation("grid_xy")   {}
 
 /// Constructor to be used when creating a new object. Data are taken from the input handle
-GridXY::GridXY(const std::string& tag) 
+GridXY::GridXY(const string& tag) 
 : Segmentation(tag) 
 {
 }
 
 /// Constructor to be used when creating a new object.
-GridXY::GridXY(const std::string& tag, double size_x, double size_y)
+GridXY::GridXY(const string& tag, double size_x, double size_y)
 : Segmentation(tag)
 {
   _data().data.cartesian_grid.grid_size_x = size_x;
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index e87aa741b3daa0646064b192a6da477817490fea..984fa05fa0c510565697bab41eb9ace6b7c2417b 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -211,7 +211,7 @@ namespace DD4hep  { namespace Geometry  {
 }}
 
 /// Add identifier
-PlacedVolume& PlacedVolume::addPhysVolID(const std::string& name, int value)   {
+PlacedVolume& PlacedVolume::addPhysVolID(const string& name, int value)   {
   Object* obj = data<Object>();
   obj->volIDs[name] = value;
   return *this;
@@ -424,7 +424,7 @@ LimitSet Volume::limitSet() const
 {  return data<Object>()->limits;                           }
 
 /// Constructor to be used when creating a new geometry tree.
-Assembly::Assembly(const std::string& name) {
+Assembly::Assembly(const string& name) {
   m_element = new Value<TGeoVolumeAssembly,Volume::Object>(name.c_str());
 }
 
diff --git a/DDCore/src/XML/XMLDetector.cpp b/DDCore/src/XML/XMLDetector.cpp
index 90cf63613732d3cf174e0c69aab759977aea9bf0..f65fa6f80569dd4c8da386920b31addbf63c2490 100644
--- a/DDCore/src/XML/XMLDetector.cpp
+++ b/DDCore/src/XML/XMLDetector.cpp
@@ -55,6 +55,10 @@ double Dimension::zmin() const  {
   return m_element.attr<double>(Attr_zmin);
 }
 
+double Dimension::zmax() const  {
+  return m_element.attr<double>(Attr_zmax);
+}
+
 double Dimension::rmax() const  {
   return m_element.attr<double>(Attr_rmax);
 }
@@ -71,6 +75,10 @@ double Dimension::outer_r() const  {
   return m_element.attr<double>(Attr_outer_r);
 }
 
+double Dimension::outer_radius() const {
+  return m_element.attr<double>(Attr_outer_radius);
+}
+
 double Dimension::inner_z() const  {
   return m_element.attr<double>(Attr_inner_z);
 }
@@ -79,6 +87,10 @@ double Dimension::inner_r() const  {
   return m_element.attr<double>(Attr_inner_r);
 }
 
+double Dimension::inner_radius() const {
+  return m_element.attr<double>(Attr_inner_radius);
+}
+
 bool   Dimension::reflect() const  {
   return m_element.attr<bool>(Attr_reflect);
 }
@@ -250,6 +262,14 @@ double Dimension::zstart() const {
   return m_element.attr<double>(Attr_zstart);
 }
 
+double DetElement::inner_field() const {
+  return m_element.attr<double>(Attr_inner_field);
+}
+
+double DetElement::outer_field() const {
+  return m_element.attr<double>(Attr_outer_field);
+}
+
 int DetElement::Component::id()  const  {
   return m_element.attr<int>(Attr_id);
 }
diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp
index 568694b47188a8aa5aed2b244edad9eec835959b..3a9f3a91dbb2f2c75ef90aa95c76fc8e03d6cbc0 100644
--- a/DDCore/src/XML/XMLElements.cpp
+++ b/DDCore/src/XML/XMLElements.cpp
@@ -233,12 +233,26 @@ Tag_t& Tag_t::operator=(const string& s) {
   return *this;
 }
 
+/// Clone the DOMelement - with the option of a deep copy
 Handle_t Handle_t::clone(DOMDocument* new_doc, bool deep) const  {
   return (DOMElement*)new_doc->importNode(m_node, deep);
 }
 
+/// Retrieve a collection of all attributes of this DOM element
+vector<Attribute> Handle_t::attributes() const {
+  vector<Attribute> attrs;
+  if ( m_node ) {
+    xercesc::DOMNamedNodeMap* l = m_node->getAttributes();
+    for(XMLSize_t i=0, n=l->getLength(); i<n; ++i)  {
+      DOMNode* n = l->item(i);
+      attrs.push_back(Attribute(n));
+    }
+  }
+  return attrs;
+}
+
 size_t Handle_t::numChildren(const XMLCh* t, bool throw_exception) const  {
-  DOMNodeList* e = (DOMNodeList*)(m_node ? m_node->getElementsByTagName(t) : 0); 
+  NodeList e = (NodeList)(m_node ? m_node->getElementsByTagName(t) : 0); 
   if ( e || !throw_exception ) return e->getLength();
   string msg = "Handle_t::numChildren: ";
   if ( m_node )
@@ -248,19 +262,9 @@ size_t Handle_t::numChildren(const XMLCh* t, bool throw_exception) const  {
   throw runtime_error(msg);
 }
 
-Handle_t Handle_t::firstChild(const XMLCh* t) const  { 
-  DOMNodeList* e = (DOMNodeList*)(m_node ? m_node->getElementsByTagName(t) : 0); 
-  if ( e && e->getLength()>0 ) return (DOMElement*)e->item(0);
-  string msg = "Handle_t::firstChild: ";
-  if ( m_node )
-    msg += "Element ["+tag()+"] has no children of type '"+_toString(t)+"'";
-  else
-    msg += "Element [INVALID] has no children of type '"+_toString(t)+"'";
-  throw runtime_error(msg);
-}
-
 Handle_t Handle_t::child(const XMLCh* t, bool throw_exception) const   { 
-  DOMElement* e = (DOMElement*)(m_node ? m_node->getElementsByTagName(t)->item(0) : 0); 
+  NodeList    l = (NodeList)(m_node ? m_node->getElementsByTagName(t) : 0); 
+  DOMElement* e = (DOMElement*)(l ? l->item(0) : 0); 
   if ( e || !throw_exception ) return e;
   string msg = "Handle_t::child: ";
   if ( m_node )
@@ -270,29 +274,28 @@ Handle_t Handle_t::child(const XMLCh* t, bool throw_exception) const   {
   throw runtime_error(msg);
 }
 
-Handle_t Handle_t::remove(xercesc::DOMElement* node)  const  {
-  DOMElement* e = (DOMElement*)(m_node && node ? m_node->removeChild(node) : 0); 
+Handle_t Handle_t::remove(Handle_t node)  const  {
+  DOMElement* e = (DOMElement*)(m_node && node.ptr() ? m_node->removeChild(node.ptr()) : 0); 
   if ( e ) return e;
   string msg = "Handle_t::remove: ";
-  Handle_t n(node);
-  if ( m_node && n.ptr() )
-    msg += "Element ["+tag()+"] has no child of type '"+n.tag()+"'";
-  else if ( n )
-    msg += "Element [INVALID]. Cannot remove child of type: '"+n.tag()+"'";
-  else if ( n )
+  if ( m_node && node.ptr() )
+    msg += "Element ["+tag()+"] has no child of type '"+node.tag()+"'";
+  else if ( node )
+    msg += "Element [INVALID]. Cannot remove child of type: '"+node.tag()+"'";
+  else if ( node )
     msg += "Element [INVALID]. Cannot remove [INVALID] child. Big Shit!!!!";
 
   throw runtime_error(msg);
 }
 
 void Handle_t::removeChildren(const XMLCh* tag)  const  {
-  DOMNodeList* l=m_node->getElementsByTagName(tag);
+  NodeList l=m_node->getElementsByTagName(tag);
   for(XMLSize_t i=0, n=l->getLength(); i<n; ++i)
     m_node->removeChild(l->item(i));
 }
 
 bool Handle_t::hasChild(const XMLCh* tag) const   { 
-  DOMNodeList* n = m_node->getElementsByTagName(tag);
+  NodeList n = m_node->getElementsByTagName(tag);
   return n ? n->getLength()>0 : false;
 }
 
@@ -319,6 +322,10 @@ Attribute Handle_t::attr_ptr(const XMLCh* t)  const    {
   throw runtime_error(msg);
 }
 
+const XMLCh* Handle_t::attr_name(const Attribute attr)  const   {
+  return attr->getName();
+}
+
 const XMLCh* Handle_t::attr_value(const XMLCh* attr)  const   {
   return attr_ptr(attr)->getValue();
 }
@@ -375,7 +382,7 @@ Attribute Handle_t::setAttr(const XMLCh* name, const XMLCh* value) const  {
   return attr;
 }
 
-DOMElement* Document::createElt(const XMLCh* tag)  const {
+Handle_t Document::createElt(const XMLCh* tag)  const {
   return m_doc->createElement(tag);
 }
 
@@ -429,14 +436,14 @@ Handle_t Element::addChild(const XMLCh* tag)  const  {
 }
 
 Handle_t Element::child(const Strng_t& tag, bool throw_exception) const  {
-  DOMNodeList* l=m_element->getElementsByTagName(tag);
+  NodeList l=m_element->getElementsByTagName(tag);
   if ( l && l->getLength() > 0 ) return Handle_t((DOMElement*)l->item(0));
   if ( throw_exception ) throw runtime_error("Cannot find the required child node!");
   return Handle_t(0);
 }
 
 Handle_t Element::setChild(const XMLCh* tag)  const  {
-  DOMNodeList* l=m_element->getElementsByTagName(tag);
+  NodeList l=m_element->getElementsByTagName(tag);
   if ( l && l->getLength() > 0 ) return Handle_t((DOMElement*)l->item(0));
   return addChild(tag);
 }
@@ -472,46 +479,85 @@ void RefElement::setName(const XMLCh* new_name)  {
   setAttr(Attr_name,new_name);
 }
 
-Collection_t::Collection_t(DOMElement* n, const XMLCh* tag) : m_index(-1), m_element(n) {
-  m_children = n->getElementsByTagName(tag);
-  m_node = (DOMElement*)(m_children->getLength() == 0 ? 0 : n);
+Collection_t::Collection_t(Elt_t element, DOMNode::NodeType typ) 
+  : m_type(typ), m_index(-1)
+{
+  m_children = element->getChildNodes();
+  m_node = (DOMElement*)m_children->item(0);
   ++(*this);
 }
 
-Collection_t::Collection_t(DOMElement* n, const char* tag) : m_index(-1), m_element(n) {
-  m_children = n->getElementsByTagName(Tag_t(tag));
-  m_node = (DOMElement*)(m_children->getLength() == 0 ? 0 : n);//m_children->item(m_index));
+Collection_t::Collection_t(Elt_t element, const XMLCh* tag) 
+  : m_type(DOMNode::ELEMENT_NODE), m_index(-1)
+{
+  m_children = element->getElementsByTagName(tag);
+  m_node = (DOMElement*)m_children->item(0);
   ++(*this);
 }
 
-Collection_t::Collection_t(DOMElement* n, DOMNodeList* c) : m_index(-1), m_element(n), m_children(c) {
-  m_node = (DOMElement*)(m_children->getLength() == 0 ? 0 : n);
+Collection_t::Collection_t(Elt_t element, const char* tag)
+  : m_type(DOMNode::ELEMENT_NODE), m_index(-1)
+{
+  m_children = element->getElementsByTagName(Strng_t(tag));
+  m_node = (DOMElement*)m_children->item(0);
+  ++(*this);
+}
+
+Collection_t::Collection_t(NodeList node_list) 
+  : m_type(DOMNode::ELEMENT_NODE), m_index(-1), m_children(node_list)
+{
+  m_node = (DOMElement*)m_children->item(0);
+  ++(*this);
+}
+
+Collection_t::Collection_t(NodeList node_list, DOMNode::NodeType typ)
+  : m_type(typ), m_index(-1), m_children(node_list)
+{
+  m_node = (DOMElement*)m_children->item(0);
   ++(*this);
 }
 
 Collection_t& Collection_t::reset()  {
   m_index = -1;
-  m_node = (DOMElement*)(m_children->getLength() == 0 ? 0 : m_element);
+  m_node = (DOMElement*)(m_children->getLength() == 0 ? 0 : m_children->item(0));
   ++(*this);
   return *this;
 }
 
 size_t Collection_t::size()  const  {
-  return m_children ? m_children->getLength() : 0;
+  return m_children->getLength();
 }
 
 void Collection_t::operator++()  const  {
+  Elt_t e = Elt_t(m_node ? m_node->getParentNode() : 0);
   while(m_node)  {
-    //int t1 = m_node->getNodeType();
-    //int t2 = DOMNode::ELEMENT_NODE;
     m_node = (DOMElement*)m_children->item(++m_index);
-    if ( m_node && m_node->getNodeType() == DOMNode::ELEMENT_NODE ) {
-      if ( m_node->getParentNode() == m_element )
+    if ( m_node && m_node->getNodeType() == m_type ) {
+      if ( m_node->getParentNode() == e )
 	return;
     }
   }
 }
 
+void Collection_t::operator--()  const  {
+  Elt_t e = Elt_t(m_node ? m_node->getParentNode() : 0);
+  while(m_node)  {
+    m_node = (DOMElement*)m_children->item(--m_index);
+    if ( m_node && m_node->getNodeType() == m_type ) {
+      if ( m_node->getParentNode() == e )
+	return;
+    }
+  }
+}
+
+void Collection_t::operator++(int)  const  {
+  ++(*this);
+}
+
+void Collection_t::operator--(int)  const  {
+  --(*this);
+}
+
 Handle_t Document::clone(Handle_t source, bool deep) const  {
   return (DOMElement*)(m_doc->importNode(source,deep));
 }
diff --git a/DDCore/src/XML/XMLTags.cpp b/DDCore/src/XML/XMLTags.cpp
index eca4dd8088af56f52095d42811181c3788165e9c..fccbd6c1adbee5167cf9dd20215e438673444641 100644
--- a/DDCore/src/XML/XMLTags.cpp
+++ b/DDCore/src/XML/XMLTags.cpp
@@ -58,6 +58,10 @@ namespace DD4hep   { namespace XML  {
   TAG(fraction);
   TAG(composite);
   TAG(sd);
+  TAG(dipole_coeff);
+  ATTR(funit);
+  ATTR(global);
+  ATTR(local);
 
   TAG(box);
   TAG(define);
@@ -93,12 +97,15 @@ namespace DD4hep   { namespace XML  {
   TAG(tube);
   TAG(vis);
   TAG(visref);
+  TAG(strength);
   TAG(volume);
   TAG(volumeref);
   TAG(zplane);
 
   TAG(alignments);
   TAG(alignment);
+  TAG(properties);
+  TAG(attributes);
 
   ATTR(overlap);
   ATTR(check);
@@ -116,6 +123,10 @@ namespace DD4hep   { namespace XML  {
   ATTR(dimensions);
   ATTR(ecut);
   ATTR(false);
+  ATTR(strength);
+  ATTR(field);
+  ATTR(inner_field);
+  ATTR(outer_field);
   ATTR(field_name);
   ATTR(g);
   ATTR(gridSizeX);
@@ -125,6 +136,7 @@ namespace DD4hep   { namespace XML  {
   ATTR(hits_collection);
   TAG(identity_rot);
   TAG(identity_pos);
+  ATTR(inner_radius);
   ATTR(inner_r);
   ATTR(inner_z);
   ATTR(layer);
@@ -134,6 +146,7 @@ namespace DD4hep   { namespace XML  {
   ATTR(name);
   ATTR(nphi);
   ATTR(ntheta);
+  ATTR(outer_radius);
   ATTR(outer_r);
   ATTR(outer_z);
   ATTR(position);
@@ -146,6 +159,7 @@ namespace DD4hep   { namespace XML  {
   ATTR(region);
   ATTR(repeat);
   ATTR(zmin);
+  ATTR(zmax);
   ATTR(rmin);
   ATTR(rmax);
   ATTR(rotation);
@@ -174,6 +188,7 @@ namespace DD4hep   { namespace XML  {
   TAG(color);
   TAG(detectors);
   TAG(display);
+  TAG(field);
   TAG(fields);
   TAG(gdml);
   TAG(grid_xyz);
diff --git a/DDCore/src/compact/Compact2Objects.cpp b/DDCore/src/compact/Compact2Objects.cpp
index 0acf7f742002aecd3d4df88bcaacd31065c93bf7..78eb80f3edf609c36842f9c862e6342b2ee19a29 100644
--- a/DDCore/src/compact/Compact2Objects.cpp
+++ b/DDCore/src/compact/Compact2Objects.cpp
@@ -6,15 +6,14 @@
 //  Author     : M.Frank
 //
 //====================================================================
-
 #include "DD4hep/DetFactoryHelper.h"
 #include "DD4hep/IDDescriptor.h"
+#include "DD4hep/FieldTypes.h"
 #include "XML/DocumentHandler.h"
+#include "XML/Conversions.h"
 #include "xercesc/util/XMLURL.hpp"
 
-#include "Conversions.h"
 #include "TGeoManager.h"
-//#include "TGeoElement.h"
 #include "TGeoMaterial.h"
 #include "Reflex/PluginService.h"
 
@@ -26,6 +25,32 @@
 using namespace std;
 using namespace DD4hep;
 using namespace DD4hep::Geometry;
+
+namespace DD4hep { 
+  namespace Geometry {
+    struct Compact;
+    struct Includes;
+    struct GdmlFile;
+    struct Property;
+    struct AlignmentFile;
+  }
+  template <> void Converter<Constant>::operator()(const xml_h& e)  const;
+  template <> void Converter<Material>::operator()(const xml_h& e)  const;
+  template <> void Converter<Atom>::operator()(const xml_h& e)  const;
+  template <> void Converter<VisAttr>::operator()(const xml_h& e)  const;
+  template <> void Converter<AlignmentEntry>::operator()(const xml_h& e)  const;
+  template <> void Converter<Region>::operator()(const xml_h& e)  const;
+  template <> void Converter<Readout>::operator()(const xml_h& e)  const;
+  template <> void Converter<LimitSet>::operator()(const xml_h& e)  const;
+  template <> void Converter<Property>::operator()(const xml_h& e)  const;
+  template <> void Converter<CartesianField>::operator()(const xml_h& e)  const;
+  template <> void Converter<SensitiveDetector>::operator()(const xml_h& element)  const;
+  template <> void Converter<DetElement>::operator()(const xml_h& element)  const;
+  template <> void Converter<GdmlFile>::operator()(const xml_h& element)  const;
+  template <> void Converter<AlignmentFile>::operator()(const xml_h& element)  const;
+  template <> void Converter<Compact>::operator()(const xml_h& element)  const;
+}
+
 namespace {
   static UInt_t unique_mat_id = 0xAFFEFEED;
 }
@@ -85,450 +110,546 @@ static Ref_t create_ProjectiveZPlane(lcdd_t& /* lcdd */, const xml_h& e)  {
 }
 DECLARE_XMLELEMENT(ProjectiveZPlane,create_ProjectiveZPlane);
 
-namespace DD4hep { namespace Geometry {
-  struct Compact;
-  struct Includes;
-  struct GdmlFile;
-  struct AlignmentFile;
+static Ref_t create_ConstantField(lcdd_t& /* lcdd */, const xml_h& e)  {
+  CartesianField obj;
+  xml_comp_t field(e), strength(e.child(_X(strength)));
+  string t = e.attr<string>(_A(field));
+  Value<TNamed,ConstantField>* ptr = new Value<TNamed,ConstantField>();
+  ptr->type = ::toupper(t[0])=='E' ? CartesianField::ELECTRIC : CartesianField::MAGNETIC;
+  ptr->direction.set(strength.x(),strength.y(),strength.z());
+  obj.assign(ptr,field.nameStr(),field.typeStr());
+  return obj;
+}
+DECLARE_XMLELEMENT(ConstantField,create_ConstantField);
 
-  template <typename T> Handle<> toObject(LCDD& lcdd, const xml_h& xml);
-  
-  template <> Ref_t toRefObject<Constant>(lcdd_t& lcdd, const xml_h& e)  {
-    xml_ref_t    constant(e);
-    TNamed*      obj = new TNamed(constant.attr<string>(_A(name)).c_str(),
-                                  constant.attr<string>(_A(value)).c_str()); 
-    Ref_t        cons(obj);
-    _toDictionary(obj->GetName(),obj->GetTitle());
-    lcdd.addConstant(cons);
-    return cons;
+static Ref_t create_SolenoidField(lcdd_t& /* lcdd */, const xml_h& e)  {
+  xml_comp_t c(e);
+  CartesianField obj;
+  Value<TNamed,SolenoidField>* ptr = new Value<TNamed,SolenoidField>();
+  if ( c.hasAttr(_A(inner_radius)) ) ptr->innerRadius = c.attr<double>(_A(inner_radius));
+  if ( c.hasAttr(_A(outer_radius)) ) ptr->outerRadius = c.attr<double>(_A(outer_radius));
+  if ( c.hasAttr(_A(inner_field))  ) ptr->innerField  = c.attr<double>(_A(inner_field));
+  if ( c.hasAttr(_A(outer_field))  ) ptr->outerField  = c.attr<double>(_A(outer_field));
+  if ( c.hasAttr(_A(zmax))         ) ptr->maxZ        = c.attr<double>(_A(zmax));
+  if ( c.hasAttr(_A(zmin))         ) ptr->minZ        = c.attr<double>(_A(zmin));
+  else                               ptr->minZ        = - ptr->maxZ;
+  obj.assign(ptr,c.nameStr(),c.typeStr());
+  return obj;
+}
+DECLARE_XMLELEMENT(SolenoidMagnet,create_SolenoidField);
+
+static Ref_t create_DipoleField(lcdd_t& /* lcdd */, const xml_h& e)  {
+  xml_comp_t c(e);
+  CartesianField obj;
+  Value<TNamed,DipoleField>* ptr = new Value<TNamed,DipoleField>();
+  double val, lunit = c.attr<double>(_A(lunit)), funit = c.attr<double>(_A(funit));
+
+  if ( c.hasAttr(_A(zmin))  ) ptr->zmin  = _multiply<double>(c.attr<string>(_A(zmin)),lunit);
+  if ( c.hasAttr(_A(zmax))  ) ptr->zmax  = _multiply<double>(c.attr<string>(_A(zmax)),lunit);
+  if ( c.hasAttr(_A(rmax))  ) ptr->rmax  = _multiply<double>(c.attr<string>(_A(rmax)),lunit);
+  for( xml_coll_t coll(c,_X(dipole_coeff)); coll; ++coll)   {
+    val = funit/pow(lunit,ptr->coefficents.size());
+    val = _multiply<double>(coll.value(),val);
+    ptr->coefficents.push_back(val);
   }
-  
-  template <> Ref_t toRefObject<Atom>(lcdd_t& /* lcdd */, const xml_h& e)  {
-    /* <element Z="29" formula="Cu" name="Cu" >
-     <atom type="A" unit="g/mol" value="63.5456" />
-     </element>
-     */
-    xml_ref_t    elem(e);
-    xml_tag_t    eltname  = elem.name();
-    TGeoManager* mgr      = gGeoManager;
-    TGeoElementTable* tab = mgr->GetElementTable();
-    TGeoElement*  element = tab->FindElement(eltname.c_str());
-    if ( !element )  {
-      xml_ref_t atom(elem.child(_X(atom)));
-      tab->AddElement(elem.attr<string>(_A(name)).c_str(),
-                      elem.attr<string>(_A(formula)).c_str(),
-                      elem.attr<int>(_A(Z)),
-                      atom.attr<int>(_A(value))
-                      );
-      element = tab->FindElement(eltname.c_str());
-    }
-    return Ref_t(element);
+  obj.assign(ptr,c.nameStr(),c.typeStr());
+  return obj;
+} 
+DECLARE_XMLELEMENT(DipoleMagnet,create_DipoleField);
+
+static long create_Compact(lcdd_t& lcdd, const xml_h& element) {
+  Converter<Compact> converter(lcdd);
+  converter(element);
+  return 1;
+}
+DECLARE_XML_DOC_READER(lccdd,create_Compact);
+
+/** Convert compact constant objects (defines)
+ *
+ *
+ */
+template <> void Converter<Constant>::operator()(const xml_h& e)  const  {
+  xml_ref_t    constant(e);
+  TNamed*      obj = new TNamed(constant.attr<string>(_A(name)).c_str(),
+				constant.attr<string>(_A(value)).c_str()); 
+  Ref_t        cons(obj);
+  _toDictionary(obj->GetName(),obj->GetTitle());
+  lcdd.addConstant(cons);
+}
+
+/** Convert compact material/element description objects
+ *
+ *  Materials:
+ *  <material name="Air">
+ *    <D type="density" unit="g/cm3" value="0.0012"/>
+ *    <fraction n="0.754" ref="N"/>
+ *    <fraction n="0.234" ref="O"/>
+ *    <fraction n="0.012" ref="Ar"/>
+ *  </material>
+ *
+ *  Elements:
+ *  <element Z="29" formula="Cu" name="Cu" >
+ *    <atom type="A" unit="g/mol" value="63.5456" />
+ *  </element>
+ *
+ */
+template <> void Converter<Material>::operator()(const xml_h& e)  const  {
+  xml_ref_t         m(e);
+  TGeoManager*      mgr      = gGeoManager;
+  xml_tag_t         mname    = m.name();
+  const char*       matname  = mname.c_str();
+  xml_h             density  = m.child(XML::Tag_D);
+  TGeoElementTable* table    = mgr->GetElementTable();
+  TGeoMaterial*     mat      = mgr->GetMaterial(matname);
+  TGeoMixture*      mix      = dynamic_cast<TGeoMixture*>(mat);
+  xml_coll_t        fractions(m,_X(fraction));
+  xml_coll_t        composites(m,_X(composite));
+  set<string> elts;
+  if ( 0 == mat )  {
+    xml_h          radlen   = m.child(XML::Tag_RL,false);
+    xml_h          intlen   = m.child(XML::Tag_NIL,false);
+    double radlen_val = radlen.ptr() ? radlen.attr<double>(_A(value)) : 0.0;
+    double intlen_val = intlen.ptr() ? intlen.attr<double>(_A(value)) : 0.0;
+    mat = mix = new TGeoMixture(matname,composites.size(),density.attr<double>(_A(value)));
+    mat->SetRadLen(radlen_val,intlen_val);
+    //cout << "Compact2Objects[INFO]: Creating material:" << matname << " composites:" << composites.size()+fractions.size() << endl;
   }
-  
-  template <> Ref_t toRefObject<Material>(lcdd_t& /* lcdd */, const xml_h& e)  {
-    /*  <material name="Air">
-     <D type="density" unit="g/cm3" value="0.0012"/>
-     <fraction n="0.754" ref="N"/>
-     <fraction n="0.234" ref="O"/>
-     <fraction n="0.012" ref="Ar"/>
-     </material>
-     <element Z="29" formula="Cu" name="Cu" >
-     <atom type="A" unit="g/mol" value="63.5456" />
-     </element>
-     */
-    xml_ref_t         m(e);
-    TGeoManager*      mgr      = gGeoManager;
-    xml_tag_t         mname    = m.name();
-    const char*       matname  = mname.c_str();
-    xml_h             density  = m.child(XML::Tag_D);
-    TGeoElementTable* table    = mgr->GetElementTable();
-    TGeoMaterial*     mat      = mgr->GetMaterial(matname);
-    TGeoMixture*      mix      = dynamic_cast<TGeoMixture*>(mat);
-    xml_coll_t        fractions(m,_X(fraction));
-    xml_coll_t        composites(m,_X(composite));
-    set<string> elts;
-    if ( 0 == mat )  {
-      xml_h          radlen   = m.child(XML::Tag_RL,false);
-      xml_h          intlen   = m.child(XML::Tag_NIL,false);
-      double radlen_val = radlen.ptr() ? radlen.attr<double>(_A(value)) : 0.0;
-      double intlen_val = intlen.ptr() ? intlen.attr<double>(_A(value)) : 0.0;
-      mat = mix = new TGeoMixture(matname,composites.size(),density.attr<double>(_A(value)));
-      mat->SetRadLen(radlen_val,intlen_val);
-      //cout << "Compact2Objects[INFO]: Creating material:" << matname << " composites:" << composites.size()+fractions.size() << endl;
-    }
-    if ( mix )  {
-      for(Int_t i=0, n=mix->GetNelements(); i<n; ++i)
-        elts.insert(mix->GetElement(i)->GetName());
-    }
-    for(; composites; ++composites)  {
-      std::string nam = composites.attr<string>(_X(ref));
-      TGeoElement*   element;
-      if ( elts.find(nam) == elts.end() )  {
-        double fraction = composites.attr<double>(_X(n));
-        if ( 0 != (element=table->FindElement(nam.c_str())) )
-          mix->AddElement(element,fraction);
-        else if ( 0 != (mat=mgr->GetMaterial(nam.c_str())) )
-          mix->AddElement(mat,fraction);
-        else  {
-	  string msg = "Compact2Objects[ERROR]: Creating material:"+mname+" Element missing: "+nam;
-	  cout << msg << endl;
-	  throw runtime_error(msg);
-        }
+  if ( mix )  {
+    for(Int_t i=0, n=mix->GetNelements(); i<n; ++i)
+      elts.insert(mix->GetElement(i)->GetName());
+  }
+  for(; composites; ++composites)  {
+    std::string nam = composites.attr<string>(_X(ref));
+    TGeoElement*   element;
+    if ( elts.find(nam) == elts.end() )  {
+      double fraction = composites.attr<double>(_X(n));
+      if ( 0 != (element=table->FindElement(nam.c_str())) )
+	mix->AddElement(element,fraction);
+      else if ( 0 != (mat=mgr->GetMaterial(nam.c_str())) )
+	mix->AddElement(mat,fraction);
+      else  {
+	string msg = "Compact2Objects[ERROR]: Creating material:"+mname+" Element missing: "+nam;
+	cout << msg << endl;
+	throw runtime_error(msg);
       }
     }
-    for(; fractions; ++fractions)  {
-      std::string nam = fractions.attr<string>(_X(ref));
-      TGeoElement*   element;
-      if ( elts.find(nam) == elts.end() )  {
-        double fraction = fractions.attr<double>(_X(n));
-        if ( 0 != (element=table->FindElement(nam.c_str())) )
-          mix->AddElement(element,fraction);
-        else if ( 0 != (mat=mgr->GetMaterial(nam.c_str())) )
-          mix->AddElement(mat,fraction);
-        else  {
-	  string msg = "Compact2Objects[ERROR]: Creating material:"+mname+" Element missing: "+nam;
-	  cout << msg << endl;
-	  throw runtime_error(msg);
-        }
+  }
+  for(; fractions; ++fractions)  {
+    std::string nam = fractions.attr<string>(_X(ref));
+    TGeoElement*   element;
+    if ( elts.find(nam) == elts.end() )  {
+      double fraction = fractions.attr<double>(_X(n));
+      if ( 0 != (element=table->FindElement(nam.c_str())) )
+	mix->AddElement(element,fraction);
+      else if ( 0 != (mat=mgr->GetMaterial(nam.c_str())) )
+	mix->AddElement(mat,fraction);
+      else  {
+	string msg = "Compact2Objects[ERROR]: Creating material:"+mname+" Element missing: "+nam;
+	cout << msg << endl;
+	throw runtime_error(msg);
       }
     }
-    TGeoMedium* medium = mgr->GetMedium(matname);
-    if ( 0 == medium )  {
-      --unique_mat_id;
-      medium = new TGeoMedium(matname,unique_mat_id,mat);
-      medium->SetTitle("material");
-      medium->SetUniqueID(unique_mat_id);
-    }
-    return Ref_t(medium);
-  }
-  
-  template <> Ref_t toRefObject<IDDescriptor>(lcdd_t& /* lcdd */, const xml_h& e)  {
-    /*     <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id>   */
-    IDDescriptor id(e.text());
-    return Ref_t(id);
   }
-  
-  template <> Ref_t toRefObject<LimitSet>(lcdd_t& lcdd, const xml_h& e)  {
-    /*      <limitset name="...."> 
-     *        <limit name="step_length_max" particles="*" value="5.0" unit="mm" />
-     *  ... </limitset>
-     */
-    LimitSet ls(e.attr<string>(_A(name)));
-    for (xml_coll_t c(e,XML::Tag_limit); c; ++c) {
-      Limit limit;
-      limit.particles = c.attr<string>(_A(particles));
-      limit.name      = c.attr<string>(_A(name));
-      limit.content   = c.attr<string>(_A(value));
-      limit.unit      = c.attr<string>(_A(unit));
-      limit.value     = _multiply<double>(limit.content,limit.unit);
-      ls.addLimit(limit);
-    }
-    return ls;
+  TGeoMedium* medium = mgr->GetMedium(matname);
+  if ( 0 == medium )  {
+    --unique_mat_id;
+    medium = new TGeoMedium(matname,unique_mat_id,mat);
+    medium->SetTitle("material");
+    medium->SetUniqueID(unique_mat_id);
   }
-  
-  /// Convert compact visualization attribute to LCDD visualization attribute
-  template <> Ref_t toRefObject<VisAttr>(lcdd_t& lcdd, const xml_h& e)  {
-    /*    <vis name="SiVertexBarrelModuleVis" alpha="1.0" r="1.0" g="0.75" b="0.76" drawingStyle="wireframe" showDaughters="false" visible="true"/>
-     */
-    VisAttr attr(lcdd,e.attr<string>(_A(name)));
-    float r = e.hasAttr(_A(r)) ? e.attr<float>(_A(r)) : 1.0f;
-    float g = e.hasAttr(_A(g)) ? e.attr<float>(_A(g)) : 1.0f;
-    float b = e.hasAttr(_A(b)) ? e.attr<float>(_A(b)) : 1.0f;
-    attr.setColor(r,g,b);
-    if ( e.hasAttr(_A(alpha))         ) attr.setAlpha(e.attr<float>(_A(alpha)));
-    if ( e.hasAttr(_A(visible))       ) attr.setVisible(e.attr<bool>(_A(visible)));
-    if ( e.hasAttr(_A(lineStyle))     )   {
-      string ls = e.attr<string>(_A(lineStyle));
-      if ( ls == "unbroken" ) attr.setLineStyle(VisAttr::SOLID);
-      if ( ls == "broken" ) attr.setLineStyle(VisAttr::DASHED);
-    }
-    else  {
-      attr.setLineStyle(VisAttr::SOLID);
-    }
-    if ( e.hasAttr(_A(drawingStyle))  )   {
-      string ds = e.attr<string>(_A(drawingStyle));
-      if ( ds == "wireframe" ) attr.setDrawingStyle(VisAttr::WIREFRAME);
-    }
-    else  {
-      attr.setDrawingStyle(VisAttr::WIREFRAME);
-    }
-    if ( e.hasAttr(_A(showDaughters)) ) attr.setShowDaughters(e.attr<bool>(_A(showDaughters)));
-    return attr;
+    
+  lcdd.addMaterial(Ref_t(medium));
+}
+
+/** Convert compact atom objects
+ *
+ *   <element Z="29" formula="Cu" name="Cu" >
+ */
+template <> void Converter<Atom>::operator()(const xml_h& e)  const  {
+  xml_ref_t    elem(e);
+  xml_tag_t    eltname  = elem.name();
+  TGeoManager* mgr      = gGeoManager;
+  TGeoElementTable* tab = mgr->GetElementTable();
+  TGeoElement*  element = tab->FindElement(eltname.c_str());
+  if ( !element )  {
+    xml_ref_t atom(elem.child(_X(atom)));
+    tab->AddElement(elem.attr<string>(_A(name)).c_str(),
+		    elem.attr<string>(_A(formula)).c_str(),
+		    elem.attr<int>(_A(Z)),
+		    atom.attr<int>(_A(value))
+		    );
+    element = tab->FindElement(eltname.c_str());
   }
+}
 
-  template <> Ref_t toRefObject<Readout>(lcdd_t& lcdd, const xml_h& e)  {
-    /* <readout name="HcalBarrelHits">
-     <segmentation type="RegularNgonCartesianGridXY" gridSizeX="3.0*cm" gridSizeY="3.0*cm" />
-     <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id>
-     </readout>
-     */
-    const xml_h  id = e.child(_X(id));
-    const xml_h seg = e.child(_X(segmentation),false);
-    string  name = e.attr<string>(_A(name));
-    Readout ro(name);
-
-    if ( seg )  { // Segmentation is not mandatory!
-      string type = seg.attr<string>(_A(type));
-      Ref_t segment(ROOT::Reflex::PluginService::Create<TNamed*>(type,&lcdd,&seg));
-      if ( !segment.isValid() ) throw runtime_error("FAILED to create segmentation:"+type);
-      ro.setSegmentation(segment);
-    }
-    if ( id )  {
-      Ref_t idSpec = toRefObject<IDDescriptor>(lcdd,id);
-      idSpec->SetName(ro.name());
-      ro.setIDDescriptor(idSpec);
-      lcdd.addIDSpecification(idSpec);
-    }
-    return ro;
+/** Convert compact visualization attribute to LCDD visualization attribute
+ *
+ *  <vis name="SiVertexBarrelModuleVis" 
+ *       alpha="1.0" r="1.0" g="0.75" b="0.76" 
+ *       drawingStyle="wireframe" 
+ *       showDaughters="false" 
+ *       visible="true"/>
+ */
+template <> void Converter<VisAttr>::operator()(const xml_h& e)  const  {
+  VisAttr attr(e.attr<string>(_A(name)));
+  float r = e.hasAttr(_A(r)) ? e.attr<float>(_A(r)) : 1.0f;
+  float g = e.hasAttr(_A(g)) ? e.attr<float>(_A(g)) : 1.0f;
+  float b = e.hasAttr(_A(b)) ? e.attr<float>(_A(b)) : 1.0f;
+  attr.setColor(r,g,b);
+  if ( e.hasAttr(_A(alpha))         ) attr.setAlpha(e.attr<float>(_A(alpha)));
+  if ( e.hasAttr(_A(visible))       ) attr.setVisible(e.attr<bool>(_A(visible)));
+  if ( e.hasAttr(_A(lineStyle))     )   {
+    string ls = e.attr<string>(_A(lineStyle));
+    if ( ls == "unbroken" ) attr.setLineStyle(VisAttr::SOLID);
+    if ( ls == "broken" ) attr.setLineStyle(VisAttr::DASHED);
+  }
+  else  {
+    attr.setLineStyle(VisAttr::SOLID);
+  }
+  if ( e.hasAttr(_A(drawingStyle))  )   {
+    string ds = e.attr<string>(_A(drawingStyle));
+    if ( ds == "wireframe" ) attr.setDrawingStyle(VisAttr::WIREFRAME);
+  }
+  else  {
+    attr.setDrawingStyle(VisAttr::WIREFRAME);
   }
+  if ( e.hasAttr(_A(showDaughters)) ) attr.setShowDaughters(e.attr<bool>(_A(showDaughters)));
+  lcdd.addVisAttribute(attr);
+}
 
-  template <> Ref_t toRefObject<AlignmentEntry>(lcdd_t& lcdd, const xml_h& e)  {
-    /* <alignment name="<path/to/object>"  shortcut="short_cut_name">
-       <position x="x-value" y="y-value" z="z-value"/>
-       <rotation theta="theta-value" phi="phi-value" psi="psi-value"/>
-     </alignment>
-     */
-    xml_comp_t child(e);
-    string  path = e.attr<string>(_A(name));
-    bool check   = e.hasAttr(_A(check));
-    bool overlap = e.hasAttr(_A(overlap));
-    AlignmentEntry alignment(lcdd,path);
-    Position pos;
-    Rotation rot;
-    if ( (child=e.child(_X(position),false)) )  { // Position is not mandatory!
-      pos.x = child.x();
-      pos.y = child.y();
-      pos.z = child.z();
-    }
-    if ( (child=e.child(_X(rotation),false)) )  {  // Rotation is not mandatory
-      rot.theta = child.x(); // child.theta();
-      rot.phi   = child.y(); // child.phi();
-      rot.psi   = child.z(); // child.psi();
-    }
-    if ( overlap ) {
-      double ovl = e.attr<double>(_A(overlap));
-      alignment.align(pos,rot,check,ovl);
-    }
-    else {
-      alignment.align(pos,rot,check);
-    }
-    return alignment;
+/** Specialized converter for compact AlignmentEntry objects.
+ *
+ *  <alignment name="<path/to/object>"  shortcut="short_cut_name">
+ *    <position x="x-value" y="y-value" z="z-value"/>
+ *    <rotation theta="theta-value" phi="phi-value" psi="psi-value"/>
+ *  </alignment>
+ */
+template <> void Converter<AlignmentEntry>::operator()(const xml_h& e)  const  {
+  xml_comp_t child(e);
+  string  path = e.attr<string>(_A(name));
+  bool check   = e.hasAttr(_A(check));
+  bool overlap = e.hasAttr(_A(overlap));
+  AlignmentEntry alignment(path);
+  Position pos;
+  Rotation rot;
+  if ( (child=e.child(_X(position),false)) )  { // Position is not mandatory!
+    pos.x = child.x();
+    pos.y = child.y();
+    pos.z = child.z();
   }
-  
-  namespace  {
-    template <typename T> static Ref_t toRefObject(LCDD& lcdd, const xml_h& xml, SensitiveDetector& sens) 
-    {  return toRefObject<T>(lcdd,xml,sens); }
+  if ( (child=e.child(_X(rotation),false)) )  {  // Rotation is not mandatory
+    rot.theta = child.x(); // child.theta();
+    rot.phi   = child.y(); // child.phi();
+    rot.psi   = child.z(); // child.psi();
   }
-  
-  template <> Ref_t toRefObject<Region>(lcdd_t& /* lcdd */, const xml_h& e)  {
-    Region region(e.attr<string>(_A(name)));
-    vector<string>& limits = region.limits();
-    string ene = e.attr<string>(_A(eunit)), len = e.attr<string>(_A(lunit));    
-
-    region.setEnergyUnit(ene);
-    region.setLengthUnit(len);
-    region.setCut(_multiply<double>(e.attr<string>(_A(cut)),len));
-    region.setThreshold(_multiply<double>(e.attr<string>(_A(threshold)),ene));
-    region.setStoreSecondaries(e.attr<bool>(_A(store_secondaries)));
-    for(xml_coll_t user_limits(e,_X(limitsetref)); user_limits; ++user_limits)
-      limits.push_back(user_limits.attr<string>(_A(name)));
-    return region;
+  if ( overlap ) {
+    double ovl = e.attr<double>(_A(overlap));
+    alignment.align(pos,rot,check,ovl);
   }
-  
-  template <> void Converter<Constant>::operator()(const xml_h& element)  const  {
-    lcdd.addConstant(toRefObject<to_type>(lcdd,element));
+  else {
+    alignment.align(pos,rot,check);
   }
-  template <> void Converter<Material>::operator()(const xml_h& element)  const  {
-    lcdd.addMaterial(toRefObject<to_type>(lcdd,element));
+  lcdd.addAlignment(alignment);
+}
+
+/** Specialized converter for compact region objects.
+ *
+ */
+template <> void Converter<Region>::operator()(const xml_h& e)  const {
+  Region region(e.attr<string>(_A(name)));
+  vector<string>& limits = region.limits();
+  string ene = e.attr<string>(_A(eunit)), len = e.attr<string>(_A(lunit));    
+
+  region.setEnergyUnit(ene);
+  region.setLengthUnit(len);
+  region.setCut(_multiply<double>(e.attr<string>(_A(cut)),len));
+  region.setThreshold(_multiply<double>(e.attr<string>(_A(threshold)),ene));
+  region.setStoreSecondaries(e.attr<bool>(_A(store_secondaries)));
+  for(xml_coll_t user_limits(e,_X(limitsetref)); user_limits; ++user_limits)
+    limits.push_back(user_limits.attr<string>(_A(name)));
+  lcdd.addRegion(region);
+}
+
+/** Specialized converter for compact readout objects.
+ *
+ * <readout name="HcalBarrelHits">
+ *  <segmentation type="RegularNgonCartesianGridXY" gridSizeX="3.0*cm" gridSizeY="3.0*cm" />
+ *  <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id>
+ *  </readout>
+ */
+template <> void Converter<Readout>::operator()(const xml_h& e)  const {
+  const xml_h  id = e.child(_X(id));
+  const xml_h seg = e.child(_X(segmentation),false);
+  string  name = e.attr<string>(_A(name));
+  Readout ro(name);
+
+  if ( seg )  { // Segmentation is not mandatory!
+    string type = seg.attr<string>(_A(type));
+    Ref_t segment(ROOT::Reflex::PluginService::Create<TNamed*>(type,&lcdd,&seg));
+    if ( !segment.isValid() ) throw runtime_error("FAILED to create segmentation:"+type);
+    ro.setSegmentation(segment);
   }
-  template <> void Converter<Atom>::operator()(const xml_h& element)  const  {
-    toRefObject<to_type>(lcdd,element);
+  if ( id )  {
+    //  <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> 
+    Ref_t idSpec = IDDescriptor(id.text());
+    idSpec->SetName(ro.name());
+    ro.setIDDescriptor(idSpec);
+    lcdd.addIDSpecification(idSpec);
   }
-  template <> void Converter<VisAttr>::operator()(const xml_h& element)  const  {
-    lcdd.addVisAttribute(toRefObject<to_type>(lcdd,element));
+  lcdd.addReadout(ro);
+}
+
+/** Specialized converter for compact LimitSet objects.
+ *
+ *      <limitset name="...."> 
+ *        <limit name="step_length_max" particles="*" value="5.0" unit="mm" />
+ *  ... </limitset>
+ */
+template <> void Converter<LimitSet>::operator()(const xml_h& e)  const {
+  LimitSet ls(e.attr<string>(_A(name)));
+  for (xml_coll_t c(e,XML::Tag_limit); c; ++c) {
+    Limit limit;
+    limit.particles = c.attr<string>(_A(particles));
+    limit.name      = c.attr<string>(_A(name));
+    limit.content   = c.attr<string>(_A(value));
+    limit.unit      = c.attr<string>(_A(unit));
+    limit.value     = _multiply<double>(limit.content,limit.unit);
+    ls.addLimit(limit);
   }
-  template <> void Converter<AlignmentEntry>::operator()(const xml_h& element)  const  {
-    lcdd.addAlignment(toRefObject<to_type>(lcdd,element));
+  lcdd.addLimitSet(ls);
+}
+
+/** Specialized converter for generic LCDD properties
+ *
+ *      <properties>
+ *        <attributes name="key" type="" .... />
+ *  ... </properties>
+ */
+template <> void Converter<Property>::operator()(const xml_h& e)  const {
+  string name = e.attr<string>(_A(name));
+  LCDD::Properties& prp = lcdd.properties();
+  if ( name.empty() ) {
+    throw runtime_error("Failed to convert properties. No name given!");
   }
-  template <> void Converter<Region>::operator()(const xml_h& element)  const {
-    lcdd.addRegion(toRefObject<to_type>(lcdd,element));
+  vector<xml_attr_t> a = e.attributes();
+  if ( prp.find(name) == prp.end() ) {
+    prp.insert(make_pair(name,LCDD::PropertyValues()));
   }
-  template <> void Converter<Readout>::operator()(const xml_h& element)  const {
-    lcdd.addReadout(toRefObject<to_type>(lcdd,element));
+  for( vector<xml_attr_t>::iterator i=a.begin(); i != a.end(); ++i)  {
+    pair<string,string> val(xml_tag_t(e.attr_name(*i)),e.attr<string>(*i));
+    prp[name].insert(val);
   }
-  template <> void Converter<LimitSet>::operator()(const xml_h& element)  const {
-    lcdd.addLimitSet(toRefObject<to_type>(lcdd,element));
+}
+
+/** Specialized converter for electric and magnetic fields
+ *
+ *  Uses internally a plugin to allow flexible field descriptions.
+ * 
+ *     <field type="ConstantField" name="Myfield" field="electric">
+ *       <strength x="0" y="0" z="5"/>
+ *     </field>
+ */
+template <> void Converter<CartesianField>::operator()(const xml_h& e)  const  {
+  string msg = "updated";
+  string name = e.attr<string>(_A(name));
+  string type = e.attr<string>(_A(type));
+  CartesianField field = lcdd.field(name);
+  if ( !field.isValid() ) {
+    // The field is not present: We create it and add it to LCDD
+    field = Ref_t(ROOT::Reflex::PluginService::Create<TNamed*>(type,&lcdd,&e));
+    if ( !field.isValid() ) {
+      throw runtime_error("Failed to create field object of type "+type);
+    }
+    lcdd.addField(field);
+    msg = "created";
   }
-  void setChildTitles(const pair<string,DetElement>& e) {
-    DetElement parent = e.second.parent();
-    const DetElement::Children& children = e.second.children();
-    if ( strlen(e.second->GetTitle()) == 0 ) {
-      e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
+  type = field.type();
+  // Now update the field structure with the generic part ie. set it's properties
+  CartesianField::Properties& prp = field.properties();
+  for( xml_coll_t c(e,_X(properties)); c; ++c)   {
+    string    props_name = c.attr<string>(_A(name));
+    vector<xml_attr_t> a = c.attributes();
+    if ( prp.find(props_name) == prp.end() ) {
+      prp.insert(make_pair(props_name,CartesianField::PropertyValues()));
+    }
+    for( vector<xml_attr_t>::iterator i=a.begin(); i != a.end(); ++i)  {
+      pair<string,string> val(xml_tag_t(c.attr_name(*i)),c.attr<string>(*i));
+      prp[props_name].insert(val);
     }
-    else {
-      //cout << "Title present: " << e.second->GetTitle() << endl;
+    if ( c.hasAttr(_A(global)) && c.attr<bool>(_A(global)) ) {
+      lcdd.field().properties() = prp;
     }
-    for_each(children.begin(),children.end(),setChildTitles);
   }
+  cout << "Converted field: Successfully " << msg << " field " << name << " [" << type << "]" << endl;
+}
 
+/** Update sensitive detectors from group tags.
+ *
+ *  Handle xml sections of the type:
+ *  <sd name="MuonBarrel"
+ *      type="Geant4Calorimeter" 
+ *      ecut="100.0*MeV" 
+ *      verbose="true" 
+ *      hit_aggregation="position"
+ *      limits="limit-set-reference"
+ *      region="region-name-reference">
+ *  </sd>
+ *
+ */
+template <> void Converter<SensitiveDetector>::operator()(const xml_h& element)  const {
+  string name = element.attr<string>(_A(name));
+  try {
+    DetElement        det = lcdd.detector(name);
+    SensitiveDetector sd  = lcdd.sensitiveDetector(name);
 
-  /** Update sensitive detectors from group tags.
-   *
-   *  Handle xml sections of the type:
-   *  <sd name="MuonBarrel"
-   *      type="Geant4Calorimeter" 
-   *      ecut="100.0*MeV" 
-   *      verbose="true" 
-   *      hit_aggregation="position"
-   *      limits="limit-set-reference"
-   *      region="region-name-reference">
-   *  </sd>
-   *
-   */
-  template <> void Converter<SensitiveDetector>::operator()(const xml_h& element)  const {
-    string name = element.attr<string>(_A(name));
-    try {
-      DetElement        det = lcdd.detector(name);
-      SensitiveDetector sd  = lcdd.sensitiveDetector(name);
-
-      xml_attr_t type  = element.attr_nothrow(_A(type));
-      if ( type ) {
-	sd.setType(element.attr<string>(type));
-      }
-      xml_attr_t verbose = element.attr_nothrow(_A(verbose));
-      if ( verbose ) {
-	sd.setVerbose(element.attr<bool>(verbose));
-      }
-      xml_attr_t combine = element.attr_nothrow(_A(combine_hits));
-      if ( combine ) {
-	sd.setCombineHits(element.attr<bool>(combine));
-      }
-      xml_attr_t limits  = element.attr_nothrow(_A(limits));
-      if ( limits ) {
-	string   l  = element.attr<string>(limits);
-	LimitSet ls = lcdd.limitSet(l);
-	if ( !ls.isValid() )  {
-	  throw runtime_error("Converter<SensitiveDetector>: Request for non-existing limitset:"+l);
-	}
-	sd.setLimitSet(ls);
-      }
-      xml_attr_t region  = element.attr_nothrow(_A(region));
-      if ( region ) {
-	string r   = element.attr<string>(region);
-	Region reg = lcdd.region(r);
-	if ( !reg.isValid() )  {
-	  throw runtime_error("Converter<SensitiveDetector>: Request for non-existing region:"+r);
-	}
-	sd.setRegion(reg);
-      }
-      xml_attr_t hits    = element.attr_nothrow(_A(hits_collection));
-      if ( hits ) {
-	sd.setHitsCollection(element.attr<string>(hits));
-      }
-      xml_attr_t ecut  = element.attr_nothrow(_A(ecut));
-      xml_attr_t eunit = element.attr_nothrow(_A(eunit));
-      if ( ecut && eunit ) {
-	double value = _multiply<double>(_toString(ecut),_toString(eunit));
-	sd.setEnergyCutoff(value);
-      }
-      else if ( ecut ) { // If no unit is given , we assume the correct Geant4 unit is used!
-	sd.setEnergyCutoff(element.attr<double>(ecut));
+    xml_attr_t type  = element.attr_nothrow(_A(type));
+    if ( type ) {
+      sd.setType(element.attr<string>(type));
+    }
+    xml_attr_t verbose = element.attr_nothrow(_A(verbose));
+    if ( verbose ) {
+      sd.setVerbose(element.attr<bool>(verbose));
+    }
+    xml_attr_t combine = element.attr_nothrow(_A(combine_hits));
+    if ( combine ) {
+      sd.setCombineHits(element.attr<bool>(combine));
+    }
+    xml_attr_t limits  = element.attr_nothrow(_A(limits));
+    if ( limits ) {
+      string   l  = element.attr<string>(limits);
+      LimitSet ls = lcdd.limitSet(l);
+      if ( !ls.isValid() )  {
+	throw runtime_error("Converter<SensitiveDetector>: Request for non-existing limitset:"+l);
       }
-      if ( sd.verbose() ) {
-	cout << "SensitiveDetector-update:" << setw(18) << left << sd.name() 
-	     << setw(24)  << left << " ["+sd.type()+"] " 
-	     << "Hits:"   << setw(24) << left << sd.hitsCollection()
-	     << "Cutoff:" << sd.energyCutoff()
-	     << endl;
+      sd.setLimitSet(ls);
+    }
+    xml_attr_t region  = element.attr_nothrow(_A(region));
+    if ( region ) {
+      string r   = element.attr<string>(region);
+      Region reg = lcdd.region(r);
+      if ( !reg.isValid() )  {
+	throw runtime_error("Converter<SensitiveDetector>: Request for non-existing region:"+r);
       }
+      sd.setRegion(reg);
     }
-    catch(const exception& e) {
-      cout << "FAILED    to convert sensitive detector:" << name << ": " << e.what() << endl;
+    xml_attr_t hits    = element.attr_nothrow(_A(hits_collection));
+    if ( hits ) {
+      sd.setHitsCollection(element.attr<string>(hits));
     }
-    catch(...) {
-      cout << "FAILED    to convert sensitive detector:" << name << ": UNKNONW Exception" << endl;
+    xml_attr_t ecut  = element.attr_nothrow(_A(ecut));
+    xml_attr_t eunit = element.attr_nothrow(_A(eunit));
+    if ( ecut && eunit ) {
+      double value = _multiply<double>(_toString(ecut),_toString(eunit));
+      sd.setEnergyCutoff(value);
     }
+    else if ( ecut ) { // If no unit is given , we assume the correct Geant4 unit is used!
+      sd.setEnergyCutoff(element.attr<double>(ecut));
+    }
+    if ( sd.verbose() ) {
+      cout << "SensitiveDetector-update:" << setw(18) << left << sd.name() 
+	   << setw(24)  << left << " ["+sd.type()+"] " 
+	   << "Hits:"   << setw(24) << left << sd.hitsCollection()
+	   << "Cutoff:" << sd.energyCutoff()
+	   << endl;
+    }
+  }
+  catch(const exception& e) {
+    cout << "FAILED    to convert sensitive detector:" << name << ": " << e.what() << endl;
   }
+  catch(...) {
+    cout << "FAILED    to convert sensitive detector:" << name << ": UNKNONW Exception" << endl;
+  }
+}
 
-  template <> void Converter<DetElement>::operator()(const xml_h& element)  const {
-    static const char* req_dets = ::getenv("REQUIRED_DETECTORS");
-    static const char* req_typs = ::getenv("REQUIRED_DETECTOR_TYPES");
-    static const char* ign_dets = ::getenv("IGNORED_DETECTORS");
-    static const char* ign_typs = ::getenv("IGNORED_DETECTOR_TYPES");
-    string           type = element.attr<string>(_A(type));
-    string           name = element.attr<string>(_A(name));
-    string           name_match = ":"+name+":";
-    string           type_match = ":"+type+":";
-    if ( req_dets && !strstr(req_dets,name_match.c_str()) ) return;
-    if ( req_typs && !strstr(req_typs,type_match.c_str()) ) return;
-    if ( ign_dets &&  strstr(ign_dets,name_match.c_str()) ) return;
-    if ( ign_typs &&  strstr(ign_typs,type_match.c_str()) ) return;
-    try {
-      xml_attr_t attr_ro = element.attr_nothrow(_A(readout));
-      SensitiveDetector sd;
+void setChildTitles(const pair<string,DetElement>& e) {
+  DetElement parent = e.second.parent();
+  const DetElement::Children& children = e.second.children();
+  if ( ::strlen(e.second->GetTitle()) == 0 ) {
+    e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
+  }
+  for_each(children.begin(),children.end(),setChildTitles);
+}
+template <> void Converter<DetElement>::operator()(const xml_h& element)  const {
+  static const char* req_dets = ::getenv("REQUIRED_DETECTORS");
+  static const char* req_typs = ::getenv("REQUIRED_DETECTOR_TYPES");
+  static const char* ign_dets = ::getenv("IGNORED_DETECTORS");
+  static const char* ign_typs = ::getenv("IGNORED_DETECTOR_TYPES");
+  string           type = element.attr<string>(_A(type));
+  string           name = element.attr<string>(_A(name));
+  string           name_match = ":"+name+":";
+  string           type_match = ":"+type+":";
+  if ( req_dets && !strstr(req_dets,name_match.c_str()) ) return;
+  if ( req_typs && !strstr(req_typs,type_match.c_str()) ) return;
+  if ( ign_dets &&  strstr(ign_dets,name_match.c_str()) ) return;
+  if ( ign_typs &&  strstr(ign_typs,type_match.c_str()) ) return;
+  try {
+    xml_attr_t attr_ro = element.attr_nothrow(_A(readout));
+    SensitiveDetector sd;
+    if ( attr_ro )  {
+      Readout ro = lcdd.readout(element.attr<string>(attr_ro));
+      sd = SensitiveDetector(name,"sensitive");
+      sd.setHitsCollection(ro.name());
+      sd.setReadout(ro);
+      lcdd.addSensitiveDetector(sd);
+    }
+    DetElement det(Ref_t(ROOT::Reflex::PluginService::Create<TNamed*>(type,&lcdd,&element,&sd)));
+    if ( det.isValid() )  {
+      setChildTitles(make_pair(name,det));
       if ( attr_ro )  {
-	Readout ro = lcdd.readout(element.attr<string>(attr_ro));
-	sd = SensitiveDetector(name,"sensitive");
-	sd.setHitsCollection(ro.name());
-	sd.setReadout(ro);
-	lcdd.addSensitiveDetector(sd);
-      }
-      DetElement det(Ref_t(ROOT::Reflex::PluginService::Create<TNamed*>(type,&lcdd,&element,&sd)));
-      if ( det.isValid() )  {
-	setChildTitles(make_pair(name,det));
-	if ( attr_ro )  {
-	  det.setReadout(sd.readout());
-	}
+	det.setReadout(sd.readout());
       }
-      cout << (det.isValid() ? "Converted" : "FAILED    ")
-	   << " subdetector:" << name << " of type " << type;
-      if ( sd.isValid() ) cout << " [" << sd.type() << "]";
-      cout << endl;
-      lcdd.addDetector(det);
-    }
-    catch(const exception& e) {
-      cout << "FAILED    to convert subdetector:" << name << " of type " << type << ": " << e.what() << endl;
-    }
-    catch(...) {
-      cout << "FAILED    to convert subdetector:" << name << " of type " << type << ": UNKNONW Exception" << endl;
     }
+    cout << (det.isValid() ? "Converted" : "FAILED    ")
+	 << " subdetector:" << name << " of type " << type;
+    if ( sd.isValid() ) cout << " [" << sd.type() << "]";
+    cout << endl;
+    lcdd.addDetector(det);
   }
-  
-  /// Read material entries from a seperate file in one of the include sections of the geometry
-  template <> void Converter<GdmlFile>::operator()(const xml_h& element)  const  {
-    xercesc::XMLURL base(element.ptr()->getBaseURI());
-    xercesc::XMLURL ref(base, element.attr_value(_A(ref)));
-    xml_h materials = XML::DocumentHandler().load(_toString(ref.getURLText())).root();
-    xml_coll_t(materials,_X(element) ).for_each(Converter<Atom>(this->lcdd));
-    xml_coll_t(materials,_X(material)).for_each(Converter<Material>(this->lcdd));
+  catch(const exception& e) {
+    cout << "FAILED    to convert subdetector:" << name << " of type " << type << ": " << e.what() << endl;
   }
-
-  /// Read alignment entries from a seperate file in one of the include sections of the geometry
-  template <> void Converter<AlignmentFile>::operator()(const xml_h& element)  const  {
-    xercesc::XMLURL base(element.ptr()->getBaseURI());
-    xercesc::XMLURL ref(base, element.attr_value(_A(ref)));
-    xml_h alignments = XML::DocumentHandler().load(_toString(ref.getURLText())).root();
-    xml_coll_t(alignments,_X(alignment)).for_each(Converter<AlignmentEntry>(this->lcdd));
+  catch(...) {
+    cout << "FAILED    to convert subdetector:" << name << " of type " << type << ": UNKNONW Exception" << endl;
   }
+}
   
-  template <> void Converter<Compact>::operator()(const xml_h& element)  const  {
-    xml_elt_t compact(element);
-    xml_coll_t(compact,_X(includes)    ).for_each(_X(gdmlFile), Converter<GdmlFile>(lcdd));
-    //Header(lcdd.header()).fromCompact(doc,compact.child(Tag_info),Strng_t("In memory"));
-    xml_coll_t(compact,_X(define)      ).for_each(_X(constant), Converter<Constant>(lcdd));
-    xml_coll_t(compact,_X(materials)   ).for_each(_X(element),  Converter<Atom>(lcdd));
-    xml_coll_t(compact,_X(materials)   ).for_each(_X(material), Converter<Material>(lcdd));
-    lcdd.init();
-    xml_coll_t(compact,_X(limits)      ).for_each(_X(limitset), Converter<LimitSet>(lcdd));
-    xml_coll_t(compact,_X(display)     ).for_each(_X(vis),      Converter<VisAttr>(lcdd));
-    xml_coll_t(compact,_X(readouts)    ).for_each(_X(readout),  Converter<Readout>(lcdd));
-    xml_coll_t(compact,_X(detectors)   ).for_each(_X(detector), Converter<DetElement>(lcdd));
-    xml_coll_t(compact,_X(includes)    ).for_each(_X(alignment),Converter<AlignmentFile>(lcdd));
-    xml_coll_t(compact,_X(alignments)  ).for_each(_X(alignment),Converter<AlignmentEntry>(lcdd));
-    xml_coll_t(compact,_X(sensitive_detectors)).for_each(_X(sd),Converter<SensitiveDetector>(lcdd));
-    lcdd.endDocument();
-  }
-}}
+/// Read material entries from a seperate file in one of the include sections of the geometry
+template <> void Converter<GdmlFile>::operator()(const xml_h& element)  const  {
+  xercesc::XMLURL base(element.ptr()->getBaseURI());
+  xercesc::XMLURL ref(base, element.attr_value(_A(ref)));
+  xml_h materials = XML::DocumentHandler().load(_toString(ref.getURLText())).root();
+  xml_coll_t(materials,_X(element) ).for_each(Converter<Atom>(this->lcdd));
+  xml_coll_t(materials,_X(material)).for_each(Converter<Material>(this->lcdd));
+}
+
+/// Read alignment entries from a seperate file in one of the include sections of the geometry
+template <> void Converter<AlignmentFile>::operator()(const xml_h& element)  const  {
+  xercesc::XMLURL base(element.ptr()->getBaseURI());
+  xercesc::XMLURL ref(base, element.attr_value(_A(ref)));
+  xml_h alignments = XML::DocumentHandler().load(_toString(ref.getURLText())).root();
+  xml_coll_t(alignments,_X(alignment)).for_each(Converter<AlignmentEntry>(this->lcdd));
+}
+  
+template <> void Converter<Compact>::operator()(const xml_h& element)  const  {
+  xml_elt_t compact(element);
+  xml_coll_t(compact,_X(includes)    ).for_each(_X(gdmlFile), Converter<GdmlFile>(lcdd));
+  //Header(lcdd.header()).fromCompact(doc,compact.child(Tag_info),Strng_t("In memory"));
+  xml_coll_t(compact,_X(define)      ).for_each(_X(constant),  Converter<Constant>(lcdd));
+  xml_coll_t(compact,_X(materials)   ).for_each(_X(element),   Converter<Atom>(lcdd));
+  xml_coll_t(compact,_X(materials)   ).for_each(_X(material),  Converter<Material>(lcdd));
+  xml_coll_t(compact,_X(properties)  ).for_each(_X(attributes),Converter<Property>(lcdd));
+  lcdd.init();
+  xml_coll_t(compact,_X(limits)      ).for_each(_X(limitset), Converter<LimitSet>(lcdd));
+  xml_coll_t(compact,_X(display)     ).for_each(_X(vis),      Converter<VisAttr>(lcdd));
+  xml_coll_t(compact,_X(readouts)    ).for_each(_X(readout),  Converter<Readout>(lcdd));
+  xml_coll_t(compact,_X(detectors)   ).for_each(_X(detector), Converter<DetElement>(lcdd));
+  xml_coll_t(compact,_X(includes)    ).for_each(_X(alignment),Converter<AlignmentFile>(lcdd));
+  xml_coll_t(compact,_X(alignments)  ).for_each(_X(alignment),Converter<AlignmentEntry>(lcdd));
+  xml_coll_t(compact,_X(fields)      ).for_each(_X(field),    Converter<CartesianField>(lcdd));
+  xml_coll_t(compact,_X(sensitive_detectors)).for_each(_X(sd),Converter<SensitiveDetector>(lcdd));
+  lcdd.endDocument();
+}
+
 
 #ifdef _WIN32
 template Converter<Atom>;
diff --git a/DDCore/src/compact/LCDD2Output.cpp b/DDCore/src/compact/LCDD2Output.cpp
index ec5c0bb62ec5b089c20148da5f888e0d4828d1e9..a2d56a80c201eb7238794a541a8e1ac92f7348f7 100644
--- a/DDCore/src/compact/LCDD2Output.cpp
+++ b/DDCore/src/compact/LCDD2Output.cpp
@@ -7,7 +7,7 @@
 //
 //====================================================================
 
-#include "Conversions.h"
+#include "XML/Conversions.h"
 #include "DD4hep/LCDD.h"
 #include "DD4hep/Objects.h"
 #include "DD4hep/IDDescriptor.h"
@@ -21,8 +21,9 @@
 #include <iomanip>
 
 using namespace std;
+using namespace DD4hep::Geometry;
 
-namespace DD4hep { namespace Geometry {
+namespace DD4hep {
 
   template <> void Printer<Constant>::operator()(const Constant& val)  const  {
     os << "++ Constant:" << val.toString() << endl;
@@ -194,4 +195,4 @@ namespace DD4hep { namespace Geometry {
   void dumpTopVolume() {
     dumpVolume(gGeoManager->GetTopVolume(),0);
   }
-}}
+}