diff --git a/DDG4/examples/CLICSidSimu.py b/DDG4/examples/CLICSidSimu.py
index 562deed19431a6c76ac88f7c813c04128209c87d..84370551108eb4573207681008b44298368ec14a 100644
--- a/DDG4/examples/CLICSidSimu.py
+++ b/DDG4/examples/CLICSidSimu.py
@@ -45,8 +45,8 @@ def run():
 
   # Configure I/O
   evt_root = simple.setupROOTOutput('RootOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
-  #evt_lcio = simple.setupLCIOOutput('LcioOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
-  #evt_lcio.OutputLevel = Output.ERROR
+  evt_lcio = simple.setupLCIOOutput('LcioOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
+  evt_lcio.OutputLevel = Output.ERROR
 
 
   generator_output_level = Output.INFO
diff --git a/DDG4/include/DDG4/Geant4MonteCarloTruth.h b/DDG4/include/DDG4/Geant4MonteCarloTruth.h
index ffcb8c25ac2733ff9884127447bb8337f9f6a99c..27507ad073119d04a51411d154e563ee542b26a6 100644
--- a/DDG4/include/DDG4/Geant4MonteCarloTruth.h
+++ b/DDG4/include/DDG4/Geant4MonteCarloTruth.h
@@ -36,24 +36,12 @@ namespace DD4hep {
      *  \ingroup DD4HEP_SIMULATION
      */
     class Geant4MonteCarloTruth   {
-    public:
-      typedef Geant4Particle           Particle;
-      typedef std::map<int,Particle*>  ParticleMap;
-      typedef std::map<int,int>        TrackEquivalents;
     protected:
       /// Standard constructor
       Geant4MonteCarloTruth();
     public:
       /// Default destructor
       virtual ~Geant4MonteCarloTruth();
-#ifndef __MAKECINT__
-      /// Access the particle map
-      virtual const ParticleMap& particles() const = 0;
-      /// Access the map of track equivalents
-      virtual const TrackEquivalents& equivalents() const = 0;
-#endif
-      /// Access the equivalent track id (shortcut to the usage of TrackEquivalents)
-      virtual int particleID(int track, bool throw_if_not_found=true) const = 0;
       /// Mark a Geant4 track to be kept for later MC truth analysis
       virtual void mark(const G4Track* track) = 0;
       /// Store a track, with a flag
@@ -71,24 +59,11 @@ namespace DD4hep {
      *  \ingroup DD4HEP_SIMULATION
      */
     class Geant4DummyTruthHandler : public Geant4Action, public Geant4MonteCarloTruth  {
-    protected:
-      /// Map with stored MC Particles
-      ParticleMap m_particleMap;
-      /// Map associating the G4Track identifiers with identifiers of existing MCParticles
-      TrackEquivalents m_equivalentTracks;
     public:
       /// Standard constructor
       Geant4DummyTruthHandler(Geant4Context* ctxt,const std::string& nam);
       /// Default destructor
       virtual ~Geant4DummyTruthHandler();
-#ifndef __MAKECINT__
-      /// Access the particle map
-      virtual const ParticleMap& particles() const { return m_particleMap; }
-      /// Access the map of track equivalents
-      virtual const TrackEquivalents& equivalents() const { return m_equivalentTracks; }
-#endif
-      /// Access the equivalent track id (shortcut to the usage of TrackEquivalents)
-      virtual int particleID(int track, bool)  const {  return track; }
       /// Mark a Geant4 track to be kept for later MC truth analysis. Default flag: CREATED_HIT
       virtual void mark(const G4Track* track);
       /// Store a track, with a flag
diff --git a/DDG4/include/DDG4/Geant4Particle.h b/DDG4/include/DDG4/Geant4Particle.h
index 278092f64f8b99e857e347dfbc81d57cdcf59a0d..35bbb66b59a473a08d65074f4cd110859e8bc7d9 100644
--- a/DDG4/include/DDG4/Geant4Particle.h
+++ b/DDG4/include/DDG4/Geant4Particle.h
@@ -58,6 +58,7 @@ namespace DD4hep {
       G4PARTICLE_CREATED_TRACKER_HIT = 1<<8,
       G4PARTICLE_KEEP_USER = 1<<9,
       G4PARTICLE_KEEP_ALWAYS = 1<<10,
+      G4PARTICLE_FORCE_KILL = 1<<11,
 
       // Generator status for a given particles: bit 0...3 come from LCIO, rest is internal
       G4PARTICLE_GEN_EMPTY           = 1<<0,  // Empty line
diff --git a/DDG4/include/DDG4/Geant4ParticleHandler.h b/DDG4/include/DDG4/Geant4ParticleHandler.h
index 787b4c35fd5cd6d290f619bcbed8399ecd47995e..4c64b7a20f024e706d33bad09fb2fe2509b14a17 100644
--- a/DDG4/include/DDG4/Geant4ParticleHandler.h
+++ b/DDG4/include/DDG4/Geant4ParticleHandler.h
@@ -27,8 +27,6 @@ namespace DD4hep {
   namespace Simulation {
 
     // Forward declarations
-    class Particle;
-    class Geant4PrimaryMap;
     class Geant4UserParticleHandler;
 
     /// Geant4Action to collect the MC particle information.
@@ -40,6 +38,10 @@ namespace DD4hep {
      *  \ingroup DD4HEP_SIMULATION
      */
     class Geant4ParticleHandler : public Geant4GeneratorAction, public Geant4MonteCarloTruth  {
+    public:
+      typedef Geant4ParticleMap::Particle         Particle;
+      typedef Geant4ParticleMap::ParticleMap      ParticleMap;
+      typedef Geant4ParticleMap::TrackEquivalents TrackEquivalents;
 #ifdef __MAKECINT__
     public:
 #else
@@ -52,21 +54,7 @@ namespace DD4hep {
 
     public:
       typedef std::vector<std::string> Processes;
-      /// Functor to select particles from a integer map by the identifier.
-      /**
-       *  \author  M.Frank
-       *  \version 1.0
-       *  \ingroup DD4HEP_SIMULATION
-       */
-      class FindParticleByID {
-      protected:
-	int pid;
-      public:
-        FindParticleByID(int p) : pid(p) {}
-	inline bool operator()(const std::pair<int,Geant4Particle*>& p)  const {
-	  return p.second->id == pid;
-	}
-      };
+
     protected:
       
       /// Property: Steer printout at tracking action begin
@@ -101,8 +89,6 @@ namespace DD4hep {
       void clear();
       /// Check the record consistency
       void checkConsistency()  const;
-      /// Get proper equivalent track from the particle map according to the given geant4 track ID
-      int equivalentTrack(int g4_id) const;
 
       /// Rebase the simulated tracks, so that they fit to the generator particles
       void rebaseSimulatedTracks(int base);
@@ -128,14 +114,6 @@ namespace DD4hep {
       virtual void begin(const G4Track* track);
       /// Post-track action callback
       virtual void end(const G4Track* track);
-#ifndef __MAKECINT__
-      /// Access the particle map
-      virtual const ParticleMap& particles() const { return m_particleMap; }
-      /// Access the map of track equivalents
-      virtual const TrackEquivalents& equivalents() const { return m_equivalentTracks; }
-#endif
-      /// Access the equivalent track id (shortcut to the usage of TrackEquivalents)
-      virtual int particleID(int track, bool throw_if_not_found=true) const;
     
       /// Mark a Geant4 track to be kept for later MC truth analysis. Default flag: CREATED_HIT
       virtual void mark(const G4Track* track);
@@ -146,6 +124,9 @@ namespace DD4hep {
       /// Store a track produced in a step to be kept for later MC truth analysis
       virtual void mark(const G4Step* step, int reason);
 
+      /// Default callback to be answered if the particle should be kept if NO user handler is installed
+      static bool defaultKeepParticle(Particle& particle);
+
     };
   }    // End namespace Simulation
 }      // End namespace DD4hep
diff --git a/DDG4/include/DDG4/Geant4UserParticleHandler.h b/DDG4/include/DDG4/Geant4UserParticleHandler.h
index 05f0e83993edf574b81029c3d1e9582c9113417a..57d60c5ad080363bdbf91f11b91564f1cd924783 100644
--- a/DDG4/include/DDG4/Geant4UserParticleHandler.h
+++ b/DDG4/include/DDG4/Geant4UserParticleHandler.h
@@ -44,6 +44,11 @@ namespace DD4hep {
     class Geant4UserParticleHandler : public Geant4Action  {
     public:
       typedef Geant4Particle Particle;
+
+    protected:
+      /// Property: Energy cut below which particles are not collected, but assigned to the parent
+      double m_kinEnergyCut;
+
     public:
       /// Standard constructor
       Geant4UserParticleHandler(Geant4Context* context, const std::string& nam);
@@ -90,10 +95,18 @@ namespace DD4hep {
        *  to set the reason mask to NULL in order to drop it.
        *  The default implementation is empty.
        *
+       *  If the reason mask entry is set to G4PARTICLE_FORCE_KILL
+       *  or is set to NULL, the particle is ALWAYS removed
+       *
+       *  The default implementation calls
+       *  Geant4ParticleHandler::defaultKeepParticle(particle)
+       *  Please have a look therein if it suffices your needs!
+       *
        *  Note: This may override all other decisions!
        *        Default implementation is empty.
+       *  
        */
-      virtual void keepParticle(Particle& particle);
+      virtual bool keepParticle(Particle& particle);
 
       /// Callback when parent should be combined
       /** Called before a particle is removed from the final record.
diff --git a/DDG4/lcio/Geant4Output2LCIO.cpp b/DDG4/lcio/Geant4Output2LCIO.cpp
index 26014ee69f2430b892254d660e5acc97bd2ccd99..7c62ff6b6a1d7f23748cdca2cc0a8075a8cf02ce 100644
--- a/DDG4/lcio/Geant4Output2LCIO.cpp
+++ b/DDG4/lcio/Geant4Output2LCIO.cpp
@@ -17,6 +17,7 @@
 #include "lcio.h"
 #include "IO/LCWriter.h"
 #include "IMPL/LCEventImpl.h"
+#include "IMPL/LCCollectionVec.h"
 
 /// Namespace for the AIDA detector description toolkit
 namespace DD4hep {
@@ -25,6 +26,8 @@ namespace DD4hep {
 
   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
   namespace Simulation {
+
+    class Geant4ParticleMap;
     
     /// Base class to output Geant4 event data to media
     /**
@@ -37,6 +40,8 @@ namespace DD4hep {
       lcio::LCWriter*  m_file;
       int              m_runNo;
       
+      /// Data conversion interface for MC particles to LCIO format
+      lcio::LCCollectionVec* saveParticles(Geant4ParticleMap* particles);
     public:
       /// Standard constructor
       Geant4Output2LCIO(Geant4Context* context, const std::string& nam);
@@ -75,6 +80,7 @@ namespace DD4hep {
 
 // Framework include files
 #include "DD4hep/InstanceCount.h"
+#include "DD4hep/LCDD.h"
 #include "DDG4/Geant4HitCollection.h"
 #include "DDG4/Geant4DataConversion.h"
 #include "DDG4/Geant4Context.h"
@@ -82,6 +88,8 @@ namespace DD4hep {
 #include "DDG4/Geant4Data.h"
 
 //#include "DDG4/Geant4Output2LCIO.h"
+#include "G4ParticleDefinition.hh"
+#include "G4VProcess.hh"
 #include "G4Event.hh"
 #include "G4Run.hh"
 
@@ -89,7 +97,11 @@ namespace DD4hep {
 #include "IMPL/LCEventImpl.h"
 #include "IMPL/LCRunHeaderImpl.h"
 #include "IMPL/LCCollectionVec.h"
-
+#include "IMPL/ClusterImpl.h"
+#include "IMPL/SimTrackerHitImpl.h"
+#include "IMPL/SimCalorimeterHitImpl.h"
+#include "IMPL/MCParticleImpl.h"
+#include "UTIL/ILDConf.h"
 
 using namespace DD4hep::Simulation;
 using namespace DD4hep;
@@ -98,7 +110,6 @@ using namespace std;
 #include "DDG4/Factories.h"
 DECLARE_GEANT4ACTION(Geant4Output2LCIO)
 
-
 /// Standard constructor
 Geant4Output2LCIO::Geant4Output2LCIO(Geant4Context* ctxt, const string& nam)
 : Geant4OutputAction(ctxt,nam), m_file(0), m_runNo(0)
@@ -143,7 +154,6 @@ void Geant4Output2LCIO::saveRun(const G4Run* run)  {
   m_file->writeRunHeader(rh);
 }
 
-
 void Geant4Output2LCIO::begin(const G4Event* /* event */)  {
   lcio::LCEventImpl* e  = new lcio::LCEventImpl;
   //fg: here the event context takes ownership and
@@ -151,6 +161,103 @@ void Geant4Output2LCIO::begin(const G4Event* /* event */)  {
   context()->event().addExtension<lcio::LCEventImpl>( e );
 }
 
+/// Data conversion interface for MC particles to LCIO format
+lcio::LCCollectionVec* Geant4Output2LCIO::saveParticles(Geant4ParticleMap* particles)    {
+  typedef ReferenceBitMask<const int> PropertyMask;
+  typedef Geant4ParticleMap::ParticleMap ParticleMap;
+  const ParticleMap& pm = particles->particleMap;
+  size_t nparts = pm.size();
+  lcio::LCCollectionVec* lc_coll = new lcio::LCCollectionVec(lcio::LCIO::MCPARTICLE);
+  lc_coll->reserve(nparts);
+  if ( nparts > 0 )  {
+    size_t cnt = 0;
+    map<int,int> p_ids;
+    vector<const Geant4Particle*> p_part(pm.size(),0);
+    vector<MCParticleImpl*> p_lcio(pm.size(),0);
+    // First create the particles
+    for(ParticleMap::const_iterator i=pm.begin(); i!=pm.end();++i, ++cnt)   {
+      int id = (*i).first;
+      const Geant4Particle* p = (*i).second;
+      PropertyMask mask(p->status);
+      const G4ParticleDefinition* def = p->definition;
+      MCParticleImpl* q = new lcio::MCParticleImpl();
+      q->setPDG(p->pdgID);
+
+      float ps_fa[3] = { p->psx/GeV, p->psy/GeV, p->psz/GeV } ;  
+      q->setMomentum( ps_fa );
+
+      double vs_fa[3] = { p->vsx/mm, p->vsy/mm, p->vsz/mm } ;  
+      q->setVertex( vs_fa );
+
+      double ve_fa[3] = { p->vex/mm, p->vey/mm, p->vez/mm } ;  
+      q->setEndpoint( ve_fa );
+
+      q->setTime(p->time/ns);
+      q->setMass(p->mass/GeV);
+      q->setCharge(def ? def->GetPDGCharge()/3.0 : 0); // Charge(e+) = 1 !
+
+      // Set generator status
+      q->setGeneratorStatus(0);
+      if ( mask.isSet(G4PARTICLE_GEN_STABLE) ) q->setGeneratorStatus(1);
+      else if ( mask.isSet(G4PARTICLE_GEN_DECAYED) ) q->setGeneratorStatus(2);
+      else if ( mask.isSet(G4PARTICLE_GEN_DOCUMENTATION) ) q->setGeneratorStatus(3);
+
+      // Set simulation status
+      q->setSimulatorStatus( 0 ) ; 
+      q->setCreatedInSimulation(         mask.isSet(G4PARTICLE_SIM_CREATED) );
+      q->setBackscatter(                 mask.isSet(G4PARTICLE_SIM_BACKSCATTER) );
+      q->setVertexIsNotEndpointOfParent( mask.isSet(G4PARTICLE_SIM_PARENT_RADIATED) );
+      q->setDecayedInTracker(            mask.isSet(G4PARTICLE_SIM_DECAY_TRACKER) );
+      q->setDecayedInCalorimeter(        mask.isSet(G4PARTICLE_SIM_DECAY_CALO) );
+      q->setHasLeftDetector(             mask.isSet(G4PARTICLE_SIM_LEFT_DETECTOR) );
+      q->setStopped(                     mask.isSet(G4PARTICLE_SIM_STOPPED) );
+      q->setOverlay(                     false );
+
+      //fg: if simstatus !=0 we have to set the generator status to 0:
+      if( q->getSimulatorStatus() != 0 ) 
+	q->setGeneratorStatus( 0 )  ;
+
+      q->setSpin(p->spin);
+      q->setColorFlow(p->colorFlow);
+
+      lc_coll->addElement(q);
+      p_ids[id] = cnt;
+      p_part[cnt] = p;
+      p_lcio[cnt] = q;
+    }
+
+    // Now establish parent-daughter relationships
+    for(size_t i=0, n=p_ids.size(); i<n; ++i)   {
+      map<int,int>::iterator k;
+      const Geant4Particle* p = p_part[i];
+      MCParticleImpl* q = p_lcio[i];
+      const Geant4Particle::Particles& dau = p->daughters;
+      for(Geant4Particle::Particles::const_iterator j=dau.begin(); j!=dau.end(); ++j)  {
+	int idau = *j;
+	if ( (k=p_ids.find(idau)) == p_ids.end() )  {  // Error!!!
+	  printout(FATAL,"Geant4Conversion","+++ Particle %d: FAILED to find daughter with ID:%d",p->id,idau);
+	  continue;
+	}
+	int iqdau = (*k).second;
+	MCParticleImpl* qdau = p_lcio[iqdau];
+	qdau->addParent(q);
+      }
+      const Geant4Particle::Particles& par = p->parents;
+      for(Geant4Particle::Particles::const_iterator j=par.begin(); j!=par.end(); ++j)  {
+	int ipar = *j; // A parent ID iof -1 means NO parent, because a base of 0 is perfectly leagal!
+	if ( ipar>=0 && (k=p_ids.find(ipar)) == p_ids.end() )  {  // Error!!!
+	  printout(FATAL,"Geant4Conversion","+++ Particle %d: FAILED to find parent with ID:%d",p->id,ipar);
+	  continue;
+	}
+	int iqpar = (*k).second;
+	MCParticleImpl* qpar = p_lcio[iqpar];
+	q->addParent(qpar);
+      }
+    }
+  }
+  return lc_coll;
+}
+
 /// Callback to store the Geant4 event
 void Geant4Output2LCIO::saveEvent(OutputContext<G4Event>& ctxt)  {
   lcio::LCEventImpl* e = context()->event().extension<lcio::LCEventImpl>();
@@ -163,10 +270,7 @@ void Geant4Output2LCIO::saveEvent(OutputContext<G4Event>& ctxt)  {
   if ( part_map )   {
     print("+++ Saving %d LCIO particles....",int(part_map->particleMap.size()));
     if ( part_map->particleMap.size() > 0 )  {
-      typedef pair<const Geant4Context*,const Geant4ParticleMap*> _Args;
-      typedef Geant4Conversion<lcio::LCCollectionVec,_Args> _C;
-      const _C& cnv = _C::converter(typeid(Geant4ParticleMap));
-      lcio::LCCollectionVec* col = cnv(_Args(context(),part_map));
+      lcio::LCCollectionVec* col = saveParticles(part_map);
       evt->addCollection(col,lcio::LCIO::MCPARTICLE);
     }
   }
diff --git a/DDG4/plugins/Geant4TCUserParticleHandler.cpp b/DDG4/plugins/Geant4TCUserParticleHandler.cpp
index 792f5e3886a878f2770de622a6f07241b9443742..28216b48643cafe22f004b7a2b0ffd670d5487f5 100644
--- a/DDG4/plugins/Geant4TCUserParticleHandler.cpp
+++ b/DDG4/plugins/Geant4TCUserParticleHandler.cpp
@@ -79,16 +79,13 @@ Geant4TCUserParticleHandler::Geant4TCUserParticleHandler(Geant4Context* context,
 
 /// Post-track action callback
 void Geant4TCUserParticleHandler::end(const G4Track* /* track */, Particle& p)  {
-
-
   double r_prod = sqrt(p.vsx*p.vsx + p.vsy*p.vsy);
   double z_prod = fabs(p.vsz);
   bool starts_in_trk_vol = ( r_prod <= m_rTracker && z_prod <= m_zTracker )  ;
 
   // created in tracking volume but below energy cut
-  if( starts_in_trk_vol && ! (p.reason&G4PARTICLE_ABOVE_ENERGY_THRESHOLD)  ){
-    
-    p.reason = 0 ;
+  if( starts_in_trk_vol && ! (p.reason&G4PARTICLE_ABOVE_ENERGY_THRESHOLD) )  {
+    p.reason = 0;
     return;
   }
 
@@ -98,12 +95,10 @@ void Geant4TCUserParticleHandler::end(const G4Track* /* track */, Particle& p)
 
   // created and ended in calo
   if( !starts_in_trk_vol && !ends_in_trk_vol ){
-    
     p.reason = 0;
     return ;
   }
   
   //fg: backscatter ??
   // if( !starts_in_trk_vol &&  ends_in_trk_vol ){  keep ?  } 
-
 }
diff --git a/DDG4/src/Geant4InputHandling.cpp b/DDG4/src/Geant4InputHandling.cpp
index 0a2180100431e02634e6ad8dfb0105e20b838216..baf1a422f0ef7d3ed1f5b6f936dd62bb69925d21 100644
--- a/DDG4/src/Geant4InputHandling.cpp
+++ b/DDG4/src/Geant4InputHandling.cpp
@@ -312,6 +312,10 @@ int DD4hep::Simulation::generatePrimaries(const Geant4Action* caller,
 		  v->x/mm,v->y/mm,v->z/mm,v->time/ns);    
     for(Geant4Vertex::Particles::const_iterator ip=v->out.begin(); ip!=v->out.end(); ++ip)  {
       Geant4ParticleHandle p = pm[*ip];
+      if ( p->daughters.size() > 0 )  {
+	PropertyMask mask(p->reason);
+	mask.set(G4PARTICLE_HAS_SECONDARIES);
+      }
       if ( p->parents.size() == 0 )  {
 	Primaries relevant = getRelevant(visited,prim,pm,p);
 	for(Primaries::const_iterator j=relevant.begin(); j!= relevant.end(); ++j)  {
diff --git a/DDG4/src/Geant4Particle.cpp b/DDG4/src/Geant4Particle.cpp
index 3dea8117b55050a27a6b1293f25b7a1e2844ff14..a529c210a4773843275f5be13448489cd9ef71d2 100644
--- a/DDG4/src/Geant4Particle.cpp
+++ b/DDG4/src/Geant4Particle.cpp
@@ -339,19 +339,9 @@ void Geant4ParticleMap::adopt(ParticleMap& pm, TrackEquivalents& equiv)    {
 
 /// Access the equivalent track id (shortcut to the usage of TrackEquivalents)
 int Geant4ParticleMap::particleID(int g4_id, bool) const   {
-  int equiv_id  = g4_id;
-  if ( g4_id != 0 )  {
-    ParticleMap::const_iterator ipar;
-    while( (ipar=particleMap.find(equiv_id)) == particleMap.end() )  {
-      TrackEquivalents::const_iterator iequiv = equivalentTracks.find(equiv_id);
-      equiv_id = (iequiv == equivalentTracks.end()) ? -1 : (*iequiv).second;
-      if ( equiv_id < 0 ) {
-	printout(INFO,"Geant4ParticleMap",
-		 "+++ No Equivalent particle for track:%d last known is:%d",
-		 g4_id,equiv_id);
-	break;
-      }
-    }
-  }
-  return equiv_id;
+  TrackEquivalents::const_iterator iequiv = equivalentTracks.find(g4_id);
+  if ( iequiv != equivalentTracks.end() ) return (*iequiv).second;
+  printout(ERROR,"Geant4ParticleMap","+++ No Equivalent particle for track:%d."
+	   " Monte Carlo truth record looks broken!",g4_id);
+  return -1;
 }
diff --git a/DDG4/src/Geant4ParticleHandler.cpp b/DDG4/src/Geant4ParticleHandler.cpp
index 0c642a7c06b31c5b526a748a8223a13facb466bb..90a700d9cb9d19fc485067a222bbddd64a2e2076 100644
--- a/DDG4/src/Geant4ParticleHandler.cpp
+++ b/DDG4/src/Geant4ParticleHandler.cpp
@@ -202,8 +202,6 @@ void Geant4ParticleHandler::begin(const G4Track* track)   {
   G4PrimaryParticle* prim = primary(h.id(),context()->event().event());
   Particle* prim_part = 0;
 
-
-
   if ( prim )   {
     Geant4PrimaryMap::Primaries::const_iterator iprim = m_primaryMap->primaryMap.find(prim);
     if ( iprim == m_primaryMap->primaryMap.end() )  {
@@ -437,9 +435,20 @@ void Geant4ParticleHandler::rebaseSimulatedTracks(int )   {
     }
     if ( ipar != m_particleMap.end() )   {
       equivalents[(*i).first] = (*ipar).second->id;  // requires (1) !
+      Particle* p = (*ipar).second;
+      const G4ParticleDefinition* def = p->definition;
+      int pdg = int(fabs(def->GetPDGEncoding())+0.1);
+      if ( pdg<36 && !(pdg > 10 && pdg < 17) && pdg != 22 )  {
+	error("+++ ERROR: Geant4 particle for track:%d last known is:%d -- is gluon or quark!",(*i).second,g4_equiv);
+      }
+      pdg = int(fabs(p->pdgID)+0.1);
+      if ( pdg<36 && !(pdg > 10 && pdg < 17) && pdg != 22 )  {
+	error("+++ ERROR(2): Geant4 particle for track:%d last known is:%d -- is gluon or quark!",(*i).second,g4_equiv);
+      }
     }
-    else
+    else   {
       error("+++ No Equivalent particle for track:%d last known is:%d",(*i).second,g4_equiv);
+    }
   }
 
   // (3) Compute the particle's parents and daughters. 
@@ -465,101 +474,101 @@ void Geant4ParticleHandler::rebaseSimulatedTracks(int )   {
   m_particleMap = finalParticles;
 }
 
+/// Default callback to be answered if the particle should be kept if NO user handler is installed
+bool Geant4ParticleHandler::defaultKeepParticle(Particle& particle)   {
+  PropertyMask mask(particle.reason);
+  bool secondaries    =  mask.isSet(G4PARTICLE_HAS_SECONDARIES);
+  bool tracker_track  =  mask.isSet(G4PARTICLE_CREATED_TRACKER_HIT);
+  bool calo_track     =  mask.isSet(G4PARTICLE_CREATED_CALORIMETER_HIT);
+  bool hits_produced  =  mask.isSet(G4PARTICLE_CREATED_HIT);
+  bool low_energy     = !mask.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD);
+
+  /// Remove this track if it has not created a hit and the energy is below threshold
+  if ( mask.isNull() || (secondaries && low_energy && !hits_produced) )  {
+    return true;
+  }
+  /// Remove this track if the energy is below threshold. Reassign hits to parent.
+  else if ( !hits_produced && low_energy )  {
+    return true;
+  }
+  /// Remove this track if the origine is in the calorimeter. Reassign hits to parent.
+  else if ( !tracker_track && calo_track && low_energy )  {
+    return true;
+  }
+  else  {
+    //printout(INFO,name(),"+++ Track: %d should be kept for no obvious reason....",id);
+  }
+  return false;
+}
+
 /// Clean the monte carlo record. Remove all unwanted stuff.
 /// This is the core of the object executed at the end of each event action.
 int Geant4ParticleHandler::recombineParents()  {
-  int break_trackID = 38;
   set<int> remove;
+
   /// Need to start from BACK, to clean first the latest produced stuff.
-  /// Otherwise the daughter list of the earlier produced tracks would not be empty!
   for(ParticleMap::reverse_iterator i=m_particleMap.rbegin(); i!=m_particleMap.rend(); ++i)  {    
-    int g4_id = (*i).first;
     Particle* p = (*i).second;
-    set<int>& daughters = p->daughters;
+    PropertyMask mask(p->reason);
+    bool remove_me = false;
 
     // Allow the user to force the particle handling either by
     // or the reason mask with G4PARTICLE_KEEP_USER or
     // to set the reason mask to NULL in order to drop it.
+    //
+    // If the mask entry is set to G4PARTICLE_FORCE_KILL
+    // or is set to NULL, the particle is ALWAYS removed
+    //
     // Note: This may override all other decisions!
-    if ( m_userHandler )  {
-      m_userHandler->keepParticle(*p);
-    }
+    remove_me = m_userHandler ? m_userHandler->keepParticle(*p) : defaultKeepParticle(*p);
 
-    if ( daughters.size() == 0 )   {
-      PropertyMask mask(p->reason);
-      int  id             =  p->id;
-      bool secondaries    =  mask.isSet(G4PARTICLE_HAS_SECONDARIES);
-      bool tracker_track  =  mask.isSet(G4PARTICLE_CREATED_TRACKER_HIT);
-      bool calo_track     =  mask.isSet(G4PARTICLE_CREATED_CALORIMETER_HIT);
-      bool hits_produced  =  mask.isSet(G4PARTICLE_CREATED_HIT);
-      bool low_energy     = !mask.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD);
-      bool keep_process   =  mask.isSet(G4PARTICLE_KEEP_PROCESS);
-      bool keep_parent    =  mask.isSet(G4PARTICLE_KEEP_PARENT);
-      bool remove_me      = false;
-
-      if ( id == break_trackID )   {  // Used for debugging to set break point
-	remove_me = false;
-      }
-
-      if ( mask.isSet(G4PARTICLE_KEEP_USER) )  {
-	/// If user decides it must be kept, it MUST be kept!
-	mask.set(G4PARTICLE_KEEP_USER);
-	continue;
-      }
-      else if ( mask.isSet(G4PARTICLE_PRIMARY) )   {
-	/// Primary particles MUST be kept!
-	continue;
-      }
-      else if ( mask.isSet(G4PARTICLE_KEEP_ALWAYS) )   {
-	continue;
-      }
-      else if ( keep_parent )  {
-	//continue;
-      }
-      else if ( keep_process )  {
-	ParticleMap::iterator ip = m_particleMap.find(p->g4Parent);
-	if ( ip != m_particleMap.end() )   {
-	  Particle* parent_part = (*ip).second;
-	  PropertyMask parent_mask(parent_part->reason);
-	  if ( parent_mask.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD) )   {
-	    parent_mask.set(G4PARTICLE_KEEP_PARENT);
-	    continue;
-	  }
+    // Now look at the property mask of the particle
+    if ( mask.isNull() || mask.isSet(G4PARTICLE_FORCE_KILL) )  {
+      remove_me = true;
+    }
+    else if ( mask.isSet(G4PARTICLE_KEEP_USER) )  {
+      /// If user decides it must be kept, it MUST be kept!
+      mask.set(G4PARTICLE_KEEP_USER);
+      continue;
+    }
+    else if ( mask.isSet(G4PARTICLE_PRIMARY) )   {
+      /// Primary particles MUST be kept!
+      continue;
+    }
+    else if ( mask.isSet(G4PARTICLE_KEEP_ALWAYS) )   {
+      continue;
+    }
+    else if ( mask.isSet(G4PARTICLE_KEEP_PARENT) )  {
+      //continue;
+    }
+    else if ( mask.isSet(G4PARTICLE_KEEP_PROCESS) )  {
+      ParticleMap::iterator ip = m_particleMap.find(p->g4Parent);
+      if ( ip != m_particleMap.end() )   {
+	Particle* parent_part = (*ip).second;
+	PropertyMask parent_mask(parent_part->reason);
+	if ( parent_mask.isSet(G4PARTICLE_ABOVE_ENERGY_THRESHOLD) )   {
+	  parent_mask.set(G4PARTICLE_KEEP_PARENT);
+	  continue;
 	}
-	// Low energy stuff. Remove it. Reassign to parent.
-	//remove_me = true;
-      }
-
-      /// Remove this track if it has not created a hit and the energy is below threshold
-      if ( mask.isNull() || (secondaries && low_energy && !hits_produced) )  {
-	remove_me = true;
-      }
-      /// Remove this track if the energy is below threshold. Reassign hits to parent.
-      else if ( !hits_produced && low_energy )  {
-	remove_me = true;
-      }
-      /// Remove this track if the origine is in the calorimeter. Reassign hits to parent.
-      else if ( !tracker_track && calo_track && low_energy )  {
-	remove_me = true;
-      }
-      else  {
-	//printout(INFO,name(),"+++ Track: %d should be kept for no obvious reason....",id);
       }
+      // Low energy stuff. Remove it. Reassign to parent.
+      //remove_me = true;
+    }
 
-      /// Remove this track from the list and also do the cleanup in the parent's children list
-      if ( remove_me )  {
-	ParticleMap::iterator ip = m_particleMap.find(p->g4Parent);
-	remove.insert(g4_id);
-	m_equivalentTracks[g4_id] = p->g4Parent;
-	if ( ip != m_particleMap.end() )   {
-	  Particle* parent_part = (*ip).second;
-	  PropertyMask(parent_part->reason).set(mask.value());
-	  parent_part->steps += p->steps;
-	  parent_part->secondaries += p->secondaries;
-	  /// Update of the particle using the user handler
-	  if ( m_userHandler )  {
-	    m_userHandler->combine(*p, *parent_part);
-	  }
+    /// Remove this track from the list and also do the cleanup in the parent's children list
+    if ( remove_me )  {
+      int g4_id = (*i).first;
+      ParticleMap::iterator ip = m_particleMap.find(p->g4Parent);
+      remove.insert(g4_id);
+      m_equivalentTracks[g4_id] = p->g4Parent;
+      if ( ip != m_particleMap.end() )   {
+	Particle* parent_part = (*ip).second;
+	PropertyMask(parent_part->reason).set(mask.value());
+	parent_part->steps += p->steps;
+	parent_part->secondaries += p->secondaries;
+	/// Update of the particle using the user handler
+	if ( m_userHandler )  {
+	  m_userHandler->combine(*p, *parent_part);
 	}
       }
     }
@@ -595,12 +604,17 @@ void Geant4ParticleHandler::checkConsistency()  const   {
     // We assume that particles from the generator have consistent parents
     // For all other particles except the primaries, the parent must be contained in the record.
     if ( !mask.isSet(G4PARTICLE_PRIMARY) && !status.anySet(G4PARTICLE_GEN_GENERATOR) )  {
-      int parent_id = equivalentTrack(p->g4Parent);
-      bool in_map = (j=m_particleMap.find(parent_id)) != m_particleMap.end();
-      bool in_parent_list = p->parents.find(parent_id) != p->parents.end();
-      char parent_list[1024];
-      parent_list[0] = 0;
+      TrackEquivalents::const_iterator eq_it = m_equivalentTracks.find(p->g4Parent);
+      bool in_map = false, in_parent_list = false;
+      int parent_id = -1;
+      if ( eq_it != m_equivalentTracks.end() )   {
+	parent_id = (*eq_it).second;
+	in_map = (j=m_particleMap.find(parent_id)) != m_particleMap.end();
+	in_parent_list = p->parents.find(parent_id) != p->parents.end();
+      }
       if ( !in_map || !in_parent_list )  {
+	char parent_list[1024];
+	parent_list[0] = 0;
 	++num_errors;
 	for(set<int>::const_iterator ip=p->parents.begin(); ip!=p->parents.end();++ip)
 	  ::snprintf(parent_list+strlen(parent_list),sizeof(parent_list)-strlen(parent_list),"%d ",*ip);
@@ -610,32 +624,7 @@ void Geant4ParticleHandler::checkConsistency()  const   {
     }
   }
 
-  /// No we have to check the consistency of the map of equivalent tracks used to assign the
-  /// proper MC particle to the created hits
-  for(TrackEquivalents::const_iterator i=m_equivalentTracks.begin(), iend=m_equivalentTracks.end(); i!=iend; ++i)  {
-    int g4_id    = (*i).first;
-    int equiv_id = equivalentTrack(g4_id);
-    if ( equiv_id < 0 )  {
-      ++num_errors;
-    }
-  }
-
   if ( num_errors > 0 )  {
     except("+++ Consistency check failed. Found %d problems.",num_errors);
   }
 }
-
-/// Get proper equivalent track from the particle map according to the given geant4 track ID
-int Geant4ParticleHandler::equivalentTrack(int g4_id)  const  {
-  int equiv_id  = g4_id;
-  if ( g4_id != 0 )  {
-    TrackEquivalents::const_iterator iequiv = m_equivalentTracks.find(equiv_id);
-    if ( iequiv != m_equivalentTracks.end() ) return (*iequiv).second;
-  }
-  return -1;
-}
-
-/// Access the equivalent track id (shortcut to the usage of TrackEquivalents)
-int Geant4ParticleHandler::particleID(int track, bool) const    {
-  return equivalentTrack(track);
-}
diff --git a/DDG4/src/Geant4UserParticleHandler.cpp b/DDG4/src/Geant4UserParticleHandler.cpp
index 221756edf945238c570c9d38641e4390a723ede1..539242a4816fc520ae2b70f0427533bda5461a71 100644
--- a/DDG4/src/Geant4UserParticleHandler.cpp
+++ b/DDG4/src/Geant4UserParticleHandler.cpp
@@ -9,7 +9,9 @@
 // Framework include files
 #include "DD4hep/Printout.h"
 #include "DD4hep/InstanceCount.h"
+#include "DDG4/Geant4ParticleHandler.h"
 #include "DDG4/Geant4UserParticleHandler.h"
+#include "CLHEP/Units/SystemOfUnits.h"
 
 using namespace DD4hep::Simulation;
 
@@ -18,6 +20,7 @@ Geant4UserParticleHandler::Geant4UserParticleHandler(Geant4Context* context, con
   : Geant4Action(context,nam)
 {
   InstanceCount::increment(this);
+  declareProperty("MinimalKineticEnergy",m_kinEnergyCut = 100e0*CLHEP::MeV);
   m_needsControl = true;
 }
 
@@ -57,5 +60,6 @@ void Geant4UserParticleHandler::combine(Particle& /* to_be_deleted */, Particle&
 }
 
 /// Callback to be answered if the particle MUST be kept during recombination step
-void Geant4UserParticleHandler::keepParticle(Particle& /* particle */)   {
+bool Geant4UserParticleHandler::keepParticle(Particle& particle)   {
+  return Geant4ParticleHandler::defaultKeepParticle(particle);
 }
diff --git a/cmake/Doxyfile.in b/cmake/Doxyfile.in
index 22e0c53e63fc1f5978983e7b467d6d3dc6db1bc2..20d5c22443c9752abc8983e8ba36c799ddb22d14 100644
--- a/cmake/Doxyfile.in
+++ b/cmake/Doxyfile.in
@@ -650,15 +650,19 @@ WARN_LOGFILE =
 # with spaces.
 
 INPUT  = @CMAKE_CURRENT_SOURCE_DIR@/doc/doxygen/DD4hepMainpage.dox
-INPUT += @CMAKE_CURRENT_SOURCE_DIR@/doc/doxygen/DD4hepFigures.dox
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDCore/src
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDCore/src/XML
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDCore/include/DD4hep
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDCore/include/DD4hep/objects
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDCore/include/XML
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDG4/include/DDG4
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDG4/src
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDG4/plugins
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDG4/lcio
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDAlign/include/DDAlign
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDAlign/src
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDCond/include/DDCond
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDCond/src
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDEve/include/DDEve
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDEve/src
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDEve/lcio
@@ -669,6 +673,10 @@ INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDSense/include/DDSense
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDRec/src
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDRec/include/DDRec
 INPUT += @CMAKE_CURRENT_SOURCE_DIR@/DDSurfaces/include/DDSurfaces
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/doc/doxygen/Geant4Classes.h
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/doc/doxygen/ROOTClasses.h
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/doc/doxygen/TiXMLClasses.h
+INPUT += @CMAKE_CURRENT_SOURCE_DIR@/doc/doxygen/DD4hepGroups.h
 #INPUT += @CMAKE_CURRENT_SOURCE_DIR@//src
 #INPUT += @CMAKE_CURRENT_SOURCE_DIR@//include