diff --git a/DDG4/examples/CLICMagField.py b/DDG4/examples/CLICMagField.py
new file mode 100644
index 0000000000000000000000000000000000000000..0880dbf3ff7c88809ad60f29a00a534926990c18
--- /dev/null
+++ b/DDG4/examples/CLICMagField.py
@@ -0,0 +1,14 @@
+"""
+   Subtest using CLICSid showing how to manipulate the magnetic field
+
+   @author  M.Frank
+   @version 1.0
+
+"""
+if __name__ == "__main__":
+  import CLICSid
+  sid = CLICSid.CLICSid().loadGeometry()
+  # <<-- See this function to know how it's done....
+  sid.setupField(quiet=false)
+  sid.test_run()
+
diff --git a/DDG4/examples/CLICPhysics.py b/DDG4/examples/CLICPhysics.py
new file mode 100644
index 0000000000000000000000000000000000000000..43e2d1d2cb1fc2436f4c2fe91033b1d23d284e37
--- /dev/null
+++ b/DDG4/examples/CLICPhysics.py
@@ -0,0 +1,13 @@
+"""
+   Subtest using CLICSid showing how to setup the Geant4 physics list
+
+   @author  M.Frank
+   @version 1.0
+
+"""
+if __name__ == "__main__":
+  import CLICSid
+  sid = CLICSid.CLICSid().loadGeometry()
+  # <<-- See this function to know how it's done....
+  sid.setupPhysics('QGSP_BERT')
+  sid.test_run()
diff --git a/DDG4/examples/CLICRandom.py b/DDG4/examples/CLICRandom.py
new file mode 100644
index 0000000000000000000000000000000000000000..338a532b2429cf2d9415d9b4034f59f5f0867938
--- /dev/null
+++ b/DDG4/examples/CLICRandom.py
@@ -0,0 +1,20 @@
+"""
+   Subtest using CLICSid showing how to setup the random number generator
+
+   @author  M.Frank
+   @version 1.0
+
+"""
+if __name__ == "__main__":
+  import CLICSid
+  sid = CLICSid.CLICSid()
+  # <<-- See this function to know how it's done....
+  rndm1=sid.setupRandom('R1',seed=987654321,type='MTwistEngine')
+  rndm2=sid.setupRandom('R2',seed=1234321)
+
+  # Move main geant random instance from rndm1 to rndm2:
+  # See how gRandom and HepRandom instances move
+  rndm2.setMainInstance(rndm2.get())
+  rndm2.showStatus()
+  rndm1.showStatus()
+  sid.test_run(have_geo=False)
diff --git a/DDG4/examples/CLICSid.py b/DDG4/examples/CLICSid.py
new file mode 100644
index 0000000000000000000000000000000000000000..e581d9fd36b146419a8d8c0b58b3410d43facbf9
--- /dev/null
+++ b/DDG4/examples/CLICSid.py
@@ -0,0 +1,78 @@
+import sys, DDG4
+from SystemOfUnits import *
+
+class CLICSid:
+  def __init__(self):
+    self.kernel = DDG4.Kernel()
+    self.lcdd   = self.kernel.lcdd()
+    self.geant4 = DDG4.Geant4(self.kernel)
+    self.kernel.UI = ""
+    self.noPhysics()
+ 
+  def loadGeometry(self):
+    import os
+    install_dir = os.environ['DD4hepINSTALL']
+    self.kernel.loadGeometry("file:"+install_dir+"/DDDetectors/compact/SiD.xml")
+    return self
+
+  # Example to show how to configure G4 magnetic field tracking
+  def setupField(self, quiet=True):
+    field = self.geant4.addConfig('Geant4FieldTrackingSetupAction/MagFieldTrackingSetup')
+    field.stepper            = "HelixGeant4Runge"
+    field.equation           = "Mag_UsualEqRhs"
+    field.eps_min            = 5e-05 * mm
+    field.eps_max            = 0.001 * mm
+    field.min_chord_step     = 0.01 * mm
+    field.delta_chord        = 0.25 * mm
+    field.delta_intersection = 1e-05 * mm
+    field.delta_one_step     = 0.001 * mm
+    if not quiet:
+      print '+++++> ',field.name,'-> stepper  = ',field.stepper
+      print '+++++> ',field.name,'-> equation = ',field.equation
+      print '+++++> ',field.name,'-> eps_min  = ',field.eps_min
+      print '+++++> ',field.name,'-> eps_max  = ',field.eps_max
+      print '+++++> ',field.name,'-> delta_one_step = ',field.delta_one_step
+    return field
+
+  # Example to show how to setup random generator
+  def setupRandom(self, name, type=None, seed=None, quiet=True):
+    rndm = DDG4.Action(self.kernel,'Geant4Random/'+name)
+    if seed: rndm.Seed = seed
+    if type: rndm.Type = type
+    rndm.initialize()
+    if not quiet: rndm.showStatus()
+    return rndm
+
+  # Example to show how to configure the Geant4 physics list
+  def setupPhysics(self, model):
+    phys = self.geant4.setupPhysics(model)
+    ph = DDG4.PhysicsList(self.kernel,'Geant4PhysicsList/Myphysics')
+    # Add bosons to the model (redundant if already implemented by the model)
+    ph.addParticleConstructor('G4BosonConstructor')
+    # Add leptons to the model (redundant if already implemented by the model)
+    ph.addParticleConstructor('G4LeptonConstructor')
+    # Add multiple scattering in the material
+    ph.addParticleProcess('e[+-]','G4eMultipleScattering',-1,1,1)
+    # Add optical physics (RICH dets etc)
+    ph.addPhysicsConstructor('G4OpticalPhysics')
+    # Interactivity
+    ph.enableUI()
+    phys.adopt(ph)
+    phys.dump()
+    return phys
+
+  # No physics list wanted for tests ? See how:
+  def noPhysics(self):
+    self.geant4.setupPhysics('')
+    return self
+
+
+  # Test runner
+  def test_run(self, have_geo=True, have_physics=False):
+    self.kernel.configure()
+    if have_geo:
+      self.kernel.initialize()
+      self.kernel.NumEvents = 0
+      self.kernel.run()
+    self.kernel.terminate()
+    sys.exit(0)
diff --git a/DDG4/examples/CLICSidSimu.py b/DDG4/examples/CLICSidSimu.py
index 0e4cdf20767c1c20f04058ec13fbe7a9eae63376..318e26eafff2c41fb12bb241fde680d5afe63b8e 100644
--- a/DDG4/examples/CLICSidSimu.py
+++ b/DDG4/examples/CLICSidSimu.py
@@ -17,7 +17,6 @@ def run():
   kernel = DDG4.Kernel()
   lcdd = kernel.lcdd()
   install_dir = os.environ['DD4hepINSTALL']
-  example_dir = install_dir+'/examples/DDG4/examples';
   kernel.loadGeometry("file:"+install_dir+"/DDDetectors/compact/SiD.xml")
   DDG4.importConstants(lcdd)
 
@@ -42,6 +41,12 @@ def run():
   print '+++++> ',field.name,'-> eps_max  = ',field.eps_max
   print '+++++> ',field.name,'-> delta_one_step = ',field.delta_one_step
 
+  # Setup random generator
+  rndm = DDG4.Action(kernel,'Geant4Random/Random')
+  rndm.Seed = 987654321
+  rndm.initialize()
+  rndm.showStatus()
+  rndm.Seed = 987654321
 
   # Configure Run actions
   run1 = DDG4.RunAction(kernel,'Geant4TestRunAction/RunInit')
diff --git a/DDG4/include/DDG4/Factories.h b/DDG4/include/DDG4/Factories.h
index a8b7bb13836f263779e55997235836f2d847a153..d0496b01571354d431edf1ce3cf99a0a42f0f71d 100644
--- a/DDG4/include/DDG4/Factories.h
+++ b/DDG4/include/DDG4/Factories.h
@@ -34,6 +34,7 @@ class G4MagneticField;
 class G4Mag_EqRhs;
 class G4VPhysicsConstructor;
 class G4VUserPhysicsList;
+class G4VPrimaryGenerator;
 class G4VProcess;
 
 /// Namespace for the AIDA detector description toolkit
@@ -125,6 +126,10 @@ namespace {
   DD4HEP_PLUGIN_FACTORY_ARGS_0(G4ParticleDefinition*)
   {    return P::Definition();  }
 
+  /// Factory to create Geant4 primary generator objects
+  DD4HEP_PLUGIN_FACTORY_ARGS_0(G4VPrimaryGenerator*)
+  {    return new P();  }
+
   /// Generic particle constructor
   DD4HEP_PLUGIN_FACTORY_ARGS_0(long)  {
     P::ConstructParticle();
@@ -172,6 +177,8 @@ namespace {
 #define DECLARE_GEANT4_PROCESS(name)       DD4HEP_PLUGINSVC_FACTORY(name,name,G4VProcess*(),__LINE__)
 /// Plugin definition to create Geant4 physics constructors (G4VPhysicsConstructor)
 #define DECLARE_GEANT4_PHYSICS(name)       DD4HEP_PLUGINSVC_FACTORY(name,name,G4VPhysicsConstructor*(),__LINE__)
+/// Plugin definition to create Geant4 physics processes (G4VProcess)
+#define DECLARE_GEANT4_GENERATOR(name)     DD4HEP_PLUGINSVC_FACTORY(name,name,G4VPrimaryGenerator*(),__LINE__)
 /// Plugin definition to force particle constructors for GEANT4 (G4ParticleDefinition)
 #define DECLARE_GEANT4_PARTICLE(name)      DD4HEP_PLUGINSVC_FACTORY(name,name,G4ParticleDefinition*(),__LINE__)
 /// Plugin definition to force particle constructors for GEANT4 (G4XXXXConstructor)
diff --git a/DDG4/include/DDG4/Geant4Action.h b/DDG4/include/DDG4/Geant4Action.h
index 5e3db52c46fb653cf1b3ca9ce77df2830e491b60..ed5c20ac7875b3a482225085520c6efbf618b7c1 100644
--- a/DDG4/include/DDG4/Geant4Action.h
+++ b/DDG4/include/DDG4/Geant4Action.h
@@ -119,7 +119,7 @@ namespace DD4hep {
         /// reference to the context;
         const Geant4Context* context;
         /// Constructor
-      ContextUpdate(const Geant4Context* c=0) : context(c)  {}
+        ContextUpdate(const Geant4Context* c=0) : context(c)  {}
         /// Callback
         void operator()(Geant4Action* action)  const;
       };
diff --git a/DDG4/include/DDG4/Geant4GeneratorWrapper.h b/DDG4/include/DDG4/Geant4GeneratorWrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..c79655f1edefc575d1ba2df4a16cefb560d2833a
--- /dev/null
+++ b/DDG4/include/DDG4/Geant4GeneratorWrapper.h
@@ -0,0 +1,60 @@
+// $Id$
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+#ifndef DD4HEP_DDG4_GEANT4GENERATORWRAPPER_H
+#define DD4HEP_DDG4_GEANT4GENERATORWRAPPER_H
+
+// Framework include files
+#include "DDG4/Geant4GeneratorAction.h"
+
+// Forward declarations
+class G4VPrimaryGenerator;
+
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace Simulation {
+
+    /// Geant4Action to merge several independent interaction to one
+    /** Wrap native G4 particle ganerators like the generic particle source etc.
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_SIMULATION
+     */
+    class Geant4GeneratorWrapper : public Geant4GeneratorAction    {
+    protected:
+      /// Property: Type name of the implementation instance. name: "Uses"
+      std::string m_generatorType;
+      /// Property: interaction identifier mask. name: "Mask"
+      int m_mask;
+
+      /// Reference to the implementation instance
+      G4VPrimaryGenerator* m_generator;
+      
+    public:
+      /// Standard constructor
+      Geant4GeneratorWrapper(Geant4Context* context, const std::string& nam);
+      /// Default destructor
+      virtual ~Geant4GeneratorWrapper();
+      /// Access the G4VPrimaryGenerator instance
+      G4VPrimaryGenerator* generator();
+      /// Event generation action callback
+      virtual void operator()(G4Event* event);
+    };
+  }    // End namespace Simulation
+}      // End namespace DD4hep
+
+#endif // DD4HEP_DDG4_GEANT4GENERATORWRAPPER_H
diff --git a/DDG4/include/DDG4/Geant4InputHandling.h b/DDG4/include/DDG4/Geant4InputHandling.h
index 90a238e559e8a9c584fcf2deeca7100b26d47d1a..3bcf54c9076b592bd29496c644da7def9d7b5a7d 100644
--- a/DDG4/include/DDG4/Geant4InputHandling.h
+++ b/DDG4/include/DDG4/Geant4InputHandling.h
@@ -20,6 +20,9 @@
 
 // Forward declarations
 class G4Event;
+class G4PrimaryVertex;
+class G4PrimaryParticle;
+
 
 /// Namespace for the AIDA detector description toolkit
 namespace DD4hep {
@@ -31,6 +34,17 @@ namespace DD4hep {
     class Geant4Action;
     class Geant4Context;
 
+    /** Helpers to import and export G4 records  */
+
+    /// Create a vertex object from it's G4 counterpart
+    Geant4Vertex* createPrimary(const G4PrimaryVertex* g4);
+    
+    /// Create a particle object from it's G4 counterpart
+    Geant4Particle* createPrimary(int particle_id, const Geant4Vertex* v, const G4PrimaryParticle* g4p);
+
+    /// Create a DDG4 interaction record from a Geant4 interaction defined by a primary vertex
+    Geant4PrimaryInteraction* createPrimary(int mask, const G4PrimaryVertex* gv);
+
     /// Initialize the generation of one event
     int generationInitialization(const Geant4Action* caller,const Geant4Context* context);
 
diff --git a/DDG4/include/DDG4/Geant4InteractionVertexBoost.h b/DDG4/include/DDG4/Geant4InteractionVertexBoost.h
index f7f8e5faf3e114436b3f0aac2584d1cd1dbcb54f..3003fe75e5ece41fb84f6a312736d15f8516d807 100644
--- a/DDG4/include/DDG4/Geant4InteractionVertexBoost.h
+++ b/DDG4/include/DDG4/Geant4InteractionVertexBoost.h
@@ -34,11 +34,19 @@ namespace DD4hep {
      *  \ingroup DD4HEP_SIMULATION
      */
     class Geant4InteractionVertexBoost: public Geant4GeneratorAction {
+    public:
+      /// Interaction definition
+      typedef Geant4PrimaryInteraction Interaction;
+
     protected:
       /// Property: The constant Lorentz transformation angle
       double m_angle;
       /// Property: Unique identifier of the interaction to be modified
       int m_mask;
+
+      /// Action routine to boost one single interaction according to the properties
+      void boost(Interaction* interaction)  const;
+
     public:
       /// Standard constructor
       Geant4InteractionVertexBoost(Geant4Context* context, const std::string& name);
diff --git a/DDG4/include/DDG4/Geant4InteractionVertexSmear.h b/DDG4/include/DDG4/Geant4InteractionVertexSmear.h
index e42f6978fb1931cea500bd92753fc0fe929b49bb..ac5762ab23397cd4a85d5f7421a4dde518bd4e05 100644
--- a/DDG4/include/DDG4/Geant4InteractionVertexSmear.h
+++ b/DDG4/include/DDG4/Geant4InteractionVertexSmear.h
@@ -26,6 +26,9 @@ namespace DD4hep {
   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
   namespace Simulation {
 
+    /// Forward declarations
+    class Geant4PrimaryInteraction;
+
     /// Action class to smear the primary vertex (and all outgoing particles) of a single interaction
     /**
      * The vertex smearing is steered by a 3D gaussian given by a constant offset and
@@ -37,6 +40,10 @@ namespace DD4hep {
      *  \ingroup DD4HEP_SIMULATION
      */
     class Geant4InteractionVertexSmear: public Geant4GeneratorAction {
+    public:
+      /// Interaction definition
+      typedef Geant4PrimaryInteraction Interaction;
+
     protected:
       /// Property: The constant smearing offset
       ROOT::Math::PxPyPzEVector m_offset;
@@ -44,6 +51,10 @@ namespace DD4hep {
       ROOT::Math::PxPyPzEVector m_sigma;
       /// Property: Unique identifier of the interaction created
       int m_mask;
+
+      /// Action routine to smear one single interaction according to the properties
+      void smear(Interaction* interaction)  const;
+      
     public:
       /// Standard constructor
       Geant4InteractionVertexSmear(Geant4Context* context, const std::string& name);
diff --git a/DDG4/include/DDG4/Geant4Primary.h b/DDG4/include/DDG4/Geant4Primary.h
index ac49f09eb0e18186b9b543759664e8b4da182c04..5e6352e805271f3649816300e370d100eaee94ab 100644
--- a/DDG4/include/DDG4/Geant4Primary.h
+++ b/DDG4/include/DDG4/Geant4Primary.h
@@ -102,9 +102,11 @@ namespace DD4hep {
       ExtensionHandle extension;
       /// User mask to flag the interaction. Also unique identifier
       int             mask;
+      /// Flag that the event is locked for G4 native generators
+      int             locked;
       /// Next PID indentifier
       int             next_particle_identifier;
-
+      
     public:
       /// Default constructor
       Geant4PrimaryInteraction();
@@ -155,6 +157,8 @@ namespace DD4hep {
       void add(int id, Geant4PrimaryInteraction* interaction);
       /// Retrieve an interaction by it's ID
       Geant4PrimaryInteraction* get(int id) const;
+      /// Number of interaction contained in the primary event
+      size_t size()  const      {        return m_interactions.size();      }
       /// Retrieve all intractions
       std::vector<Geant4PrimaryInteraction*> interactions() const;
     };
diff --git a/DDG4/include/DDG4/Geant4Random.h b/DDG4/include/DDG4/Geant4Random.h
index d7cea8aafefb134eef56de2ab8a50b15ab209af2..6322ee7f56ad778ea017742c573b342c95970daa 100644
--- a/DDG4/include/DDG4/Geant4Random.h
+++ b/DDG4/include/DDG4/Geant4Random.h
@@ -15,8 +15,16 @@
 #define DD4HEP_GEANT4RANDOM_H
 
 // Framework include files
+#include "DDG4/Geant4Action.h"
 
 // C/C++ include files
+#include <string>
+
+// Forward declarations
+class TRandom;
+
+/// CLHEP namespace 
+namespace CLHEP   {  class HepRandomEngine;   }
 
 /// Namespace for the AIDA detector description toolkit
 namespace DD4hep {
@@ -41,29 +49,111 @@ namespace DD4hep {
      *  if the generation functions will have to become virtual....
      *  Future will tell us.
      *
+     *  The first instance of the random action is automatically set
+     *  to be the Geant4 instance. If another instance should be used by 
+     *  Geant4, use setMainInstance(Geant4Random* ptr).
+     *
      *  \author  M.Frank
      *  \version 1.0
      *  \ingroup DD4HEP_SIMULATION
      */
-    class Geant4Random  {
+    class Geant4Random : public Geant4Action   {
       friend class Geant4Exec;
 
     protected:
-      /// Default constructor
-      Geant4Random();
+      /// Property: File name if initialized from file. If set, engine name and seeds are ignored
+      std::string  m_file;
+      /// Property: Engine type. default: "HepJamesRandom"
+      std::string  m_engineType;
+      /// Property: Initial random seed. Default: 123456789
+      long         m_seed, m_luxury;
+      /// Property: Indicator to replace the ROOT gRandom instance
+      bool         m_replace;
+      
+      /// Reference to the CLHEP random number engine (valid only after initialization)
+      CLHEP::HepRandomEngine* m_engine;
+
+      /// Reference to ROOT random instance
+      TRandom *m_rootRandom, *m_rootOLD;
+      /// Flag to remember initialization
+      bool m_inited;
+      
+    public:
+      /// Standard constructor
+      /** Please Note:
+       *  Should be used only for initialization of the main instance.
+       *  Subsequent usage should be invoked using the class member
+       *  Geant4Random::instance().
+       *
+       *  @param   context     Geant4 context for this action.
+       *  @param   name        Name of the action object
+       */
+      Geant4Random(Geant4Context* context, const std::string& name);
       /// Default destructor
       virtual ~Geant4Random();
-    public:
-      void   circle(double &x, double &y, double r);
-      double exp(double tau);
-      double gauss(double mean=0, double sigma=1);
-      double landau(double mean=0, double sigma=1);
+
+      /// Access the main Geant4 random generator instance. Must be created before used!
+      static Geant4Random* instance(bool throw_exception=true);
+      /// Make this random generator instance the one used by Geant4.
+      /** Returns reference to previous instance. It is up to the user
+       *  to manage the reference.
+       *  Caveat: other code may hold references to this instance.
+       *
+       *  @param   ptr         Reference to main random number generator
+       *  @return              Reference to previous random number generator instance
+       */
+      static Geant4Random* setMainInstance(Geant4Random* ptr);
+
+      /// Initialize the instance. 
+      /** Called either by user or on request of the first random number.
+       *  To propagate the engine to Geant4, initialize MUST be called by 
+       *  the user.
+       */
+      void initialize();
+      
+      /** Access to the CLHEP random number engine. For further doc see CLHEP/Random/RandomEngine.h  */
+
+      /// CLHEP random number engine (valid after initialization only)
+      CLHEP::HepRandomEngine* engine()      {  return m_engine;   }
+      
+      /// Should initialise the status of the algorithm according to seed.
+      virtual void setSeed(long seed);
+      /// Should initialise the status of the algorithm
+      /** Initialization according to the zero terminated
+       *  array of seeds. It is allowed to ignore one or 
+       *  many seeds in this array.
+       */
+      virtual void setSeeds(const long * seeds, int size);
+      /// Should save on a file specific to the instantiated engine in use the current status.
+      virtual void saveStatus( const char filename[] = "Config.conf") const;
+      /// Should read from a file and restore the last saved engine configuration.
+      virtual void restoreStatus( const char filename[] = "Config.conf" );
+      /// Should dump the current engine status on the screen.
+      virtual void showStatus() const;
+
+      /** Basic random generator functions  */
+
+      /// Create flat distributed random numbers in the interval ]0,1]
       double rndm(int i=0);
+      /// Create a float array of flat distributed random numbers in the interval ]0,1]
       void   rndmArray(int n, float *array);
+      /// Create a double array of flat distributed random numbers in the interval ]0,1]
       void   rndmArray(int n, double *array);
-      void   sphere(double &x, double &y, double &z, double r);
+      /// Create uniformly disributed random numbers in the interval ]0,x1]
       double uniform(double x1=1);
+      /// Create uniformly disributed random numbers in the interval ]x1,x2]
       double uniform(double x1, double x2);
+
+      /// Create exponentially distributed random numbers
+      double exp(double tau);
+      /// Create gaussian distributed random numbers
+      double gauss(double mean=0, double sigma=1);
+      /// Create landau distributed random numbers
+      double landau(double mean=0, double sigma=1);
+      /// Create tuple of randum number around a circle with radius r
+      void   circle(double &x, double &y, double r);
+      /// Create tuple of randum number on a sphere with radius r
+      void   sphere(double &x, double &y, double &z, double r);
     };
 
   }    // End namespace Simulation
diff --git a/DDG4/plugins/Geant4Factories.cpp b/DDG4/plugins/Geant4Factories.cpp
index 9ddc2f7f25acf00bc04ff2b5316da1547f98a4a4..03bb7e6054de1eef32acc118e1c35ee9649ad88c 100644
--- a/DDG4/plugins/Geant4Factories.cpp
+++ b/DDG4/plugins/Geant4Factories.cpp
@@ -16,6 +16,9 @@
 #include "DDG4/Factories.h"
 using namespace DD4hep::Simulation;
 
+#include "DDG4/Geant4Random.h"
+DECLARE_GEANT4ACTION(Geant4Random)
+
 #include "DDG4/Geant4ActionPhase.h"
 DECLARE_GEANT4ACTION(Geant4PhaseAction)
 
@@ -106,6 +109,10 @@ DECLARE_GEANT4ACTION(Geant4PrimaryHandler)
 #include "DDG4/Geant4InputAction.h"
 DECLARE_GEANT4ACTION(Geant4InputAction)
 
+//=============================
+#include "DDG4/Geant4GeneratorWrapper.h"
+DECLARE_GEANT4ACTION(Geant4GeneratorWrapper)
+
 //=============================
 #include "DDG4/Geant4TestActions.h"
 namespace DD4hep {  namespace Simulation   {
diff --git a/DDG4/plugins/Geant4PrimaryGenerators.cpp b/DDG4/plugins/Geant4PrimaryGenerators.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..018938ec24ca3005fac30bc3123937f6f0ed4169
--- /dev/null
+++ b/DDG4/plugins/Geant4PrimaryGenerators.cpp
@@ -0,0 +1,27 @@
+// $Id$
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "DDG4/Factories.h"
+
+// Geant 4 include files
+#include "G4ParticleGun.hh"
+#include "G4SingleParticleSource.hh"
+#include "G4GeneralParticleSource.hh"
+#include "G4AdjointPrimaryGenerator.hh"
+
+DECLARE_GEANT4_GENERATOR(G4ParticleGun)
+DECLARE_GEANT4_GENERATOR(G4SingleParticleSource)
+DECLARE_GEANT4_GENERATOR(G4GeneralParticleSource)
+//DECLARE_GEANT4_GENERATOR(G4AdjointPrimaryGenerator)
diff --git a/DDG4/python/DDG4Dict.C b/DDG4/python/DDG4Dict.C
index b51c633b8ee7ec576a53ca056d88509f39fb1118..ea0602cfd31940a22c7527540dd2f6162bdaa155 100644
--- a/DDG4/python/DDG4Dict.C
+++ b/DDG4/python/DDG4Dict.C
@@ -18,6 +18,7 @@
 //====================================================================
 // FRamework include files
 #include "DDG4/Geant4Primary.h"
+#include "DDG4/Geant4Random.h"
 #include "DDG4/DDG4Dict.h"
 
 
@@ -33,17 +34,17 @@ using namespace DD4hep::Simulation;
 namespace DD4hep {
   namespace Simulation  {
 
-#define ACTIONHANDLE(x)    \
-    struct x##Handle  {    \
-      Geant4##x* action;   \
+#define ACTIONHANDLE(x)                                                 \
+    struct x##Handle  {                                                 \
+      Geant4##x* action;                                                \
       x##Handle(Geant4##x* a)       : action(a)        { if ( action ) action->addRef();} \
       x##Handle(const x##Handle& h) : action(h.action) { if ( action ) action->addRef();} \
       ~x##Handle()                  { if ( action) action->release();                   } \
       Geant4##x* release()          { Geant4##x* tmp = action; action=0; return tmp;    } \
-      operator Geant4##x* () const  { return action;     }  \
-      Geant4##x* operator->() const { return action;     }  \
-      Geant4##x* get() const        { return action;     }  \
-      }
+      operator Geant4##x* () const  { return action;     }              \
+      Geant4##x* operator->() const { return action;     }              \
+      Geant4##x* get() const        { return action;     }              \
+    }
 
     ACTIONHANDLE(Filter);
     ACTIONHANDLE(Action);
@@ -68,109 +69,109 @@ namespace DD4hep {
     ACTIONHANDLE(SensDetActionSequence);
 
     struct PropertyResult  {
-      string data;
-      int status;
-      PropertyResult() : status(0) {}
-      PropertyResult(const string& d, int s) : data(d), status(s) {}
+    string data;
+    int status;
+    PropertyResult() : status(0) {}
+    PropertyResult(const string& d, int s) : data(d), status(s) {}
       PropertyResult(const PropertyResult& c) : data(c.data), status(c.status) {}
-      ~PropertyResult() {}
-    };
+        ~PropertyResult() {}
+          };
 
     struct Geant4ActionCreation  {
-      template <typename H,typename T> static H cr(KernelHandle& kernel, const string& name_type)  {
-	T action(*kernel.get(),name_type);
-	H handle(action.get());
-	return handle;
-      }
-      static ActionHandle createAction(KernelHandle& kernel, const string& name_type)   
-      { return cr<ActionHandle,Setup::Action>(kernel,name_type);                            }
-      static FilterHandle createFilter(KernelHandle& kernel, const string& name_type)
-      { return cr<FilterHandle,Setup::Filter>(kernel,name_type);                            }
-      static PhaseActionHandle createPhaseAction(KernelHandle& kernel, const string& name_type)   
-      { return cr<PhaseActionHandle,Setup::PhaseAction>(kernel,name_type);                  }
-      static PhysicsListHandle createPhysicsList(KernelHandle& kernel, const string& name_type)
-      { return cr<PhysicsListHandle,Setup::PhysicsList>(kernel,name_type);                  }
-      static RunActionHandle createRunAction(KernelHandle& kernel, const string& name_type)
-      { return cr<RunActionHandle,Setup::RunAction>(kernel,name_type);                      }
-      static EventActionHandle createEventAction(KernelHandle& kernel, const string& name_type)
-      { return cr<EventActionHandle,Setup::EventAction>(kernel,name_type);                  }
-      static TrackingActionHandle createTrackingAction(KernelHandle& kernel, const string& name_type)
-      { return cr<TrackingActionHandle,Setup::TrackAction>(kernel,name_type);               }
-      static SteppingActionHandle createSteppingAction(KernelHandle& kernel, const string& name_type)
-      { return cr<SteppingActionHandle,Setup::StepAction>(kernel,name_type);                }
-      static StackingActionHandle createStackingAction(KernelHandle& kernel, const string& name_type)
-      { return cr<StackingActionHandle,Setup::StackAction>(kernel,name_type);               }
-      static GeneratorActionHandle createGeneratorAction(KernelHandle& kernel, const string& name_type)
-      { return cr<GeneratorActionHandle,Setup::GenAction>(kernel,name_type);                }
-      static SensitiveHandle createSensitive(KernelHandle& kernel, const string& name_type, const string& detector)
-      {	return SensitiveHandle(Setup::Sensitive(*kernel.get(),name_type,detector).get());   }
-      static SensDetActionSequenceHandle createSensDetSequence(KernelHandle& kernel, const string& name_type)
-      {	return cr<SensDetActionSequenceHandle,Setup::SensitiveSeq>(kernel,name_type);       }
-
-      static Geant4Action* toAction(Geant4Filter* f)                   { return f;          }
-      static Geant4Action* toAction(Geant4Action* f)                   { return f;          }
-      static Geant4Action* toAction(Geant4PhaseAction* f)              { return f;          }
-      static Geant4Action* toAction(Geant4Sensitive* f)                { return f;          }
-      static Geant4Action* toAction(Geant4PhysicsList* f)              { return f;          }
-      static Geant4Action* toAction(Geant4RunAction* f)                { return f;          }
-      static Geant4Action* toAction(Geant4EventAction* f)              { return f;          }
-      static Geant4Action* toAction(Geant4TrackingAction* f)           { return f;          }
-      static Geant4Action* toAction(Geant4SteppingAction* f)           { return f;          }
-      static Geant4Action* toAction(Geant4StackingAction* f)           { return f;          }
-      static Geant4Action* toAction(Geant4GeneratorAction* f)          { return f;          }
-      static Geant4Action* toAction(Geant4GeneratorActionSequence* f)  { return f;          }
-      static Geant4Action* toAction(Geant4RunActionSequence* f)        { return f;          }
-      static Geant4Action* toAction(Geant4EventActionSequence* f)      { return f;          }
-      static Geant4Action* toAction(Geant4TrackingActionSequence* f)   { return f;          }
-      static Geant4Action* toAction(Geant4SteppingActionSequence* f)   { return f;          }
-      static Geant4Action* toAction(Geant4StackingActionSequence* f)   { return f;          }
-      static Geant4Action* toAction(Geant4PhysicsListActionSequence* f){ return f;          }
-      static Geant4Action* toAction(Geant4SensDetActionSequence* f)    { return f;          }
-
-      static Geant4Action* toAction(FilterHandle f)                    { return f.action;   }
-      static Geant4Action* toAction(ActionHandle f)                    { return f.action;   }
-      static Geant4Action* toAction(PhaseActionHandle f)               { return f.action;   }
-      static Geant4Action* toAction(SensitiveHandle f)                 { return f.action;   }
-      static Geant4Action* toAction(PhysicsListHandle f)               { return f.action;   }
-      static Geant4Action* toAction(RunActionHandle f)                 { return f.action;   }
-      static Geant4Action* toAction(EventActionHandle f)               { return f.action;   }
-      static Geant4Action* toAction(TrackingActionHandle f)            { return f.action;   }
-      static Geant4Action* toAction(SteppingActionHandle f)            { return f.action;   }
-      static Geant4Action* toAction(StackingActionHandle f)            { return f.action;   }
-      static Geant4Action* toAction(GeneratorActionHandle f)           { return f.action;   }
-      static Geant4Action* toAction(GeneratorActionSequenceHandle f)   { return f.action;   }
-      static Geant4Action* toAction(RunActionSequenceHandle f)         { return f.action;   }
-      static Geant4Action* toAction(EventActionSequenceHandle f)       { return f.action;   }
-      static Geant4Action* toAction(TrackingActionSequenceHandle f)    { return f.action;   }
-      static Geant4Action* toAction(SteppingActionSequenceHandle f)    { return f.action;   }
-      static Geant4Action* toAction(StackingActionSequenceHandle f)    { return f.action;   }
-      static Geant4Action* toAction(PhysicsListActionSequenceHandle f) { return f.action;   }
-      static Geant4Action* toAction(SensDetActionSequenceHandle f)     { return f.action;   }
-      static PropertyResult getProperty(Geant4Action* action, const string& name)  {
-	if ( action->hasProperty(name) )  {
+    template <typename H,typename T> static H cr(KernelHandle& kernel, const string& name_type)  {
+    T action(*kernel.get(),name_type);
+    H handle(action.get());
+    return handle;
+  }
+    static ActionHandle createAction(KernelHandle& kernel, const string& name_type)   
+    { return cr<ActionHandle,Setup::Action>(kernel,name_type);                            }
+    static FilterHandle createFilter(KernelHandle& kernel, const string& name_type)
+    { return cr<FilterHandle,Setup::Filter>(kernel,name_type);                            }
+    static PhaseActionHandle createPhaseAction(KernelHandle& kernel, const string& name_type)   
+    { return cr<PhaseActionHandle,Setup::PhaseAction>(kernel,name_type);                  }
+    static PhysicsListHandle createPhysicsList(KernelHandle& kernel, const string& name_type)
+    { return cr<PhysicsListHandle,Setup::PhysicsList>(kernel,name_type);                  }
+    static RunActionHandle createRunAction(KernelHandle& kernel, const string& name_type)
+    { return cr<RunActionHandle,Setup::RunAction>(kernel,name_type);                      }
+    static EventActionHandle createEventAction(KernelHandle& kernel, const string& name_type)
+    { return cr<EventActionHandle,Setup::EventAction>(kernel,name_type);                  }
+    static TrackingActionHandle createTrackingAction(KernelHandle& kernel, const string& name_type)
+    { return cr<TrackingActionHandle,Setup::TrackAction>(kernel,name_type);               }
+    static SteppingActionHandle createSteppingAction(KernelHandle& kernel, const string& name_type)
+    { return cr<SteppingActionHandle,Setup::StepAction>(kernel,name_type);                }
+    static StackingActionHandle createStackingAction(KernelHandle& kernel, const string& name_type)
+    { return cr<StackingActionHandle,Setup::StackAction>(kernel,name_type);               }
+    static GeneratorActionHandle createGeneratorAction(KernelHandle& kernel, const string& name_type)
+    { return cr<GeneratorActionHandle,Setup::GenAction>(kernel,name_type);                }
+    static SensitiveHandle createSensitive(KernelHandle& kernel, const string& name_type, const string& detector)
+    {	return SensitiveHandle(Setup::Sensitive(*kernel.get(),name_type,detector).get());   }
+    static SensDetActionSequenceHandle createSensDetSequence(KernelHandle& kernel, const string& name_type)
+    {	return cr<SensDetActionSequenceHandle,Setup::SensitiveSeq>(kernel,name_type);       }
+
+    static Geant4Action* toAction(Geant4Filter* f)                   { return f;          }
+    static Geant4Action* toAction(Geant4Action* f)                   { return f;          }
+    static Geant4Action* toAction(Geant4PhaseAction* f)              { return f;          }
+    static Geant4Action* toAction(Geant4Sensitive* f)                { return f;          }
+    static Geant4Action* toAction(Geant4PhysicsList* f)              { return f;          }
+    static Geant4Action* toAction(Geant4RunAction* f)                { return f;          }
+    static Geant4Action* toAction(Geant4EventAction* f)              { return f;          }
+    static Geant4Action* toAction(Geant4TrackingAction* f)           { return f;          }
+    static Geant4Action* toAction(Geant4SteppingAction* f)           { return f;          }
+    static Geant4Action* toAction(Geant4StackingAction* f)           { return f;          }
+    static Geant4Action* toAction(Geant4GeneratorAction* f)          { return f;          }
+    static Geant4Action* toAction(Geant4GeneratorActionSequence* f)  { return f;          }
+    static Geant4Action* toAction(Geant4RunActionSequence* f)        { return f;          }
+    static Geant4Action* toAction(Geant4EventActionSequence* f)      { return f;          }
+    static Geant4Action* toAction(Geant4TrackingActionSequence* f)   { return f;          }
+    static Geant4Action* toAction(Geant4SteppingActionSequence* f)   { return f;          }
+    static Geant4Action* toAction(Geant4StackingActionSequence* f)   { return f;          }
+    static Geant4Action* toAction(Geant4PhysicsListActionSequence* f){ return f;          }
+    static Geant4Action* toAction(Geant4SensDetActionSequence* f)    { return f;          }
+
+    static Geant4Action* toAction(FilterHandle f)                    { return f.action;   }
+    static Geant4Action* toAction(ActionHandle f)                    { return f.action;   }
+    static Geant4Action* toAction(PhaseActionHandle f)               { return f.action;   }
+    static Geant4Action* toAction(SensitiveHandle f)                 { return f.action;   }
+    static Geant4Action* toAction(PhysicsListHandle f)               { return f.action;   }
+    static Geant4Action* toAction(RunActionHandle f)                 { return f.action;   }
+    static Geant4Action* toAction(EventActionHandle f)               { return f.action;   }
+    static Geant4Action* toAction(TrackingActionHandle f)            { return f.action;   }
+    static Geant4Action* toAction(SteppingActionHandle f)            { return f.action;   }
+    static Geant4Action* toAction(StackingActionHandle f)            { return f.action;   }
+    static Geant4Action* toAction(GeneratorActionHandle f)           { return f.action;   }
+    static Geant4Action* toAction(GeneratorActionSequenceHandle f)   { return f.action;   }
+    static Geant4Action* toAction(RunActionSequenceHandle f)         { return f.action;   }
+    static Geant4Action* toAction(EventActionSequenceHandle f)       { return f.action;   }
+    static Geant4Action* toAction(TrackingActionSequenceHandle f)    { return f.action;   }
+    static Geant4Action* toAction(SteppingActionSequenceHandle f)    { return f.action;   }
+    static Geant4Action* toAction(StackingActionSequenceHandle f)    { return f.action;   }
+    static Geant4Action* toAction(PhysicsListActionSequenceHandle f) { return f.action;   }
+    static Geant4Action* toAction(SensDetActionSequenceHandle f)     { return f.action;   }
+    static PropertyResult getProperty(Geant4Action* action, const string& name)  {
+    if ( action->hasProperty(name) )  {
 	  return PropertyResult(action->property(name).str(),1);
-	}
-	return PropertyResult("",0);
-      }
+    }
+    return PropertyResult("",0);
+    }
       static int setProperty(Geant4Action* action, const string& name, const string& value)  {
-	if ( action->hasProperty(name) )  {
-	  action->property(name).str(value);
-	  return 1;
-	}
-	return 0;
+        if ( action->hasProperty(name) )  {
+          action->property(name).str(value);
+          return 1;
+        }
+        return 0;
       }
       static PropertyResult getPropertyKernel(Geant4Kernel* kernel, const string& name)  {
-	if ( kernel->hasProperty(name) )  {
-	  return PropertyResult(kernel->property(name).str(),1);
-	}
-	return PropertyResult("",0);
+        if ( kernel->hasProperty(name) )  {
+          return PropertyResult(kernel->property(name).str(),1);
+        }
+        return PropertyResult("",0);
       }
       static int setPropertyKernel(Geant4Kernel* kernel, const string& name, const string& value)  {
-	if ( kernel->hasProperty(name) )  {
-	  kernel->property(name).str(value);
-	  return 1;
-	}
-	return 0;
+        if ( kernel->hasProperty(name) )  {
+          kernel->property(name).str(value);
+          return 1;
+        }
+        return 0;
       }
     };
   }
@@ -241,6 +242,7 @@ namespace {
 #pragma link C++ class Geant4Kernel::PhaseSelector;
 #pragma link C++ class Geant4Context;
 #pragma link C++ class KernelHandle;
+#pragma link C++ class Geant4Random;
 
 #pragma link C++ class Geant4RunActionSequence;
 #pragma link C++ class Geant4RunAction;
diff --git a/DDG4/src/Geant4Exec.cpp b/DDG4/src/Geant4Exec.cpp
index d4d72c1160bb3e6def6eb2f590650806f7407c93..4a9c59c9da7826010d2d9e568685d5e9f7ed2dca 100644
--- a/DDG4/src/Geant4Exec.cpp
+++ b/DDG4/src/Geant4Exec.cpp
@@ -51,7 +51,6 @@ namespace DD4hep {
 
     namespace {
       Geant4Context* s_globalContext = 0;
-      Geant4Random*  s_globalRandom = 0;
     }
 
     Geant4Context* ddg4_globalContext()   {
@@ -77,24 +76,24 @@ namespace DD4hep {
       void _aquire(T* s) {
         InstanceCount::increment(this);
         m_sequence = s;
-        m_sequence->addRef();
+        if ( m_sequence ) m_sequence->addRef();
       }
       void _release() {
         releasePtr(m_sequence);
         InstanceCount::decrement(this);
       }
       Geant4Context* context() const  {  
-	return m_activeContext;
+        return m_activeContext;
       }
       Geant4Kernel& kernel()  const  {
-	return context()->kernel();
+        return context()->kernel();
       }
 
       void setContextToClients()   {
-        (Geant4Action::ContextUpdate(m_activeContext))(m_sequence);
+        if ( m_sequence ) (Geant4Action::ContextUpdate(m_activeContext))(m_sequence);
       }
       void releaseContextFromClients()  {
-        Geant4Action::ContextUpdate(0)(m_sequence);
+        if ( m_sequence ) Geant4Action::ContextUpdate(0)(m_sequence);
       }
       void createClientContext(const G4Run* run)   {
         Geant4Run* r = new Geant4Run(run);
@@ -110,7 +109,7 @@ namespace DD4hep {
         }
       }
       void createClientContext(const G4Event* evt)   {
-        Geant4Event* e = new Geant4Event(evt,s_globalRandom);
+        Geant4Event* e = new Geant4Event(evt,Geant4Random::instance());
         m_activeContext->setEvent(e);
         setContextToClients();
       }
@@ -327,8 +326,13 @@ int Geant4Exec::configure(Geant4Kernel& kernel) {
   CLHEP::HepRandom::setTheEngine(new CLHEP::RanecuEngine);
   Geometry::LCDD& lcdd = kernel.lcdd();
   Geant4Context* ctx = s_globalContext = new Geant4Context(&kernel);
-  // For now do this:
-  /* Geant4Random* rnd = */ s_globalRandom = new Geant4Random();
+  Geant4Random* rndm = Geant4Random::instance(false);
+  
+  if ( !rndm )  {
+    rndm = new Geant4Random(ctx, "Geant4Random");
+    /// Initialize the engine etc.
+    rndm->initialize();
+  }
 
   kernel.executePhase("configure",0);
 
@@ -417,7 +421,7 @@ int Geant4Exec::run(Geant4Kernel& kernel) {
       Geant4Call* c = dynamic_cast<Geant4Call*>(ui);
       if ( c )  {
         (*c)(0);
-	kernel.executePhase("stop",0);
+        kernel.executePhase("stop",0);
         return 1;
       }
       ui->except("++ Geant4Exec: Failed to start UI interface.");
diff --git a/DDG4/src/Geant4GeneratorWrapper.cpp b/DDG4/src/Geant4GeneratorWrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4016a367cc54b947599ba8eaf1c797d5f9e6308a
--- /dev/null
+++ b/DDG4/src/Geant4GeneratorWrapper.cpp
@@ -0,0 +1,87 @@
+// $Id$
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "DDG4/Geant4GeneratorWrapper.h"
+
+#include "DD4hep/InstanceCount.h"
+#include "DD4hep/Plugins.h"
+#include "DD4hep/Printout.h"
+#include "DDG4/Geant4Context.h"
+//#include "DDG4/Geant4Primary.h"
+#include "DDG4/Geant4InputHandling.h"
+
+// Geant4 include files
+#include "G4Event.hh"
+#include "G4PrimaryVertex.hh"
+//#include "G4PrimaryParticle.hh"
+#include "G4VPrimaryGenerator.hh"
+
+// C/C++ include files
+#include <stdexcept>
+#include <set>
+
+using namespace DD4hep::Simulation;
+using namespace std;
+
+/// Standard constructor
+Geant4GeneratorWrapper::Geant4GeneratorWrapper(Geant4Context* ctxt, const string& nam)
+  : Geant4GeneratorAction(ctxt,nam), m_generator(0)
+{
+  declareProperty("Uses", m_generatorType);
+  declareProperty("Mask", m_mask = 1);
+  InstanceCount::increment(this);
+}
+  
+/// Default destructor
+Geant4GeneratorWrapper::~Geant4GeneratorWrapper()  {
+  deletePtr(m_generator);
+  InstanceCount::decrement(this);
+}
+
+G4VPrimaryGenerator* Geant4GeneratorWrapper::generator()   {
+  if ( 0 == m_generator )  {
+    m_generator = PluginService::Create<G4VPrimaryGenerator*>(m_generatorType);
+    if ( 0 == m_generator )  {
+      PluginDebug dbg;
+      m_generator = PluginService::Create<G4VPrimaryGenerator*>(m_generatorType);
+      if ( !m_generator )  {
+        throw runtime_error("Geant4GeneratorWrapper: FATAL Failed to "
+                            "create G4VPrimaryGenerator of type " + m_generatorType + ".");
+      }
+    }
+  }
+  return m_generator;
+}
+
+/// Event generation action callback
+void Geant4GeneratorWrapper::operator()(G4Event* event)  {
+  Geant4PrimaryEvent* prim = context()->event().extension<Geant4PrimaryEvent>();
+  set<G4PrimaryVertex*> primaries;
+  
+  /// Collect all existing interactions (primary vertices)
+  for(G4PrimaryVertex* v=event->GetPrimaryVertex(); v; v=v->GetNext())
+    primaries.insert(v);
+
+  // Now generate the new interaction
+  generator()->GeneratePrimaryVertex(event);
+
+  /// Add all the missing interactions (primary vertices) to the primary event record.
+  for(G4PrimaryVertex* v=event->GetPrimaryVertex(); v; v=v->GetNext())  {
+    if ( primaries.find(v) == primaries.end() )   {
+      Geant4PrimaryInteraction* inter = createPrimary(m_mask, v);
+      prim->add(m_mask, inter);
+    }
+  }
+}
diff --git a/DDG4/src/Geant4InputHandling.cpp b/DDG4/src/Geant4InputHandling.cpp
index 280b66d8cdc11c2aa97522f13a3da42720b95dcd..5d0be177d391ef809a90a6fe843bf9768e550e2c 100644
--- a/DDG4/src/Geant4InputHandling.cpp
+++ b/DDG4/src/Geant4InputHandling.cpp
@@ -37,6 +37,90 @@ using namespace DD4hep::Simulation;
 
 typedef ReferenceBitMask<int> PropertyMask;
 
+
+/// Create a vertex object from the Geant4 primary vertex
+Geant4Vertex* DD4hep::Simulation::createPrimary(const G4PrimaryVertex* g4)      {        
+  Geant4Vertex* v = new Geant4Vertex();
+  v->x = g4->GetX0();
+  v->y = g4->GetY0();
+  v->z = g4->GetZ0();
+  v->time = g4->GetT0();
+  return v;
+}
+
+/// Create a particle object from the Geant4 primary particle
+Geant4Particle* 
+DD4hep::Simulation::createPrimary(int particle_id, 
+                                  const Geant4Vertex* v,
+                                  const G4PrimaryParticle* g4p)
+{
+  Geant4ParticleHandle p = new Geant4Particle();
+  p->id           = particle_id;
+  p->reason       = 0;
+  p->pdgID        = g4p->GetPDGcode();
+  p->psx          = g4p->GetPx();
+  p->psy          = g4p->GetPy();
+  p->psz          = g4p->GetPz();
+  p->time         = g4p->GetProperTime();
+  p->properTime   = g4p->GetProperTime();
+  p->vsx          = v->x;
+  p->vsy          = v->y;
+  p->vsz          = v->z;
+  p->vex          = v->x;
+  p->vey          = v->y;
+  p->vez          = v->z;
+  //p->definition   = g4p->GetG4code();
+  //p->process      = 0;
+  p->spin[0]      = 0;
+  p->spin[1]      = 0;
+  p->spin[2]      = 0;
+  p->colorFlow[0] = 0;
+  p->colorFlow[0] = 0;
+  p->mass         = g4p->GetMass();
+  p->charge       = g4p->GetCharge();
+  PropertyMask status(p->status);
+  status.set(G4PARTICLE_GEN_STABLE);
+  return p;
+}
+
+/// Helper to recursively collect interaction data
+void collectPrimaries(Geant4PrimaryInteraction* interaction, 
+                      Geant4Vertex*             particle_origine,
+                      const G4PrimaryParticle*  gp)
+{
+  int pid = int(interaction->particles.size());
+  Geant4Particle* p = createPrimary(pid,particle_origine,gp);
+  G4PrimaryParticle* dau = gp->GetDaughter();
+  int mask = interaction->mask;
+  
+  interaction->particles.insert(make_pair(p->id,p));
+  p->mask = mask;
+  particle_origine->out.insert(p->id);
+  if ( dau )   {
+    Geant4Vertex* dv = new Geant4Vertex(*particle_origine);
+    int vid = int(interaction->vertices.size());
+    dv->mask = mask;
+    dv->in.insert(p->id);
+    interaction->vertices.insert(make_pair(vid,dv));
+    for(; dau; dau = dau->GetNext())
+      collectPrimaries(interaction, dv, dau);
+  }
+}
+
+/// Import a Geant4 interaction defined by a primary vertex into a DDG4 interaction record
+Geant4PrimaryInteraction* DD4hep::Simulation::createPrimary(int mask, const G4PrimaryVertex* gv)  {
+  Geant4PrimaryInteraction* interaction = new Geant4PrimaryInteraction();
+  Geant4Vertex* v = createPrimary(gv);
+  int vid = int(interaction->vertices.size());
+  interaction->locked = true;
+  interaction->mask = mask;
+  v->mask = mask;
+  interaction->vertices.insert(make_pair(vid,v));
+  for (G4PrimaryParticle *gp = gv->GetPrimary(); gp; gp = gp->GetNext() )
+    collectPrimaries(interaction, v, gp);
+  return interaction;
+}
+
 /// Initialize the generation of one event
 int DD4hep::Simulation::generationInitialization(const Geant4Action* /* caller */,
                                                  const Geant4Context* context)
@@ -150,7 +234,7 @@ int DD4hep::Simulation::mergeInteractions(const Geant4Action* caller,
 }
 
 /// Boost particles of one interaction identified by its mask
-int DD4hep::Simulation::boostInteraction(const Geant4Action* /* caller */,
+int DD4hep::Simulation::boostInteraction(const Geant4Action* caller,
                                          Geant4PrimaryEvent::Interaction* inter,
                                          double alpha)
 {
@@ -160,7 +244,11 @@ int DD4hep::Simulation::boostInteraction(const Geant4Action* /* caller */,
   double gamma = std::sqrt(1 + SQR(tan(alpha)));
   double betagamma = std::tan(alpha);
 
-  if ( alpha != 0.0 )  {
+  if ( inter->locked )  {
+    caller->abortRun("Locked interactions may not be boosted!",
+                     "Cannot boost interactions with a native G4 primary record!");
+  }
+  else if ( alpha != 0.0 )  {
     // Now move begin and end-vertex of all primary vertices accordingly
     for(iv=inter->vertices.begin(); iv != inter->vertices.end(); ++iv)  {
       Geant4Vertex* v = (*iv).second;
@@ -202,13 +290,18 @@ int DD4hep::Simulation::boostInteraction(const Geant4Action* /* caller */,
 }
 
 /// Smear the primary vertex of an interaction
-int DD4hep::Simulation::smearInteraction(const Geant4Action* /* caller */,
+int DD4hep::Simulation::smearInteraction(const Geant4Action* caller,
                                          Geant4PrimaryEvent::Interaction* inter,
                                          double dx, double dy, double dz, double dt)
 {
   Geant4PrimaryEvent::Interaction::VertexMap::iterator iv;
   Geant4PrimaryEvent::Interaction::ParticleMap::iterator ip;
 
+  if ( inter->locked )  {
+    caller->abortRun("Locked interactions may not be smeared!",
+                     "Cannot smear interactions with a native G4 primary record!");
+  }
+  
   // Now move begin and end-vertex of all primary vertices accordingly
   for(iv=inter->vertices.begin(); iv != inter->vertices.end(); ++iv)  {
     Geant4Vertex* v = (*iv).second;
@@ -319,38 +412,45 @@ int DD4hep::Simulation::generatePrimaries(const Geant4Action* caller,
   set<int> visited;
   char text[64];
 
-  Geant4PrimaryInteraction::VertexMap::iterator ivfnd, iv, ivend;
-  for(Interaction::VertexMap::const_iterator iend=vm.end(),i=vm.begin(); i!=iend; ++i)  {
-    int num_part = 0;
-    Geant4Vertex* v = (*i).second;
-    G4PrimaryVertex* v4 = new G4PrimaryVertex(v->x,v->y,v->z,v->time);
-    event->AddPrimaryVertex(v4);
-    caller->print("+++++ G4PrimaryVertex at (%+.2e,%+.2e,%+.2e) [mm] %+.2e [ns]",
-                  v->x/CLHEP::mm,v->y/CLHEP::mm,v->z/CLHEP::mm,v->time/CLHEP::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)  {
-          Geant4ParticleHandle r = (*j).first;
-          G4PrimaryParticle* p4 = (*j).second;
-          PropertyMask reason(r->reason);
-          reason.set(G4PARTICLE_PRIMARY);
-          v4->SetPrimary(p4);
-          ::snprintf(text,sizeof(text),"-> G4Primary[%3d]",num_part);
-          r.dumpWithMomentum(caller->outputLevel()-1,caller->name(),text);
-          ++num_part;
+  if ( !interaction->locked )  {
+    caller->abortRun("Locked interactions may not be used to generate primaries!",
+                     "Cannot handle a native G4 primary record!");
+    return 0;
+  }
+  else   {
+    Geant4PrimaryInteraction::VertexMap::iterator ivfnd, iv, ivend;
+    for(Interaction::VertexMap::const_iterator iend=vm.end(),i=vm.begin(); i!=iend; ++i)  {
+      int num_part = 0;
+      Geant4Vertex* v = (*i).second;
+      G4PrimaryVertex* v4 = new G4PrimaryVertex(v->x,v->y,v->z,v->time);
+      event->AddPrimaryVertex(v4);
+      caller->print("+++++ G4PrimaryVertex at (%+.2e,%+.2e,%+.2e) [mm] %+.2e [ns]",
+                    v->x/CLHEP::mm,v->y/CLHEP::mm,v->z/CLHEP::mm,v->time/CLHEP::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)  {
+            Geant4ParticleHandle r = (*j).first;
+            G4PrimaryParticle* p4 = (*j).second;
+            PropertyMask reason(r->reason);
+            reason.set(G4PARTICLE_PRIMARY);
+            v4->SetPrimary(p4);
+            ::snprintf(text,sizeof(text),"-> G4Primary[%3d]",num_part);
+            r.dumpWithMomentum(caller->outputLevel()-1,caller->name(),text);
+            ++num_part;
+          }
         }
       }
     }
-  }
-  for(map<int,G4PrimaryParticle*>::iterator i=prim.begin(); i!=prim.end(); ++i)  {
-    Geant4ParticleHandle p = pm[(*i).first];
-    primaries->primaryMap[(*i).second] = p->addRef();
+    for(map<int,G4PrimaryParticle*>::iterator i=prim.begin(); i!=prim.end(); ++i)  {
+      Geant4ParticleHandle p = pm[(*i).first];
+      primaries->primaryMap[(*i).second] = p->addRef();
+    }
   }
   return 1;
 }
diff --git a/DDG4/src/Geant4InteractionVertexBoost.cpp b/DDG4/src/Geant4InteractionVertexBoost.cpp
index 9b3e6b112bb481dca672c4b2c01b96122d425179..369e6e12d9bf98766fcf9a92a6559be2c7b60b6e 100644
--- a/DDG4/src/Geant4InteractionVertexBoost.cpp
+++ b/DDG4/src/Geant4InteractionVertexBoost.cpp
@@ -26,7 +26,7 @@ Geant4InteractionVertexBoost::Geant4InteractionVertexBoost(Geant4Context* ctxt,
 {
   InstanceCount::increment(this);
   declareProperty("Angle", m_angle = 0);
-  declareProperty("Mask",  m_mask = 0);
+  declareProperty("Mask",  m_mask = 1);
   m_needsControl = true;
 }
 
@@ -35,11 +35,26 @@ Geant4InteractionVertexBoost::~Geant4InteractionVertexBoost() {
   InstanceCount::decrement(this);
 }
 
-/// Callback to generate primary particles
-void Geant4InteractionVertexBoost::operator()(G4Event*) {
-  Geant4PrimaryEvent::Interaction* inter =
-    context()->event().extension<Geant4PrimaryEvent>()->get(m_mask);
+/// Action to boost one single interaction according to the properties
+void Geant4InteractionVertexBoost::boost(Interaction* inter)  const  {
   if ( inter )  {
     boostInteraction(this, inter, m_angle);
+    return;
+  }
+  print("+++ No interaction of type %d present.",m_mask);
+}
+
+/// Callback to generate primary particles
+void Geant4InteractionVertexBoost::operator()(G4Event*) {
+  typedef std::vector<Geant4PrimaryInteraction*> _I;
+  Geant4PrimaryEvent* evt = context()->event().extension<Geant4PrimaryEvent>();
+
+  if ( m_mask >= 0 )  {
+    Interaction* inter = evt->get(m_mask);
+    boost(inter);
+    return;
   }
+  _I interactions = evt->interactions();
+  for(_I::iterator i=interactions.begin(); i != interactions.end(); ++i)
+    boost(*i);
 }
diff --git a/DDG4/src/Geant4InteractionVertexSmear.cpp b/DDG4/src/Geant4InteractionVertexSmear.cpp
index 00254a5d784481f9255f3160a79bf6b86be69344..396f35f9633dd0bd6a73b7e1e1f05634d06ad9ca 100644
--- a/DDG4/src/Geant4InteractionVertexSmear.cpp
+++ b/DDG4/src/Geant4InteractionVertexSmear.cpp
@@ -32,7 +32,7 @@ Geant4InteractionVertexSmear::Geant4InteractionVertexSmear(Geant4Context* ctxt,
   InstanceCount::increment(this);
   declareProperty("Offset", m_offset);
   declareProperty("Sigma",  m_sigma);
-  declareProperty("Mask",   m_mask = 0);
+  declareProperty("Mask",   m_mask = 1);
   m_needsControl = true;
 }
 
@@ -41,13 +41,10 @@ Geant4InteractionVertexSmear::~Geant4InteractionVertexSmear() {
   InstanceCount::decrement(this);
 }
 
-/// Callback to generate primary particles
-void Geant4InteractionVertexSmear::operator()(G4Event*) {
-  typedef Geant4PrimaryEvent::Interaction Interaction;
-  Geant4Random& rndm = context()->event().random();
-  Geant4PrimaryEvent* evt = context()->event().extension<Geant4PrimaryEvent>();
-  Interaction* inter = evt->get(m_mask);
 
+/// Action to smear one single interaction according to the properties
+void Geant4InteractionVertexSmear::smear(Interaction* inter)  const  {
+  Geant4Random& rndm = context()->event().random();
   if ( inter )  {
     double dx = rndm.gauss(m_offset.x(),m_sigma.x());
     double dy = rndm.gauss(m_offset.y(),m_sigma.y());
@@ -57,8 +54,22 @@ void Geant4InteractionVertexSmear::operator()(G4Event*) {
           "by (%+.2e mm, %+.2e mm, %+.2e mm, %+.2e ns)",
           m_mask,int(inter->vertices.size()),int(inter->particles.size()),dx,dy,dz,dt);
     smearInteraction(this,inter,dx,dy,dz,dt);
+    return;
   }
-  else  {
-    print("+++ No interaction of type %d present.",m_mask);
+  print("+++ No interaction of type %d present.",m_mask);
+}
+
+/// Callback to generate primary particles
+void Geant4InteractionVertexSmear::operator()(G4Event*) {
+  typedef std::vector<Geant4PrimaryInteraction*> _I;
+  Geant4PrimaryEvent* evt = context()->event().extension<Geant4PrimaryEvent>();
+
+  if ( m_mask >= 0 )  {
+    Interaction* inter = evt->get(m_mask);
+    smear(inter);
+    return;
   }
+  _I interactions = evt->interactions();
+  for(_I::iterator i=interactions.begin(); i != interactions.end(); ++i)
+    smear(*i);
 }
diff --git a/DDG4/src/Geant4ParticleGun.cpp b/DDG4/src/Geant4ParticleGun.cpp
index e4d0be7b626c53058ceb9e9fcedf5c048ede1f0c..40bb01e93b8ac0b2476382db3ccd94166acbd57b 100644
--- a/DDG4/src/Geant4ParticleGun.cpp
+++ b/DDG4/src/Geant4ParticleGun.cpp
@@ -98,13 +98,14 @@ void Geant4ParticleGun::operator()(G4Event* event)   {
   Geant4Vertex* vtx = new Geant4Vertex();
   inter->vertices.insert(make_pair(m_mask,vtx));
   prim->add(m_mask, inter);
-
+  vtx->mask = m_mask;
   vtx->x = m_position.X();
   vtx->y = m_position.Y();
   vtx->z = m_position.Z();
   for(int i=0; i<m_multiplicity; ++i)    {
     Geant4ParticleHandle p = new Geant4Particle(i);
     p->reason       = 0;
+    p->mask         = m_mask;
     p->pdgID        = m_particle->GetPDGEncoding();
     p->psx          = m_direction.X()*m_energy;
     p->psy          = m_direction.Y()*m_energy;
diff --git a/DDG4/src/Geant4Plugins.cpp b/DDG4/src/Geant4Plugins.cpp
index ec4513de11dbdbe6d6fce2106aa2ec87ede1ac20..7d58fd1a1cc5bbfd484f0400cad3fe41d851fb97 100644
--- a/DDG4/src/Geant4Plugins.cpp
+++ b/DDG4/src/Geant4Plugins.cpp
@@ -41,6 +41,7 @@ DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(G4MagIntegratorStepper*, (G4Mag_EqRhs*))
 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(G4Mag_EqRhs*, (G4MagneticField*))
 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(G4VProcess*, ())
 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(G4VPhysicsConstructor*, ())
+DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(G4VPrimaryGenerator*, ())
 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(G4ParticleDefinition*, ())
 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(G4VUserPhysicsList*, (DD4hep::Simulation::Geant4PhysicsListActionSequence*,int))
 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(DD4hep::Simulation::Geant4EventReader*, (std::string))
diff --git a/DDG4/src/Geant4Primary.cpp b/DDG4/src/Geant4Primary.cpp
index 1f4773bfbf822ee030feb5fbb05057bb38282598..652c5db3787460149bb4ceeb7a51a7e6d62a1c8f 100644
--- a/DDG4/src/Geant4Primary.cpp
+++ b/DDG4/src/Geant4Primary.cpp
@@ -35,13 +35,13 @@ Geant4PrimaryMap::~Geant4PrimaryMap()   {
 
 /// Default constructor
 Geant4PrimaryInteraction::Geant4PrimaryInteraction()
-  : mask(0), next_particle_identifier(-1)
+  : mask(0), locked(0), next_particle_identifier(-1)
 {
 }
 
 /// Copy constructor
 Geant4PrimaryInteraction::Geant4PrimaryInteraction(const Geant4PrimaryInteraction&)
-  : mask(0), next_particle_identifier(-1)
+  : mask(0), locked(0), next_particle_identifier(-1)
 {
 }
 
diff --git a/DDG4/src/Geant4Random.cpp b/DDG4/src/Geant4Random.cpp
index da0306366ac0c7968d71488f099e2265c8fcdd73..bdb7aee1142de78a532b208120f59fbf259d3951 100644
--- a/DDG4/src/Geant4Random.cpp
+++ b/DDG4/src/Geant4Random.cpp
@@ -17,6 +17,9 @@
 #include "DD4hep/InstanceCount.h"
 #include "DDG4/Geant4Random.h"
 
+#include "CLHEP/Random/EngineFactory.h"
+#include "CLHEP/Random/Random.h"
+
 // ROOT include files
 #include "TRandom1.h"
 
@@ -26,63 +29,266 @@
 using namespace std;
 using namespace DD4hep::Simulation;
 
+namespace CLHEP   {
+  unsigned long crc32ul(const std::string& s);
+}
+
+namespace    {
+
+  /// Helper class to redirect calls to gRandon to Geant4Random
+  class RNDM : public TRandom  {
+    /// Reference to the generator object
+    Geant4Random* m_generator;
+    /// Reference to HepRandomEngine
+    CLHEP::HepRandomEngine* m_engine;
+    
+  public:
+    /// Initializing constructor
+    RNDM(Geant4Random* r) : TRandom(), m_generator(r)    {
+      m_engine = m_generator->engine();
+    }
+    /// Default destructor
+    virtual ~RNDM() {      }
+    /// Set new seed
+    virtual  void SetSeed(UInt_t seed=0)    {
+      fSeed = seed;
+      m_generator->setSeed((long)seed);
+    }
+    /// Single shot random number creation
+    virtual Double_t Rndm(Int_t)  {
+      return m_engine->flat();
+    }
+    /// Return an array of n random numbers uniformly distributed in ]0,1].
+    virtual void RndmArray(Int_t size, Float_t *array)    {
+      for (Int_t i=0;i<size;i++) array[i] = m_engine->flat();
+    }
+    /// Return an array of n random numbers uniformly distributed in ]0,1].
+    virtual void RndmArray(Int_t size, Double_t *array)    {
+      m_engine->flatArray(size,array);
+    }
+  };
+  static Geant4Random* s_instance = 0;
+}
+
 /// Default constructor
-Geant4Random::Geant4Random()   {
-  if ( 0 == gRandom ) gRandom = new TRandom1();
+Geant4Random::Geant4Random(Geant4Context* ctxt, const std::string& nam)
+  : Geant4Action(ctxt,nam), m_engine(0), m_rootRandom(0), m_rootOLD(0), 
+    m_inited(false)
+{
+  declareProperty("File",   m_file="");
+  declareProperty("Type",   m_engineType="");
+  declareProperty("Seed",   m_seed = 123456789);
+  declareProperty("Luxury", m_luxury = 1);
+  declareProperty("Replace_gRandom",  m_replace = true);
+  // Default: static Geant4 random engine.
+  m_engine = CLHEP::HepRandom::getTheEngine();
   InstanceCount::increment(this);
 }
 
 /// Default destructor
 Geant4Random::~Geant4Random()  {
+  if (  s_instance == this ) s_instance = 0;
+  if ( !m_engineType.empty() ) deletePtr(m_engine);
+  if (  m_rootRandom == gRandom ) gRandom = m_rootOLD;
+  deletePtr(m_rootRandom);
   InstanceCount::decrement(this);
 }
 
-void   Geant4Random::circle(double &x, double &y, double r)  {
-  gRandom->Circle(x,y,r);
+/// Access the main Geant4 random generator instance. Must be created before used!
+Geant4Random* Geant4Random::instance(bool throw_exception)   {
+  if ( !s_instance && throw_exception )  {
+    throw runtime_error("No global random number generator defined!");
+  }  
+  return s_instance;
 }
 
-//
-double Geant4Random::exp(double tau)  {
-  return gRandom->Exp(tau);
+/// Make this random generator instance the one used by Geant4
+ Geant4Random* Geant4Random::setMainInstance(Geant4Random* ptr)   {
+   if ( s_instance != ptr )   {
+     if ( !ptr )  {
+       throw runtime_error("Attempt to declare invalid Geant4Random instance.");
+     }
+     if ( !ptr->m_inited )  {
+       throw runtime_error("Attempt to declare uninitialized Geant4Random instance.");
+     }
+     Geant4Random* old = s_instance;
+     if ( ptr->m_engine != CLHEP::HepRandom::getTheEngine() )     {       
+       CLHEP::HepRandom::setTheEngine(ptr->m_engine);
+     }
+     if ( ptr->m_replace )   {
+       ptr->m_rootOLD = gRandom;
+       gRandom = ptr->m_rootRandom;
+     }
+     s_instance = ptr;
+     return old;
+   }
+   return 0;
 }
 
-//
-double Geant4Random::gauss(double mean, double sigma)  {
-  return gRandom->Gaus(mean,sigma);
+#include "CLHEP/Random/DualRand.h"
+#include "CLHEP/Random/JamesRandom.h"
+#include "CLHEP/Random/MTwistEngine.h"
+#include "CLHEP/Random/RanecuEngine.h"
+#include "CLHEP/Random/Ranlux64Engine.h"
+#include "CLHEP/Random/RanluxEngine.h"
+#include "CLHEP/Random/RanshiEngine.h"
+#include "CLHEP/Random/NonRandomEngine.h"
+
+/// Initialize the instance. 
+void Geant4Random::initialize()   {
+  if ( !m_file.empty() )  {
+    ifstream in(m_file);
+    m_engine = CLHEP::EngineFactory::newEngine(in);
+    if ( !m_engine )    {
+      except("Failed to create CLHEP random engine from file:%s.",m_file.c_str());
+    }
+    m_seed = m_engine->getSeed();
+  }
+  else if ( !m_engineType.empty() )    {
+    /// Create new engine if a type is specified
+    if ( m_engineType == CLHEP::HepJamesRandom::engineName() )
+      m_engine = new CLHEP::HepJamesRandom();
+    else if ( m_engineType == CLHEP::RanecuEngine::engineName() )
+      m_engine = new CLHEP::RanecuEngine();
+    else if ( m_engineType == CLHEP::Ranlux64Engine::engineName() )
+      m_engine = new CLHEP::Ranlux64Engine();
+    else if ( m_engineType == CLHEP::MTwistEngine::engineName() )
+      m_engine = new CLHEP::MTwistEngine();
+    else if ( m_engineType == CLHEP::DualRand::engineName() )
+      m_engine = new CLHEP::DualRand();
+    else if ( m_engineType == CLHEP::RanluxEngine::engineName() )
+      m_engine = new CLHEP::RanluxEngine();
+    else if ( m_engineType == CLHEP::RanshiEngine::engineName() )
+      m_engine = new CLHEP::RanshiEngine();
+    else if ( m_engineType == CLHEP::NonRandomEngine::engineName() )
+      m_engine = new CLHEP::NonRandomEngine();
+
+    if ( !m_engine )    {
+      except("Failed to create CLHEP random engine of type: %s.",m_engineType.c_str());
+    }
+  }
+  m_engine->setSeed(m_seed,m_luxury);
+  m_rootRandom = new RNDM(this);
+  m_inited = true;
+  if ( 0 == s_instance )   {
+    setMainInstance(this);
+  }
 }
 
-//
-double Geant4Random::landau(double mean, double sigma)  {
-  return gRandom->Landau(mean,sigma);
+/// Should initialise the status of the algorithm according to seed.
+void Geant4Random::setSeed(long seed)   {
+  if ( !m_inited ) initialize();
+  m_engine->setSeed(m_seed=seed,0);
 }
 
-//
+/// Should initialise the status of the algorithm
+/** Initialization according to the zero terminated
+ *  array of seeds. It is allowed to ignore one or 
+ *  many seeds in this array.
+ */
+void Geant4Random::setSeeds(const long* seeds, int size)   {
+  if ( !m_inited ) initialize();
+  m_seed = seeds[0];
+  m_engine->setSeeds(seeds, size);
+}
+
+/// Should save on a file specific to the instantiated engine in use the current status.
+void Geant4Random::saveStatus( const char filename[] ) const    {
+  if ( !m_inited )  {
+    except("Failed to save RandomGenerator status. [Not-inited]");
+  }
+  m_engine->saveStatus(filename);
+}
+
+/// Should read from a file and restore the last saved engine configuration.
+void Geant4Random::restoreStatus( const char filename[] )    {
+  if ( !m_inited ) initialize();
+  m_engine->restoreStatus(filename);
+}
+
+/// Should dump the current engine status on the screen.
+void Geant4Random::showStatus() const    {
+  if ( !m_inited )  {
+    error("Failed to show RandomGenerator status. [Not-inited]");
+    return;
+  }
+  printP2("Random engine status of object of type Geant4Random @ 0x%p",this);
+  if ( !m_file.empty() )
+    printP2("   Created from file: %s",m_file.c_str());
+  else if ( !m_engineType.empty() )
+    printP2("   Special instance created of type:%s",m_engineType.c_str());
+  else
+    printP2("   Reused HepRandom instance @ 0x%p",m_engine);
+  
+  if ( m_engine != CLHEP::HepRandom::getTheEngine() )
+    printP2("   Instance is identical to Geant4's HepRandom instance.");
+
+  printP2("   Instance is %sidentical to ROOT's gRandom instance.",
+          gRandom == m_rootRandom ? "" : "NOT ");
+
+  if ( gRandom != m_rootRandom )  {
+    printP2("      Local TRandom: 0x%p  gRandom: 0x%p",m_rootRandom,gRandom);
+  }  
+  m_engine->showStatus();
+}
+
+/// Create flat distributed random numbers in the interval ]0,1]
 double Geant4Random::rndm(int i)  {
+  if ( !m_inited ) initialize();
   return gRandom->Rndm(i);
 }
 
-//
+/// Create a float array of flat distributed random numbers in the interval ]0,1]
 void   Geant4Random::rndmArray(int n, float *array)  {
+  if ( !m_inited ) initialize();
   gRandom->RndmArray(n,array);
 }
 
-//
+/// Create a double array of flat distributed random numbers in the interval ]0,1]
 void   Geant4Random::rndmArray(int n, double *array)  {
+  if ( !m_inited ) initialize();
   gRandom->RndmArray(n,array);
 }
 
-//
-void   Geant4Random::sphere(double &x, double &y, double &z, double r)  {
-  gRandom->Sphere(x,y,z,r);
-}
-
-//
+/// Create uniformly disributed random numbers in the interval ]0,x1]
 double Geant4Random::uniform(double x1)  {
+  if ( !m_inited ) initialize();
   return gRandom->Uniform(x1);
 }
 
-//
+/// Create uniformly disributed random numbers in the interval ]x1,x2]
 double Geant4Random::uniform(double x1, double x2)  {
+  if ( !m_inited ) initialize();
   return gRandom->Uniform(x1,x2);
 }
 
+/// Create exponentially distributed random numbers
+double Geant4Random::exp(double tau)  {
+  if ( !m_inited ) initialize();
+  return gRandom->Exp(tau);
+}
+
+/// Generates random vectors, uniformly distributed over a circle of given radius.
+double Geant4Random::gauss(double mean, double sigma)  {
+  if ( !m_inited ) initialize();
+  return gRandom->Gaus(mean,sigma);
+}
+
+/// Create landau distributed random numbers
+double Geant4Random::landau(double mean, double sigma)  {
+  if ( !m_inited ) initialize();
+  return gRandom->Landau(mean,sigma);
+}
+
+/// Create tuple of randum number around a circle with radius r
+void   Geant4Random::circle(double &x, double &y, double r)  {
+  if ( !m_inited ) initialize();  
+  gRandom->Circle(x,y,r);
+}
+
+/// Create tuple of randum number on a sphere with radius r
+void   Geant4Random::sphere(double &x, double &y, double &z, double r)  {
+  if ( !m_inited ) initialize();
+  gRandom->Sphere(x,y,z,r);
+}
+
diff --git a/doc/DDG4Manual.pdf b/doc/DDG4Manual.pdf
index 48e7b2e76fa04fea785a84bc8d12a4f01f859d6d..b1092bae184bd0aedd3ee8b3119553fae0953d26 100644
Binary files a/doc/DDG4Manual.pdf and b/doc/DDG4Manual.pdf differ
diff --git a/doc/LaTex/DDG4Manual.tex b/doc/LaTex/DDG4Manual.tex
index e10d5213246f800ba02a0d562ec998eb5c65b61d..83a9c692c540ba872b68fd46c797f0f4e970ea68 100644
--- a/doc/LaTex/DDG4Manual.tex
+++ b/doc/LaTex/DDG4Manual.tex
@@ -1822,11 +1822,11 @@ interact.
 \noindent
 The {\tt{Geant4UIManager}} is a component attached to the {\tt{Geant4Kernel}}
 object. All properties of all {\tt{Geant4Action}} instances may be exported to 
-Geant4 messengers and {\em{may}} hence be accessible directly from the Geant4 
-prompt. To export properties from any action, call the {\tt{enableUI()}}
-method of the action.
+\tw{Geant4} messengers and {\em{may}} hence be accessible directly from 
+the \tw{Geant4} prompt. To export properties from any action, call the 
+{\tt{enableUI()}} method of the action.
 \noindent
-The callback signature is: void operator()(G4Event* event)
+The callback signature is: \tw{void operator()(G4Event* event)}.
 
 \vspace{0.5cm}
 \noindent
@@ -1836,23 +1836,87 @@ The callback signature is: void operator()(G4Event* event)
 \bold{File name}       & \tts{DDG4/src/Geant4.cpp}                       \\
 \bold{Type}            & \tts{Geant4Action}                              \\
 \hline
-\bold{Component Properties:}   & defaults apply                            \\
+\bold{Component Properties:}   & defaults apply                          \\
 \hline
 \bold{SessionType} (string)  & Session type (csh, tcsh, etc.             \\
 \bold{SetupUI} (string)   & Name of the UI macro file                    \\
 \bold{SetupVIS} (string)  & Name of the visualization macro file         \\
 \bold{HaveVIS} (bool)     & Flag to instantiate Vis manager 
-                            (def:false, unless VisSetup set)              \\
+                            (def:false, unless VisSetup set)             \\
 \bold{HaveUI} (bool)      & Flag to instantiate UI (default=true)        \\
 \end{tabular}
 
+%=============================================================================
+\subsubsection{Geant4Random}
+%=============================================================================
+\noindent
+Mini interface to the random generator of the application.
+Necessary, that on every object creates its own instance, but accesses
+the main instance available through the \tw{Geant4Context}.
+
+\noindent
+This is mandatory to ensure reproducibility of the event generation
+process. Particular objects may use a dependent generator from
+an experiment framework like \tw{GAUDI}.
+
+\noindent
+internally the engine factory mechanism of \tw{CLHEP} is used. Please refer
+there within for valid engine names and the random seeding mechanism,
+which may vary between different engines.
+
+\noindent
+Any number of independent random objects may be created and used 
+in parallel. This however, is not advised to ensure reproducibility.
+
+\noindent
+The first instance of the random action is automatically set
+to be the \tw{Geant4} instance. If another instance should be used by 
+\tw{Geant4}, use \tw{setMainInstance(Geant4Random* ptr)} class method to 
+override this behavior.
+Provision, steered by options, is taken to ensure the \tw{gRandom}
+of \tw{ROOT} uses the same random number engine.
+
+\vspace{0.5cm}
+\noindent
+\begin{tabular}{ l p{10cm} }
+\hline
+\bold{Class name}      & \tts{Geant4}                                    \\
+\bold{File name}       & \tts{DDG4/src/Geant4Random.cpp}                 \\
+\bold{Type}            & \tts{Geant4Random}                              \\
+\hline
+\bold{Component Properties:}   & defaults apply                          \\
+\hline
+\bold{File}   (string)       & File name if initialized from file.              \\
+                             & If set, engine name and seeds are ignored        \\
+\bold{Engine} (string)       & Engine type name.                                \\
+                             & All engines defined in the
+                               \tw{CLHEP::EngineFactory} class are available.
+                               If no type is supplied the engine from the 
+                               HepRandom generator instance is taken.           \\
+\bold{Seed}   (long)         & Initial random seed.                             \\
+                                 & Default:    123456789.                       \\
+                                 & If not ZERO terminated, termination is added.\\
+\bold{Replace\_gRandom} (bool)& Flag to replace the \tw{ROOT} \tw{gRandom}
+                                instance with this random number engine.
+                                This ensures \tw{ROOT} and \tw{Geant4} use the same 
+                                random number engine, hence the same random sequence.
+                                                    \\
+\end{tabular}
+
 
 %=============================================================================
 \subsection{Predefined Geant4 Physics List Objects}
 %=============================================================================
 \noindent
 The physics list may be defined entirely data driven using the factory mechanism
-using a variety of predefined objects:
+using a variety of predefined objects. Though users are free to define private 
+physics lists, typically the predefined physics lists from \tw{Geant4} are used. 
+
+\noindent
+The inventory changes over time, new lists appear and obsolete lists are purged,
+hence we will not list them explicitly here.
+For the inventory of available physics lists, please refer to the implementation files:
+
 \noindent
 \begin{itemize}\itemcompact
 \item Inventory of predefined physics lists, which may be inherited:\\
@@ -1972,8 +2036,8 @@ These by default are extensions of type:
 \bold{Type}            & \tts{Geant4GeneratorAction}                     \\
 \hline
 \bold{Component Properties:}   & defaults apply                            \\
-\bold{Angle} (double)  & \tts{Lorentz-Angle of boost}                          \\
-\bold{Mask} (int.bitmask)    & \tts{Interaction identifier} \\
+\bold{Angle} (double)          & \tts{Lorentz-Angle of boost}                          \\
+\bold{Mask} (int.bitmask)      & \tts{Interaction identifier} \\
 \hline
 \end{tabular}
 
@@ -1983,17 +2047,28 @@ These by default are extensions of type:
 \noindent
 Boost the primary vertex and all particles outgoing the primary interaction in X-direction.
 
+\noindent
+The interaction to be processed by the component is uniquely identified
+by the {\bf{Mask}} property. Two primary interaction may not have the same
+mask.
+
+\noindent
+{\bold{Note [special use case]:}}\\
+If all contributing interactions of the one event \bold{registered 
+in the primary event at the time the action is called} should be handled by 
+one single component instance, set the {\bf{Mask}} property to {\bold{-1}}.
+
 \vspace{0.5cm}
 \noindent
 \begin{tabular}{ l p{10cm} }
 \hline
-\bold{Class name}      & \tts{Geant4InteractionVertexBoost}              \\
-\bold{File name}       & \tts{DDG4/src/Geant4InteractionVertexBoost.cpp} \\
-\bold{Type}            & \tts{Geant4GeneratorAction}                     \\
+\bold{Class name}        & \tts{Geant4InteractionVertexBoost}              \\
+\bold{File name}         & \tts{DDG4/src/Geant4InteractionVertexBoost.cpp} \\
+\bold{Type}              & \tts{Geant4GeneratorAction}                     \\
 \hline
 \bold{Component Properties:}   & defaults apply                            \\
-\bold{Angle} (double)  & \tts{Lorentz-Angle of boost}                    \\
-\bold{Mask} (int.bitmask)    & \tts{Interaction identifier} \\
+\bold{Angle} (double)          & \tts{Lorentz-Angle of boost}              \\
+\bold{Mask} (int.bitmask)      & \tts{Interaction identifier}              \\
 \hline
 \end{tabular}
 
@@ -2003,17 +2078,28 @@ Boost the primary vertex and all particles outgoing the primary interaction in X
 \noindent
 Smear the primary vertex and all particles outgoing the primary interaction.
 
+\noindent
+The interaction to be processed by the component is uniquely identified
+by the {\bf{Mask}} property. Two primary interaction may not have the same
+mask.
+
+\noindent
+{\bold{Note [special use case]:}}\\
+If all contributing interactions of the one event \bold{registered 
+in the primary event at the time the action is called} should be handled by 
+one single component instance, set the {\bf{Mask}} property to {\bold{-1}}.
+
 \vspace{0.5cm}
 \noindent
 \begin{tabular}{ l p{10cm} }
 \hline
-\bold{Class name}      & \tts{Geant4InteractionVertexSmear}              \\
-\bold{File name}       & \tts{DDG4/src/Geant4InteractionVertexSmear.cpp} \\
+\bold{Class name}        & \tts{Geant4InteractionVertexSmear}              \\
+\bold{File name}         & \tts{DDG4/src/Geant4InteractionVertexSmear.cpp} \\
 \hline
 \bold{Component Properties:}   & defaults apply                            \\
-\bold{Offset} (PxPyPzEVector) & \tts{Smearing offset}                    \\
-\bold{Sigma}   (PxPyPzEVector) & \tts{Sigma on offset}                    \\
-\bold{Mask} (int.bitmask)    & \tts{Interaction identifier} \\
+\bold{Offset}  (PxPyPzEVector) & \tts{Smearing offset}                     \\
+\bold{Sigma}   (PxPyPzEVector) & \tts{Sigma (Errors) on offset}            \\
+\bold{Mask}    (int.bitmask)   & \tts{Interaction identifier} \\
 \hline
 \end{tabular}
 
@@ -2030,9 +2116,9 @@ and are merged into the {\tt{Geant4PrimaryInteraction}} object attached to the
 \noindent
 \begin{tabular}{ l p{10cm} }
 \hline
-\bold{Class name}      & \tts{Geant4InteractionMerger}                   \\
-\bold{File name}       & \tts{DDG4/src/Geant4InteractionMerger.cpp}      \\
-\bold{Type}            & \tts{Geant4GeneratorAction}                     \\
+\bold{Class name}        & \tts{Geant4InteractionMerger}                   \\
+\bold{File name}         & \tts{DDG4/src/Geant4InteractionMerger.cpp}      \\
+\bold{Type}              & \tts{Geant4GeneratorAction}                     \\
 \hline
 \bold{Component Properties:}   & defaults apply                            \\
 \hline
@@ -2050,9 +2136,9 @@ to Geant4 for simulation.
 \noindent
 \begin{tabular}{ l p{10cm} }
 \hline
-\bold{Class name}      & \tts{Geant4PrimaryHandler}                      \\
-\bold{File name}       & \tts{DDG4/src/Geant4PrimaryHandler.cpp}         \\
-\bold{Type}            & \tts{Geant4GeneratorAction}                     \\
+\bold{Class name}        & \tts{Geant4PrimaryHandler}                      \\
+\bold{File name}         & \tts{DDG4/src/Geant4PrimaryHandler.cpp}         \\
+\bold{Type}              & \tts{Geant4GeneratorAction}                     \\
 \hline
 \bold{Component Properties:}   & defaults apply                            \\
 \hline
@@ -2082,23 +2168,28 @@ If there is only one particle gun in use, the property 'Standalone',
 which by default is set to true invokes the interaction merging and the
 Geant4 primary generation directly.
 
+\noindent
+The interaction to be created by the component is uniquely identified
+by the {\bf{Mask}} property. Two primary interaction may not have the same
+mask.
+
 \vspace{0.5cm}
 \noindent
 \begin{tabular}{ l p{10cm} }
 \hline
-\bold{Class name}      & \tts{Geant4PrimaryHandler}                      \\
-\bold{File name}       & \tts{DDG4/src/Geant4PrimaryHandler.cpp}         \\
-\bold{Type}            & \tts{Geant4GeneratorAction}                     \\
+\bold{Class name}         & \tts{Geant4PrimaryHandler}                      \\
+\bold{File name}          & \tts{DDG4/src/Geant4PrimaryHandler.cpp}         \\
+\bold{Type}               & \tts{Geant4GeneratorAction}                     \\
 \hline
 Component Properties:     & default                                         \\
-\bold{particle} (string) & Particle type to be shot \\
-\bold{energy} (double)   & Particle energy in $MeV$ \\
+\bold{particle} (string)  & Particle type to be shot                        \\
+\bold{energy} (double)    & Particle energy in $MeV$                        \\
 \bold{position} (XYZVector)  & Pole position of the generated particles in $mm$\\
 \bold{direction} (XYZVector) & Momentum direction of the generated particles\\
-\bold{isotrop} (bool)        & Isotropic particle directions in space. \\
-\bold{Mask} (int.bitmask)    & Interaction identifier \\
-\bold{Standalone} (bool)     & Setup for standalone execution \\ 
-                              & including interaction merging etc. \\
+\bold{isotrop} (bool)        & Isotropic particle directions in space.      \\
+\bold{Mask} (int.bitmask)    & Interaction identifier                       \\
+\bold{Standalone} (bool)     & Setup for standalone execution               \\ 
+                             & including interaction merging etc.           \\
 \hline
 \end{tabular}
 
diff --git a/doc/release.notes b/doc/release.notes
index 3f6168c1b9dfed585657b33b6e5489630c9dd352..6b0e2321a3331bad0064b792a7896a8882d9162b 100644
--- a/doc/release.notes
+++ b/doc/release.notes
@@ -3,6 +3,24 @@
 DD4hep  ----  Release Notes
 =================================
 
+2015-10-09 M.Frank
+  DDG4
+  - Extend the functionality of the DDG4 plugins
+    Geant4InteractionVertexBoost and Geant4InteractionVertexSmear.
+    If the Mask property is set to -1, all interactions present
+    at call time are smeared/boosted according to the parameters.
+    Note, that the position of the plugins within the generation 
+    sequence is important.
+  - Add a new generator Geant4GeneratorWrapper to allow the use
+    of native G4 generator classes such as the G4ParticleGun or
+    the G4GeneralParticleSource. Still to be tested.
+  - Extend the Geant4Random functionality: May now be instantiated
+    like any other Geant4Action. Users may set the seed or the 
+    luxury level.
+    All calls to HepRandom (CLHEP) or gRandom (ROOT) will re-use 
+    this instance. See DDG4/examples/CLICRandom.py for illustration.
+  - Updated DDG4 manual.
+
 2015-09-15 F.Gaede
   - refactoring of Surface classes:
     - made VolSurface a reference counting handle to