diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaHepMCInterface.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaHepMCInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..44ff779143baa649e57611468e1b02222a509b1e
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaHepMCInterface.h
@@ -0,0 +1,27 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef AthenaHepMCInterface_H
+#define AthenaHepMCInterface_H
+
+#include "FadsKinematics/FadsGenerator.h"
+#include <string>
+
+class StoreGateSvc;
+class MsgStream;
+
+class AthenaHepMCInterface: public FADS::FadsGenerator {
+public:
+	AthenaHepMCInterface(std::string);
+	~AthenaHepMCInterface();
+	void Initialize();
+	void Terminate();
+	HepMC::GenEvent* GenerateAnEvent();
+private:
+	StoreGateSvc *p_sgSvc;
+	MsgStream * m_log;
+	MsgStream log();
+};
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaStackingAction.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaStackingAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..17a376942129455c0389759b27d2b51945ad2142
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaStackingAction.h
@@ -0,0 +1,31 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef AthenaStackingAction_H
+#define AthenaStackingAction_H
+
+#include "FadsActions/ApplicationStackingAction.h"
+
+class AthenaStackingAction:public FADS::ApplicationStackingAction {
+public:
+        AthenaStackingAction();
+        ~AthenaStackingAction(){}
+
+        G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track* aTrack);
+        void NewStage();
+        void PrepareNewEvent();
+
+        inline void KillAllNeutrinos(const bool a){ p_killAllNeutrinos=a; }
+        inline bool KillAllNeutrinos() const { return p_killAllNeutrinos; }
+
+        inline void KillLowEPhotons(const double a){ p_stackEnergyCut=a; }
+        inline double KillLowEPhotons() const { return p_stackEnergyCut; }
+
+private:
+
+	bool p_killAllNeutrinos;
+	double p_stackEnergyCut;
+};
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaTrackingAction.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaTrackingAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..689b8690593a6d7659694faa5c6434c655bf6b87
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/AthenaTrackingAction.h
@@ -0,0 +1,21 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef AthenaTrackingAction_H
+#define AthenaTrackingAction_H
+
+#include "FadsActions/ApplicationTrackingAction.h"
+
+class AthenaTrackingAction: public FADS::ApplicationTrackingAction {
+public:
+	AthenaTrackingAction(): FADS::ApplicationTrackingAction()
+	{
+	}
+	void PreUserTrackingAction(const G4Track*);
+	void PostUserTrackingAction(const G4Track*);
+private:
+
+};
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasAlg.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d320eec5434b19564e48f8974ed017f3e712da2
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasAlg.h
@@ -0,0 +1,63 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef G4AtlasAlg_H
+#define G4AtlasAlg_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaKernel/IAtRndmGenSvc.h"
+
+#include <string>
+#include <map>
+
+class AthenaStackingAction;
+class AthenaTrackingAction;
+class G4AtlasRunManager;
+
+template <class ConcreteAlgorithm> class AlgFactory;
+
+
+class G4AtlasAlg : public AthAlgorithm {
+
+    friend class AlgFactory<G4AtlasAlg>;
+
+public:
+
+	G4AtlasAlg(const std::string& name, ISvcLocator* pSvcLocator);
+  	virtual ~G4AtlasAlg() {  };
+
+  	StatusCode initialize();
+  	StatusCode finalize();
+  	StatusCode execute();
+
+	void initializeG4();
+
+private:
+
+  	G4AtlasRunManager* p_runMgr;
+
+	// Properties for the jobOptions
+  	std::string libList;
+	std::string physList;
+	std::string generator;
+	std::string fieldMap;
+	std::string rndmGen;
+	bool m_KillAllNeutrinos;
+	double m_KillLowEPhotons;
+	bool m_releaseGeoModel;
+        bool m_IncludeParentsInG4Event;
+        bool m_killAbortedEvents;
+        bool m_flagAbortedEvents;
+
+	std::map<std::string,std::string> m_verbosities;
+
+	AthenaStackingAction* stackingAction;
+	AthenaTrackingAction* trackingAction;
+
+    // Random number service
+    ServiceHandle<IAtRndmGenSvc> m_rndmGenSvc;
+};
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasAlgDict.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasAlgDict.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e6c94340a5c19590a00595b3811c06acd3d2be6
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasAlgDict.h
@@ -0,0 +1,10 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef G4ATLASALG_G4ATLASALGDICT_H
+#define G4ATLASALG_G4ATLASALGDICT_H 1
+
+#include "G4AtlasAlg/G4AtlasAlg.h"
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasRunManager.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasRunManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b4bd50bbec227b8de8877ded75f4cd0edba8a98
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasRunManager.h
@@ -0,0 +1,60 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef G4AtlasRunManager_h
+#define G4AtlasRunManager_h 1
+
+#include "G4RunManager.hh"
+#include "G4VUserPhysicsList.hh"
+#include "GaudiKernel/MsgStream.h"
+
+#include <vector>
+
+class StoreGateSvc;
+class MsgStream;
+
+class G4AtlasRunManager: public G4RunManager {
+
+  friend class G4AtlasAlg;
+  friend class SimControl;
+
+public:
+
+  virtual ~G4AtlasRunManager() { if (m_log) delete m_log; }
+
+  static G4AtlasRunManager* GetG4AtlasRunManager();
+
+  void SetPhysicsList(G4VUserPhysicsList* p) { m_pl = p; }
+  G4Event* GenerateEvent(G4int i_event);
+  bool SimulateFADSEvent();
+  void RunTermination();
+  void SetCurrentG4Event(int);
+
+protected:
+
+  void InitializeGeometry();
+  void InitializePhysics();
+
+private:
+
+  G4AtlasRunManager();
+  void EndEvent();
+
+  void SetStoreGatePtr( StoreGateSvc *sgs) { m_sgSvc = sgs; }
+  void SetReleaseGeo(bool b) { m_releaseGeo = b; }
+  void SetLogLevel(int i) { log().setLevel(i); }
+
+private:
+
+  G4VUserPhysicsList* m_pl;
+  StoreGateSvc* m_sgSvc;
+  bool m_releaseGeo;
+  MsgStream * m_log;
+  MsgStream log();
+};
+
+
+#endif
+
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/PreEventAction.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/PreEventAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..bccfc9e6cb291d3a043478fd7255ed3ec93613ae
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/PreEventAction.h
@@ -0,0 +1,20 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PreEventAction_H
+#define PreEventAction_H
+
+#include <string>
+
+class PreEventAction {
+private:
+	std::string name;
+public:
+	PreEventAction(std::string);
+	virtual ~PreEventAction() {}
+	std::string GetName();
+	virtual void Execute() = 0;
+};
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/PreEventActionManager.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/PreEventActionManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..e389a2b5358725304cc289895084c3b4a5516ee2
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/PreEventActionManager.h
@@ -0,0 +1,27 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef PreEventActionManager_H
+#define PreEventActionManager_H
+
+#include <string>
+#include <map>
+
+class PreEventAction;
+typedef std::map<std::string, PreEventAction*, std::less<std::string> > preEvActionMap;
+
+
+class PreEventActionManager {
+public:
+	static PreEventActionManager* GetPreEventActionManager();
+	void Execute();
+	void RegisterAction(PreEventAction *);
+private:
+	static PreEventActionManager* thePointer;
+	PreEventActionManager();
+	PreEventActionManager(const PreEventActionManager&) {}
+	preEvActionMap theMap;
+};
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/TruthHepMCEventConverter.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/TruthHepMCEventConverter.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf2a982e84dabe65169d2f4d8ddd346cf5411294
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/TruthHepMCEventConverter.h
@@ -0,0 +1,38 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TruthHepMCEventConverter_H
+#define TruthHepMCEventConverter_H
+
+#include "FadsKinematics/HepMCEventConverter.h"
+#include <vector>
+
+class G4PrimaryParticle;
+class G4PrimaryVertex;
+
+// Helper class to convert HepMC into G4. this is used by the Generator
+// Center, instead of the standard conversion helper
+
+class TruthHepMCEventConverter: public FADS::HepMCEventConverter {
+public:
+  TruthHepMCEventConverter();
+  ~TruthHepMCEventConverter();
+  void HepMC2G4(const HepMC::GenEvent* ,G4Event *, const bool) const;
+private:
+  TruthHepMCEventConverter (const TruthHepMCEventConverter&);  //declared, but not defined  	 	 
+  TruthHepMCEventConverter& operator= (const TruthHepMCEventConverter&); //declared, but not defined  	 	 
+  // helper functions here
+  bool SeparateVertices(HepMC::GenVertex* , HepMC::GenVertex*) const ;
+  G4PrimaryVertex* ConstructG4PrimaryVertex(HepMC::GenVertex*) const ;
+  G4PrimaryParticle* ConstructG4PrimaryParticle(HepMC::GenParticle*) const;
+  HepMC::GenVertex* ConstructHepMCVertex(G4PrimaryVertex*) const ;
+  void TransformHepMCParticle(HepMC::GenParticle*,G4PrimaryParticle*) const;
+  void TransformHepMCVertex(HepMC::GenVertex*,G4PrimaryVertex*) const;
+  void ModifyVertex(G4PrimaryParticle *pp, HepMC::GenVertex *v) const;
+  bool ValidHepMCVertex(HepMC::GenVertex*) const;
+  int printLev;
+  std::vector<int> *m_modded;
+};
+
+#endif
diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/selection.xml b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/selection.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3c3359d5948cdb79a3f459055eb8371551277a5a
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/selection.xml
@@ -0,0 +1,3 @@
+<lcgdict>
+  <class name="G4AtlasAlg"/>
+</lcgdict>
diff --git a/Simulation/G4Atlas/G4AtlasAlg/cmt/requirements b/Simulation/G4Atlas/G4AtlasAlg/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..b2d530fba9a0710417e884827ec1de3f2b70de0d
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/cmt/requirements
@@ -0,0 +1,35 @@
+package G4AtlasAlg
+
+author Andrea DellAcqua <dellacqu@mail.cern.ch>
+
+branches src cmt doc
+
+use AtlasPolicy      AtlasPolicy-*
+use AthenaBaseComps  AthenaBaseComps-*   Control
+use AthenaKernel     AthenaKernel-*      Control
+use GaudiInterface   GaudiInterface-*    External
+use Geant4           Geant4-*            External
+use FadsActions      FadsActions-*       Simulation/G4Sim/FADS
+use FadsKinematics   FadsKinematics-*    Simulation/G4Sim/FADS
+
+private
+use AtlasHepMC       AtlasHepMC-*        External
+use MCTruth          MCTruth-*           Simulation/G4Sim
+use FadsGeometry     FadsGeometry-*      Simulation/G4Sim/FADS
+use FadsPhysics      FadsPhysics-*       Simulation/G4Sim/FADS
+use GeneratorObjects GeneratorObjects-*  Generators
+use SimHelpers       SimHelpers-*        Simulation/G4Sim
+use StoreGate        StoreGate-*         Control
+use SGTools          SGTools-*           Control
+use GeoModelInterfaces  GeoModelInterfaces-*       DetectorDescription/GeoModel
+use EventInfo        EventInfo-*         Event 
+end_private
+
+# build a dual_use library
+apply_pattern dual_use_library files=*.cxx
+
+#private
+#apply_pattern lcgdict dict=G4AtlasAlg \
+#  headerfiles="../G4AtlasAlg/G4AtlasAlg.h" \
+#  selectionfile=selection.xml
+#end_private
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaHepMCInterface.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaHepMCInterface.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3e01a8109190e8c570d83f6ed0fbc03d611d6473
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaHepMCInterface.cxx
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "G4AtlasAlg/AthenaHepMCInterface.h"
+#include "G4AtlasAlg/TruthHepMCEventConverter.h"
+
+#include "HepMC/GenEvent.h"
+#include "FadsKinematics/FadsGeneratorT.h"
+#include "FadsKinematics/GeneratorCenter.h"
+
+#include "StoreGate/StoreGate.h"
+#include "StoreGate/DataHandle.h"
+
+// to permit access to StoreGate
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/IMessageSvc.h"
+#include "StoreGate/StoreGateSvc.h"
+
+#include "GeneratorObjects/McEventCollection.h"
+
+FADS::FadsGeneratorT<AthenaHepMCInterface> gen("AthenaHepMCInterface");
+
+AthenaHepMCInterface::AthenaHepMCInterface(std::string s):FADS::FadsGenerator(s),p_sgSvc(0),m_log(0)
+{
+	FADS::GeneratorCenter::GetGeneratorCenter()->DeleteHepMCEvent(false);
+	FADS::GeneratorCenter::GetGeneratorCenter()->SetHepMCEventConverter(
+						new TruthHepMCEventConverter);
+}
+AthenaHepMCInterface::~AthenaHepMCInterface()
+{
+	log() << MSG::DEBUG << "\b the AthenaHepMCInterface is being destroyed "<<"\n"
+          << " should you wish to use it again type: "<<"\n"
+          << " /Generator/Select AthenaHepMCInterface "<<"\n"<<endreq;
+	if (m_log) delete m_log;
+}
+void AthenaHepMCInterface::Initialize()
+{}
+void AthenaHepMCInterface::Terminate()
+{}
+HepMC::GenEvent* AthenaHepMCInterface::GenerateAnEvent()
+{
+	// Lazy initialization
+	if (!p_sgSvc){
+    	log() << MSG::DEBUG <<
+	    " standard interface to StoreGate for retrieving HepMC events"<<endreq;
+    	ISvcLocator* svcLocator = Gaudi::svcLocator(); // from Bootstrap
+	    StatusCode sc=svcLocator->service("StoreGateSvc",p_sgSvc);
+    	if (sc.isFailure())
+ 		{
+    	    log() << MSG::WARNING <<"AthenaHepMCInterface could not access StoreGate!!"<<endreq;
+	    }
+	}
+
+	const DataHandle<McEventCollection> mcCollptr;
+	StatusCode status=p_sgSvc->retrieve(mcCollptr,"GEN_EVENT");
+	if (status.isSuccess() ) 
+	{
+		if (0==mcCollptr->size()){
+			log() << MSG::WARNING << "No event in MC Event Collection!" << endreq;
+			return 0;
+		}
+
+		McEventCollection::const_iterator it = mcCollptr->begin();
+		
+		// getting only the first event here.
+		HepMC::GenEvent *p_evt = (*it);
+		return p_evt;
+
+  	} 
+	else 
+	{
+    		log() << MSG::WARNING << "no McEventCollection found."  << endreq;
+  	}
+	return 0;
+}
+
+MsgStream AthenaHepMCInterface::log()
+{
+    if (m_log) return *m_log;
+    ISvcLocator* svcLocator = Gaudi::svcLocator();
+    IMessageSvc* p_msgSvc = 0;
+    if (svcLocator->service("MessageSvc", p_msgSvc).isFailure() || !p_msgSvc)
+        std::cout << "AthenaHepMCInterface: Trouble getting the message service.  Should never happen.  Will crash now." << std::endl;
+    m_log = new MsgStream(p_msgSvc,"AthenaHepMCInterface");
+    return *m_log;
+}
+
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..56114c2853b9687b9fea6ec45e4d32b0a843fa35
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.cxx
@@ -0,0 +1,105 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/Bootstrap.h"
+
+#include "G4AtlasAlg/AthenaStackingAction.h"
+#include "MCTruth/PrimaryParticleInformation.h"
+#include "MCTruth/TrackInformation.h"
+#include "MCTruth/TrackBarcodeInfo.h"
+#include "MCTruth/EventInformation.h"
+#include <iostream>
+#include <string>
+
+#include "G4VProcess.hh"
+#include "G4Event.hh"
+#include "G4EventManager.hh"
+
+#include "G4NeutrinoE.hh"
+#include "G4NeutrinoMu.hh"
+#include "G4NeutrinoTau.hh"
+#include "G4AntiNeutrinoE.hh"
+#include "G4AntiNeutrinoMu.hh"
+#include "G4AntiNeutrinoTau.hh"
+
+#include "G4Gamma.hh"
+
+// static AthenaStackingAction stacking;
+
+AthenaStackingAction::AthenaStackingAction(): ApplicationStackingAction(), p_killAllNeutrinos(false), p_stackEnergyCut(-1){}
+
+G4ClassificationOfNewTrack AthenaStackingAction::ClassifyNewTrack(const G4Track* aTrack)
+{
+    // Neutrinos turned off at job options level
+	G4ParticleDefinition &particleType = *(aTrack->GetDefinition() );
+	if (  p_killAllNeutrinos                                               &&
+        ( &particleType == G4NeutrinoE::NeutrinoEDefinition()              ||
+          &particleType == G4AntiNeutrinoE::AntiNeutrinoEDefinition()      ||
+          &particleType == G4NeutrinoMu::NeutrinoMuDefinition()            ||
+          &particleType == G4AntiNeutrinoMu::AntiNeutrinoMuDefinition()    ||
+          &particleType == G4NeutrinoTau::NeutrinoTauDefinition()          ||
+          &particleType == G4AntiNeutrinoTau::AntiNeutrinoTauDefinition()  ) ){
+	  return fKill;
+	}
+
+    if ( &particleType == G4Gamma::Gamma() &&
+      aTrack->GetTotalEnergy() < 0.00005 ){ // Safe cut for ultra-low-energy photons
+      return fKill;
+    }
+
+
+	G4Track *inT=const_cast<G4Track*>(aTrack);
+
+	G4Event *ev=G4EventManager::GetEventManager()->GetNonconstCurrentEvent();
+	EventInformation* eventInfo __attribute__ ((unused)) =static_cast<EventInformation*>
+				    (ev->GetUserInformation());
+
+	int pID=aTrack->GetParentID();
+	if (!pID)	// this is a primary particle.
+	{
+		const G4PrimaryParticle *pp=0;
+		PrimaryParticleInformation *ppi=0;
+		
+		const G4DynamicParticle *dp=aTrack->GetDynamicParticle();
+		if (dp)  pp=(const G4PrimaryParticle *)dp->GetPrimaryParticle();
+		if (pp)
+		ppi=dynamic_cast
+			<PrimaryParticleInformation *> (pp->GetUserInformation());
+		if (ppi) {
+		        const ISF::ISFParticle* isp = ppi->GetISFParticle();
+			const HepMC::GenParticle *part=ppi->GetHepMCParticle();
+			if (part) {// OK, we got back to HepMC
+			  TrackInformation *ti=new TrackInformation(part);
+			  ti->SetRegenerationNr(0); 
+			  ti->SetISFParticle(isp);
+			  // regNr=0 and classify=Primary are default values anyway
+			  inT->SetUserInformation(ti);
+			  ti->SetClassification(Primary);
+
+			}
+			else if (ppi->GetParticleBarcode()>=0) {
+			  // PrimaryParticleInformation should at least provide a barcode
+			  TrackBarcodeInfo *bi=new TrackBarcodeInfo(ppi->GetParticleBarcode());
+			  bi->SetISFParticle(isp);
+			  inT->SetUserInformation(bi);
+			}
+		}
+	}
+	else		// secondary track: see if it must be saved
+	{			
+
+          // Time cut for particles stacking after a certain time...
+          if (  p_stackEnergyCut > 0 &&
+                &particleType == G4Gamma::Gamma() &&
+                aTrack->GetTotalEnergy() < p_stackEnergyCut ){
+	    return fKill;
+          }
+
+ 	}
+        return fUrgent;
+}
+void AthenaStackingAction::NewStage() {;}
+void AthenaStackingAction::PrepareNewEvent() {;}
+
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingAction.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingAction.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..27a7a28323261312eb43062dabed0868a673b3b9
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingAction.cxx
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "G4AtlasAlg/AthenaTrackingAction.h"
+#include "MCTruth/PrimaryParticleInformation.h"
+#include "MCTruth/TrackInformation.h"
+#include "MCTruth/EventInformation.h"
+#include "MCTruth/TruthStrategyManager.h"
+#include <iostream>
+
+#include "G4DynamicParticle.hh"
+#include "G4PrimaryParticle.hh"
+#include "G4EventManager.hh"
+#include "MCTruth/TrackHelper.h"
+#include "FadsActions/FadsTrackingAction.h"
+#include "MCTruth/AtlasTrajectory.h"
+
+// static AthenaTrackingAction ta;
+
+void AthenaTrackingAction::PreUserTrackingAction(const G4Track* inTrack)
+{	
+	static int ilevel=TruthStrategyManager::GetStrategyManager()->
+					GetSecondarySavingLevel();
+//	std::cout<<" this is AthenaTrackingAction::PreUserTrackingAction"<<std::endl;
+	G4Track* inT = const_cast<G4Track*> (inTrack);
+	TrackHelper trackHelper(inT);
+	if (trackHelper.IsPrimary() || trackHelper.IsRegisteredSecondary())
+	{
+		HepMC::GenParticle* part=const_cast<HepMC::GenParticle*> (
+					trackHelper.GetTrackInformation()->
+						GetHepMCParticle());
+		EventInformation *eventInfo=TruthStrategyManager::GetStrategyManager()->
+					GetEventInformation();
+		if (trackHelper.IsPrimary()) eventInfo->SetCurrentPrimary(part);
+		eventInfo->SetCurrentlyTraced(part);
+	}
+ 	if (trackHelper.IsPrimary() || 
+	    (trackHelper.IsRegisteredSecondary()&&ilevel>1) ||
+	    (trackHelper.IsSecondary()&&ilevel>2)) 
+ 	{		
+		G4VTrajectory *temp=new AtlasTrajectory(inTrack);
+		FADS::FadsTrackingAction::GetTrackingAction()->SetTraj(temp);		
+	}
+}
+
+
+void AthenaTrackingAction::PostUserTrackingAction(const G4Track* /*outTrack*/)
+{
+//	std::cout <<"AthenaTrackingAction::PostUserTrackingAction"<<std::endl;
+	FADS::FadsTrackingAction::GetTrackingAction()->ResetTraj();
+}
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..240b847d41dc6031c03cd76fa7d1621b25ce431d
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx
@@ -0,0 +1,237 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "G4AtlasAlg/G4AtlasAlg.h"
+
+#include "G4AtlasAlg/PreEventActionManager.h"
+#include "G4AtlasAlg/AthenaTrackingAction.h"
+#include "G4AtlasAlg/AthenaStackingAction.h"
+#include "G4AtlasAlg/G4AtlasRunManager.h"
+
+#include "GaudiKernel/AlgFactory.h"
+
+#include "FadsActions/FadsEventAction.h"
+#include "FadsActions/FadsSteppingAction.h"
+#include "FadsActions/FadsRunAction.h"
+#include "FadsActions/FadsTrackingAction.h"
+#include "FadsActions/FadsStackingAction.h"
+#include "FadsKinematics/GeneratorCenter.h"
+#include "FadsPhysics/PhysicsListCatalog.h"
+#include "FadsPhysics/PhysicsListSteering.h"
+#include "FadsGeometry/FadsDetectorConstruction.h"
+
+#include "G4TransportationManager.hh"
+#include "G4RunManagerKernel.hh"
+#include "G4EventManager.hh"
+#include "G4Navigator.hh"
+#include "G4PropagatorInField.hh"
+#include "G4TrackingManager.hh"
+#include "G4StackManager.hh"
+#include "G4UImanager.hh"
+
+#include "EventInfo/EventInfo.h" 
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+G4AtlasAlg::G4AtlasAlg(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthAlgorithm(name, pSvcLocator),
+    m_rndmGenSvc("AtDSFMTGenSvc", name)
+{
+  ATH_MSG_DEBUG(std::endl << std::endl << std::endl);
+  ATH_MSG_INFO("++++++++++++  G4AtlasAlg created  ++++++++++++" << std::endl << std::endl);
+  declareProperty( "Dll", libList="");
+  declareProperty( "Physics", physList="");
+  declareProperty( "Generator", generator="");
+  declareProperty( "FieldMap", fieldMap="");
+  declareProperty( "RandomGenerator", rndmGen="athena");
+  declareProperty( "KillAllNeutrinos",m_KillAllNeutrinos=true);
+  declareProperty( "KillLowEPhotons",m_KillLowEPhotons=-1.);
+  declareProperty( "ReleaseGeoModel",m_releaseGeoModel=true);
+  declareProperty( "IncludeParentsInG4Event",m_IncludeParentsInG4Event=false);
+  declareProperty( "KillAbortedEvents", m_killAbortedEvents=true); 
+  declareProperty( "FlagAbortedEvents", m_flagAbortedEvents=false); 
+
+  // Service instantiation
+  declareProperty("AtRndmGenSvc", m_rndmGenSvc);
+
+  p_runMgr = G4AtlasRunManager::GetG4AtlasRunManager();
+  // if (m_noGeomInit) p_runMgr->NoGeomInit();
+
+  G4VUserPhysicsList *thePL=FADS::PhysicsListCatalog::GetInstance()->GetMainPhysicsList();
+  p_runMgr->SetPhysicsList(thePL);
+  p_runMgr->SetUserInitialization(thePL);
+  p_runMgr->SetUserInitialization(new FADS::FadsDetectorConstruction);
+  trackingAction =new AthenaTrackingAction;
+  stackingAction =new AthenaStackingAction;
+  p_runMgr->SetUserAction(FADS::FadsRunAction::GetRunAction());
+  p_runMgr->SetUserAction(FADS::FadsEventAction::GetEventAction());
+  p_runMgr->SetUserAction(FADS::FadsSteppingAction::GetSteppingAction());
+  p_runMgr->SetUserAction(FADS::FadsTrackingAction::GetTrackingAction());
+  p_runMgr->SetUserAction(FADS::FadsStackingAction::GetStackingAction());
+
+  // Verbosities
+  m_verbosities.clear();
+  declareProperty( "Verbosities" , m_verbosities );
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode G4AtlasAlg::initialize()
+{
+  G4UImanager *ui = G4UImanager::GetUIpointer();
+
+  if (!libList.empty())
+    {
+      ATH_MSG_INFO("G4AtlasAlg specific libraries requested ") ;
+      std::string temp="/load "+libList;
+      ui->ApplyCommand(temp);
+    }
+  if (!physList.empty())
+    {
+      ATH_MSG_INFO("requesting a specific physics list "<< physList) ;
+      std::string temp="/Physics/GetPhysicsList "+physList;
+      ui->ApplyCommand(temp);
+    }
+  FADS::GeneratorCenter * gc = FADS::GeneratorCenter::GetGeneratorCenter();
+  gc->SetIncludeParentsInG4Event( m_IncludeParentsInG4Event );
+  if (!generator.empty())
+    {
+      ATH_MSG_INFO("requesting a specific generator "<< generator) ;
+      gc->SelectGenerator(generator);
+    } else {
+    // make sure that there is a default generator (i.e. HepMC interface)
+    gc->SelectGenerator("AthenaHepMCInterface");
+  }
+  if (!fieldMap.empty())
+    {
+      ATH_MSG_INFO("requesting a specific field map "<< fieldMap) ;
+      ATH_MSG_INFO("the field is initialized straight away") ;
+      std::string temp="/MagneticField/Select "+fieldMap;
+      ui->ApplyCommand(temp);
+      ui->ApplyCommand("/MagneticField/Initialize");
+    }
+
+  stackingAction->KillAllNeutrinos(m_KillAllNeutrinos);
+  stackingAction->KillLowEPhotons(m_KillLowEPhotons);
+  p_runMgr->SetReleaseGeo( m_releaseGeoModel );
+  p_runMgr->SetLogLevel( int(msg().level()) ); // Synch log levels
+
+  ATH_MSG_DEBUG(std::endl << std::endl << std::endl);
+  ATH_MSG_INFO("++++++++++++  G4AtlasAlg initialized  ++++++++++++" << std::endl << std::endl);
+
+  ATH_MSG_INFO("Setting checkmode to true");
+  ui->ApplyCommand("/geometry/navigator/check_mode true");
+
+  if (rndmGen=="athena" || rndmGen=="ranecu")	{
+    // Set the random number generator to AtRndmGen
+    if (m_rndmGenSvc.retrieve().isFailure()) {
+      ATH_MSG_ERROR("Could not initialize ATLAS Random Generator Service");
+      return StatusCode::FAILURE;
+    }
+    CLHEP::HepRandomEngine* engine = m_rndmGenSvc->GetEngine("AtlasG4");
+    CLHEP::HepRandom::setTheEngine(engine);
+    ATH_MSG_INFO("Random nr. generator is set to Athena");
+  }
+  else if (rndmGen=="geant4" || rndmGen.empty()) {
+    ATH_MSG_INFO("Random nr. generator is set to Geant4");
+  }
+
+  // G4 init moved to PyG4AtlasAlg / G4AtlasEngine
+  /// @todo Reinstate or delete?! This can't actually be called from the Py algs
+  //ATH_MSG_INFO("Firing initialization of G4!!!");
+  //initializeG4();
+
+  return StatusCode::SUCCESS;
+
+}
+
+void G4AtlasAlg::initializeG4()
+{
+
+  if (m_verbosities.size()>0){
+    G4TransportationManager *tm = G4TransportationManager::GetTransportationManager();
+    G4RunManagerKernel *rmk = G4RunManagerKernel::GetRunManagerKernel();
+    G4EventManager *em = G4EventManager::GetEventManager();
+
+    if (m_verbosities.find("Navigator") != m_verbosities.end()){
+      tm->GetNavigatorForTracking()->SetVerboseLevel( atof(m_verbosities.find("Navigator")->second.data()) );
+    }
+    if (m_verbosities.find("Propagator") != m_verbosities.end()){
+      tm->GetPropagatorInField()->SetVerboseLevel( atof(m_verbosities.find("Propagator")->second.data()) );
+    }
+    if (m_verbosities.find("Tracking") != m_verbosities.end()){
+      rmk->GetTrackingManager()->SetVerboseLevel( atof(m_verbosities.find("Tracking")->second.data()) );
+    }
+    if (m_verbosities.find("Stepping") != m_verbosities.end()){
+      rmk->GetTrackingManager()->GetSteppingManager()->SetVerboseLevel( atof(m_verbosities.find("Stepping")->second.data()) );
+    }
+    if (m_verbosities.find("Stacking") != m_verbosities.end()){
+      rmk->GetStackManager()->SetVerboseLevel( atof(m_verbosities.find("Stacking")->second.data()) );
+    }
+    if (m_verbosities.find("Event") != m_verbosities.end()){
+      em->SetVerboseLevel( atof(m_verbosities.find("Event")->second.data()) );
+    }
+  } // End of the setting of verbosities
+
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode G4AtlasAlg::finalize() {
+  ATH_MSG_DEBUG(std::endl<<std::endl<<std::endl);
+  ATH_MSG_INFO("++++++++++++  G4AtlasAlg finalized  ++++++++++++" <<std::endl<<std::endl);
+
+  ATH_MSG_DEBUG("\t terminating the current G4 run");
+
+  p_runMgr->RunTermination();
+
+  return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode G4AtlasAlg::execute()
+{
+  static int n_Event=0;
+  static PreEventActionManager *preEvent=PreEventActionManager::
+    GetPreEventActionManager();
+  ATH_MSG_DEBUG(std::endl<<std::endl<<std::endl);
+  ATH_MSG_INFO("++++++++++++  G4AtlasAlg execute  ++++++++++++" <<std::endl<<std::endl);
+
+  n_Event += 1;
+
+  if (n_Event<=10 || (n_Event%100) == 0) {
+    ATH_MSG_ALWAYS("G4AtlasAlg: Event num. "  << n_Event << " start processing");
+  }
+
+  preEvent->Execute();
+
+  ATH_MSG_DEBUG("Calling SimulateG4Event");
+
+  bool abort = p_runMgr->SimulateFADSEvent();
+
+  if (abort) {
+    ATH_MSG_WARNING("Event was aborted !! ");
+    ATH_MSG_WARNING("Simulation will now go on to the next event ");
+    if (m_killAbortedEvents){ 
+      ATH_MSG_WARNING("setFilterPassed is now False");
+      setFilterPassed(false);
+    }
+    if (m_flagAbortedEvents){ 
+      const DataHandle<EventInfo> eic = 0; 
+      if ( sgSvc()->retrieve( eic ).isFailure() || !eic ){ 
+	ATH_MSG_WARNING( "Failed to retrieve EventInfo" ); 
+      } else { 
+	// Gotta cast away the const... sadface 
+	EventInfo *ei = const_cast< EventInfo * > (&(*eic)); 
+	ei->setErrorState(EventInfo::Core,EventInfo::Error); 
+	ATH_MSG_WARNING( "Set error state in event info!" ); 
+      } 
+    } 
+  }
+
+  return StatusCode::SUCCESS;
+}
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasRunManager.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasRunManager.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5a4534ad0463a9f5cfa44711a7d21ab7067c21f5
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasRunManager.cxx
@@ -0,0 +1,227 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "G4AtlasAlg/G4AtlasRunManager.h"
+
+#include "G4StateManager.hh"
+#include "G4UImanager.hh"
+#include "G4Timer.hh"
+#include "G4UserRunAction.hh"
+#include "G4Run.hh"
+
+#include "G4ios.hh"
+
+#include "G4Event.hh"
+
+#include "G4VUserDetectorConstruction.hh"
+#include "G4VUserPhysicsList.hh"
+
+#include "StoreGate/StoreGateSvc.h"
+#include "GaudiKernel/System.h"
+#include "GaudiKernel/IMessageSvc.h"
+
+#include "FadsKinematics/GeneratorCenter.h"
+#include "FadsPhysics/PhysicsListCatalog.h"
+#include "FadsPhysics/DummyPhysicsList.h"
+#include "G4VUserPrimaryGeneratorAction.hh"
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "GeoModelInterfaces/IGeoModelSvc.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/IMessageSvc.h"
+
+#include "G4LogicalVolumeStore.hh"
+#include "G4RegionStore.hh"
+#include "G4ProductionCutsTable.hh"
+#include "G4GeometryManager.hh"
+
+
+G4AtlasRunManager::G4AtlasRunManager()
+  : G4RunManager(),
+    m_pl(NULL), 
+    m_sgSvc(NULL), 
+    m_releaseGeo(false),
+    m_log(0)
+{  }
+
+
+G4AtlasRunManager* G4AtlasRunManager::GetG4AtlasRunManager() {
+	static G4AtlasRunManager* thisManager=0;
+	if (!thisManager) thisManager=new G4AtlasRunManager;
+	return thisManager;
+}
+
+
+void G4AtlasRunManager::InitializeGeometry() {
+  G4LogicalVolumeStore *lvs = G4LogicalVolumeStore::GetInstance();
+  for (unsigned int i=0;i<lvs->size();++i){
+    if ( (*lvs)[i]->GetName() == "Muon::MuonSys" ){
+      (*lvs)[i]->SetSmartless( 0.1 );
+      log() << MSG::INFO << "Set smartlessness for Muon::MuonSys to 0.1" << endreq;
+    } else if ( (*lvs)[i]->GetName() == "LArMgr::LAr::EMB::STAC") {
+      (*lvs)[i]->SetSmartless( 0.5 );
+      log() << MSG::INFO << "Set smartlessness for LArMgr::LAr::EMB::STAC to 0.5" << endreq;
+    }
+  }
+
+  if (userDetector) {
+ 	G4RunManager::InitializeGeometry();
+  } else {
+    log() << MSG::WARNING <<" User Detector not set!!! Geometry NOT initialized!!!"<<endreq;
+  }
+}
+
+
+void G4AtlasRunManager::EndEvent() {
+  log() << MSG::DEBUG << "G4AtlasRunManager::EndEvent" << endreq;
+}
+
+
+void G4AtlasRunManager::InitializePhysics() {
+  kernel->InitializePhysics();
+  physicsInitialized = true;
+}
+
+
+G4Event* G4AtlasRunManager::GenerateEvent(G4int i_event)
+{
+  static FADS::GeneratorCenter* generatorCenter=FADS::GeneratorCenter::GetGeneratorCenter();
+
+  SetCurrentG4Event(i_event);
+
+  generatorCenter->GenerateAnEvent(currentEvent);
+
+  return currentEvent;
+}
+
+
+bool G4AtlasRunManager::SimulateFADSEvent()
+{
+
+//	std::cout<<" SimulateFADSEvent : start simulating one event "<<std::endl;
+
+	G4StateManager* stateManager = G4StateManager::GetStateManager();
+	stateManager->SetNewState(G4State_GeomClosed);
+//    	stateManager->SetNewState(G4State_EventProc);
+
+    // Release GeoModel Geometry if necessary
+    if (m_releaseGeo){
+        ISvcLocator* svcLocator = Gaudi::svcLocator(); // from Bootstrap
+        StoreGateSvc* m_detStore;
+        StatusCode sc=svcLocator->service("DetectorStore",m_detStore);
+        if (sc.isFailure()){
+            log()<<MSG::ERROR<<"G4AtlasRunManager could not access the detector store - PANIC!!!!"<<endreq;
+            abort();
+        }
+
+        IGeoModelSvc* geoModel = 0;
+        StatusCode status=svcLocator->service("GeoModelSvc",geoModel);
+        if(status.isFailure()) {
+            log()<<MSG::WARNING<< " ----> Unable to retrieve GeoModelSvc" << endreq;
+        } else {
+            status = geoModel->clear();
+            if(status.isFailure()) {
+                log()<<MSG::WARNING<< " ----> GeoModelSvc::clear() failed" << endreq;
+            } else {
+                log()<<MSG::INFO<< " ----> GeoModelSvc::clear() succeeded " << endreq;
+            }
+        }
+        m_releaseGeo=false; // Don't do that again...
+    }
+
+
+    currentEvent = GenerateEvent(1);
+	if (currentEvent->IsAborted())
+	{
+		log()<<MSG::WARNING<<"G4AtlasRunManager::SimulateFADSEvent: "<<
+		           "Event Aborted at Generator level"<<endreq;
+	    currentEvent=0;
+		return true;
+	}
+
+    eventManager->ProcessOneEvent(currentEvent);
+	if (currentEvent->IsAborted())
+	{
+		log()<<MSG::WARNING<<"G4AtlasRunManager::SimulateFADSEvent: "<<
+		           "Event Aborted at Detector Simulation level"<<endreq;
+		currentEvent=0;
+		return true;
+	}
+
+    AnalyzeEvent(currentEvent);
+	if (currentEvent->IsAborted())
+	{
+		log()<<MSG::WARNING<<"G4AtlasRunManager::SimulateFADSEvent: "<<
+		           "Event Aborted at Analysis level"<<endreq;
+		currentEvent=0;
+		return true;
+	}
+
+//    	stateManager->SetNewState(G4State_GeomClosed);
+   	StackPreviousEvent(currentEvent);
+    bool abort=currentEvent->IsAborted();
+   	currentEvent = 0;
+	//	std::cout<<" SimulateFADSEvent : done simulating one event "<<std::endl;
+	return abort;
+}
+
+
+void  G4AtlasRunManager::RunTermination()
+{
+  // std::cout<<" this is G4AtlasRunManager::RunTermination() "<<std::endl;
+  for(size_t itr=0;itr<previousEvents->size();itr++)
+  { delete (*previousEvents)[itr]; }
+  previousEvents->clear();
+
+  if(userRunAction) userRunAction->EndOfRunAction(currentRun);
+
+  delete currentRun;
+  currentRun = 0;
+  runIDCounter++;
+
+  std::cout << "Changing the state..." << std::endl;
+  G4StateManager* stateManager = G4StateManager::GetStateManager();
+  stateManager->SetNewState(G4State_Idle);
+
+  std::cout << "Opening the geometry back up" << std::endl;
+  G4GeometryManager::GetInstance()->OpenGeometry();
+
+  std::cout << "Terminating the run...  State is " << stateManager->GetStateString( stateManager->GetCurrentState() ) << std::endl;
+  kernel->RunTermination();
+  std::cout << "All done..." << std::endl;
+
+  // std::cout<<" setting all pointers in G4AtlasRunManager to 0"<<std::endl;
+  userRunAction=0;
+  userEventAction=0;
+  userSteppingAction=0;
+  userStackingAction=0;
+  userTrackingAction=0;
+  // physicsList=0;
+  userDetector=0;
+  userPrimaryGeneratorAction=0;
+
+  // std::cout<<" this is G4AtlasRunManager::RunTermination(): done "<<std::endl;
+}
+
+void G4AtlasRunManager::SetCurrentG4Event(int iEvent)
+{
+	currentEvent=new G4Event(iEvent);
+}
+
+MsgStream G4AtlasRunManager::log()
+{
+    if (m_log) return *m_log;
+    ISvcLocator* svcLocator = Gaudi::svcLocator();
+    IMessageSvc* p_msgSvc = 0;
+    if (svcLocator->service("MessageSvc", p_msgSvc).isFailure() || !p_msgSvc)
+        std::cout << "G4AtlasRunManager: Trouble getting the message service.  Should never happen.  Will crash now." << std::endl;
+    m_log = new MsgStream(p_msgSvc,"G4AtlasRunManager");
+    return *m_log;
+}
+
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/PreEventAction.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/PreEventAction.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2348c0c77bbde435d12565d8279e9754d7a533ef
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/PreEventAction.cxx
@@ -0,0 +1,16 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "G4AtlasAlg/PreEventAction.h"
+#include "G4AtlasAlg/PreEventActionManager.h"
+
+PreEventAction::PreEventAction(std::string n):name(n)
+{
+	PreEventActionManager::GetPreEventActionManager()->
+				RegisterAction(this);
+}
+std::string PreEventAction::GetName()
+{
+	return name;
+}
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/PreEventActionManager.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/PreEventActionManager.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..589d36f30de9c857fa83ff17a1727498ced700d1
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/PreEventActionManager.cxx
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "G4AtlasAlg/PreEventActionManager.h"
+#include "G4AtlasAlg/PreEventAction.h"
+#include <iostream>
+
+PreEventActionManager* PreEventActionManager::thePointer=0;
+
+PreEventActionManager::PreEventActionManager()
+{
+}
+
+PreEventActionManager* PreEventActionManager::GetPreEventActionManager()
+{
+	if (!thePointer) thePointer=new PreEventActionManager();
+	return thePointer;
+}
+
+void PreEventActionManager::Execute()
+{
+	preEvActionMap::const_iterator it;
+	for (it=theMap.begin();it!=theMap.end();it++)
+		(*it).second->Execute();
+}
+
+void PreEventActionManager::RegisterAction(PreEventAction *act)
+{
+	std::string n=act->GetName();
+	if (theMap.find(n)!=theMap.end())
+		std::cout<<"Attempt of re-defining an existing pre-event action"
+			<<std::endl;
+	else
+		theMap[n]=act;
+}
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/TruthHepMCEventConverter.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/TruthHepMCEventConverter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..32f2f5afc050f4fe42f0d28777de727267d52c00
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/TruthHepMCEventConverter.cxx
@@ -0,0 +1,468 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "G4AtlasAlg/TruthHepMCEventConverter.h"
+#include "G4Event.hh"
+
+#include "G4PrimaryParticle.hh"
+#include "G4PrimaryVertex.hh"
+#include "G4LorentzVector.hh"
+#include "G4Geantino.hh"
+#include "G4ChargedGeantino.hh"
+#include "G4EventManager.hh"
+#include "G4ParticleTable.hh"
+
+#include "FadsKinematics/VertexManipulator.h"
+#include "FadsKinematics/ParticleManipulator.h"
+#include "FadsKinematics/G4EventAnalyzer.h"
+#include "FadsKinematics/GeneratorCenter.h"
+
+#include "MCTruth/EventInformation.h"
+#include "MCTruth/TruthEvent.h"
+#include "MCTruth/PrimaryParticleInformation.h"
+
+#include "SimHelpers/ServiceAccessor.h"
+
+#include "GeneratorObjects/McEventCollection.h"
+
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "SGTools/BuiltinsClids.h"
+
+#include <map>
+
+typedef HepMC::GenEvent Hevent;
+typedef HepMC::GenVertex Hvertex;
+typedef HepMC::GenParticle Hparticle;
+typedef HepMC::GenEvent::vertex_const_iterator Hv_iterator;
+typedef HepMC::GenVertex::particle_iterator Hp_iterator;
+// A note on unit conventions 26/10/2012
+//
+// HepMC objects store spatial coordinates in millimetres and time
+// coordinates are stored as c_light*t, also recorded in mm.
+//
+// G4PrimaryVertex objects store spatial coordinates in millimetres
+// and time coordinates are stored in ns.
+//
+// Therefore it is necessary to divide the time component by
+// CLHEP::c_light when going from HepMC to Geant4 objects and multiply
+// by CLHEP::c_light when going from Geant4 to HepMC objects.
+//
+// TODO: In the future we should include full conversion of units from
+// HepMC to G4 (CLHEP) i.e. G4_pos = HepMC_pos / HepMC::mm * CLHEP::mm
+// and G4_time = HepMC_time / HepMC::mm * CLHEP::mm / CLHEP::c_light.
+// Need to determine how best to get the HepMC::mm factor. Similary
+// for energies and momenta.
+
+
+class IsFinalState {
+// borrowed from one of the HepMC examples
+// this predicate returns true if the input has no decay vertex
+public:
+    bool operator()( const HepMC::GenParticle* p ) {
+        if ( !p->end_vertex() && p->status()==1 ) return 1;
+        return 0;
+    }
+};
+
+TruthHepMCEventConverter::TruthHepMCEventConverter()
+{
+	printLev=0;
+	m_modded = new std::vector<int>(10);
+}
+
+TruthHepMCEventConverter::~TruthHepMCEventConverter()
+{
+  if (m_modded) delete m_modded;
+}
+
+bool TruthHepMCEventConverter::ValidHepMCVertex(HepMC::GenVertex *testVertex) const
+{
+  bool vertexOK(true);
+  double coordinate(testVertex->position().x());
+  vertexOK&=!(std::isnan(coordinate) || std::isinf(coordinate));
+  coordinate = testVertex->position().y();
+  vertexOK&=!(std::isnan(coordinate) || std::isinf(coordinate));
+  coordinate = testVertex->position().z();
+  vertexOK&=!(std::isnan(coordinate) || std::isinf(coordinate));
+  coordinate = testVertex->position().t();
+  vertexOK&=!(std::isnan(coordinate) || std::isinf(coordinate));
+  return vertexOK;
+}
+
+bool TruthHepMCEventConverter::SeparateVertices(HepMC::GenVertex *v1,HepMC::GenVertex *v2) const
+{
+        const double distMin=0.01*CLHEP::mm;
+	G4LorentzVector vv1(v1->position().x(),v1->position().y(),v1->position().z(),v1->position().t());
+	G4LorentzVector vv2(v2->position().x(),v2->position().y(),v2->position().z(),v2->position().t());
+	return ((sqrt(pow(vv1.x()-vv2.x(),2)+pow(vv1.y()-vv2.y(),2)+
+	         pow(vv1.z()-vv2.z(),2))>distMin) || (vv1.t()!=vv2.t()));
+}
+
+G4PrimaryVertex* TruthHepMCEventConverter::ConstructG4PrimaryVertex(HepMC::GenVertex *v) const
+{
+  if(!ValidHepMCVertex(v))
+    {
+      std::cout << "TruthHepMCEventConverter FATAL ConstructG4PrimaryVertex: Received invalid GenVertex object:" << *v
+		<< " - Job will die now..." << std::endl;
+      throw;
+    }
+  G4LorentzVector vv(v->position().x(),v->position().y(),v->position().z(),v->position().t());
+  G4PrimaryVertex *vert= new G4PrimaryVertex (vv.x()*CLHEP::mm,
+					      vv.y()*CLHEP::mm,
+					      vv.z()*CLHEP::mm,
+					      vv.t()*CLHEP::mm/CLHEP::c_light);
+  return vert;
+}
+
+void TruthHepMCEventConverter::TransformHepMCParticle(HepMC::GenParticle *hp, G4PrimaryParticle *gp) const
+{
+  hp->set_pdg_id(gp->GetPDGcode());  //this should not change at all, right?
+  CLHEP::Hep3Vector gpv=gp->GetMomentum();
+  const double pmass=gp->GetMass();
+  const double pe = sqrt(gpv.mag2() + pmass*pmass);  // this does only change for boosts, etc.
+  hp->set_momentum(CLHEP::HepLorentzVector(gpv.x(),gpv.y(),gpv.z(),pe));
+}
+
+void TruthHepMCEventConverter::TransformHepMCVertex(HepMC::GenVertex *hv,G4PrimaryVertex *gv) const
+{
+	CLHEP::HepLorentzVector hvlv(hv->position().x(),hv->position().y(),hv->position().z(),hv->position().t());
+	if (hvlv.x()!=gv->GetX0()) hvlv.setX(gv->GetX0());
+	if (hvlv.y()!=gv->GetY0()) hvlv.setY(gv->GetY0());
+	if (hvlv.z()!=gv->GetZ0()) hvlv.setZ(gv->GetZ0());
+	const double cT0(gv->GetT0()*CLHEP::c_light);
+	if (hvlv.t()!=cT0) hvlv.setT(cT0);
+	hv->set_position(hvlv);
+}
+
+G4PrimaryParticle* TruthHepMCEventConverter::ConstructG4PrimaryParticle(HepMC::GenParticle *hp) const
+{
+	// check if stable
+	if(hp->status()!=1) return 0;
+
+	int pdgcode=hp->pdg_id();
+        CLHEP::HepLorentzVector lp(hp->momentum().px(),hp->momentum().py(),hp->momentum().pz(),hp->momentum().e());
+	G4ThreeVector& p=lp;
+
+	if (printLev>1)
+	{
+		std::cout << "GenParticle being converted :"<<std::endl;
+		std::cout << "momentum components (in MeV): "<<p<<std::endl;
+		std::cout << "Energy (in MeV): "<<lp.e()<<std::endl;
+		std::cout << "Mass (in MeV): "<<lp.m()<<std::endl;
+	}
+
+        G4PrimaryParticle *part;
+        if (pdgcode==999){
+	  G4ParticleDefinition *pdef=
+	    G4Geantino::GeantinoDefinition();
+	  part=new G4PrimaryParticle(pdef,p.x(),p.y(),p.z());
+
+        } else if (pdgcode==998){
+	  G4ParticleDefinition *pdef=
+	    G4ChargedGeantino::ChargedGeantinoDefinition();
+	  part=new G4PrimaryParticle(pdef,p.x(),p.y(),p.z());
+	} else {
+	  part= new G4PrimaryParticle(pdgcode,
+				      p.x(),
+				      p.y(),
+				      p.z());
+	}
+	return part;
+
+}
+
+HepMC::GenVertex* TruthHepMCEventConverter::ConstructHepMCVertex(G4PrimaryVertex *v) const
+{
+	G4ThreeVector pos=v->GetPosition();
+	double t0=v->GetT0();
+	G4LorentzVector lv(pos.x(),pos.y(),pos.z(),t0*CLHEP::c_light)	;
+	HepMC::GenVertex *hv=new HepMC::GenVertex(lv);
+	return hv;
+}
+
+struct CompositeVertex {
+	HepMC::GenVertex* primary;
+	std::vector<HepMC::GenVertex*> secondaries;
+};
+
+typedef std::vector<CompositeVertex> vertexVector;
+
+void TruthHepMCEventConverter::HepMC2G4(const HepMC::GenEvent* evt,G4Event * anEvent, const bool IncludeParentsInG4Event=false) const
+{
+
+  m_modded->clear();
+  int n_vertices=0;
+  int n_particles=0;
+
+  std::vector<G4PrimaryVertex* > vertexVector;
+  std::vector<G4PrimaryParticle* > particleVector;
+
+  if (printLev>3) std::cout<<" This is the Truth HepMC event converter "<<std::endl;
+
+  FADS::GeneratorCenter *gc=FADS::GeneratorCenter::GetGeneratorCenter();
+
+  FADS::vtxModifiers::const_iterator vit;
+  for (vit=gc->BeginVertexManipulator();vit!=gc->EndVertexManipulator();vit++)
+	if ((*vit).second->IsOn()) (*vit).second->EventInitialization();
+
+  FADS::particleModifiers::const_iterator pit;
+  for (pit=gc->BeginParticleManipulator();pit!=gc->EndParticleManipulator();pit++)
+	if ((*pit).second->IsOn()) (*pit).second->EventInitialization();
+
+  FADS::eventAnalyzers::const_iterator eit;
+  for (eit=gc->BeginEventAnalyzer();eit!=gc->EndEventAnalyzer();eit++)
+	if ((*eit).second->IsOn()) (*eit).second->EventInitialization();
+
+  if (printLev>=3) std::cout<<" creating the Truth event "<<std::endl;
+  HepMC::GenEvent* newEvt=new HepMC::GenEvent(*evt);
+
+  StoreGateSvc* storeGate=0;
+  ISvcLocator* svcLocator = Gaudi::svcLocator();
+  StatusCode st=svcLocator->service("StoreGateSvc", storeGate);
+  if (st.isFailure())
+     std::cout<<" storeGateSvc(); could not access StoreGateSvc"<<std::endl;
+   // Grab an instance of the particle table
+   G4ParticleTable *partTable = G4ParticleTable::GetParticleTable();
+   // If we failed, yell
+   if (partTable==0)
+     std::cout << "Could not find a particle table!" << std::endl;
+
+  // store the time in SG
+  double vtxTime = 0;
+  std::vector<HepMC::GenParticle*> incoming; incoming.clear();
+  for (HepMC::GenEvent::particle_iterator p = newEvt->particles_begin(); p != newEvt->particles_end(); ++p){
+    if ( ((*p)->pdg_id() >= 2212) && (!(*p)->production_vertex())) incoming.push_back( *p );
+    if (incoming.size() > 1) break;
+  }
+  if (incoming.size() == 2 &&
+      newEvt->vertices_size() != 0){
+    vtxTime = (*(newEvt->vertices_begin()))->position().z()/CLHEP::c_light;
+
+    // sign issue
+    if (incoming[0]->momentum().z() + incoming[1]->momentum().z() < 0) vtxTime = -vtxTime;
+  }
+  double *p_vtxTime = new double(vtxTime);
+  st=storeGate->record( p_vtxTime, "PrimarySimEventTime" );
+  if (st.isFailure())
+         std::cout << "TruthHepMCEventConverter: could not record primary vertex time to storeGate!"<<std::endl;
+
+// loop on the vertices
+// only those which have stable particles will be translated into G4PrimaryVertex
+// vertices will be displaced if their final position differs from the original
+
+//  std::cout<<" primary vertex being processed "<<std::endl<<*(*(newEvt->vertices_begin()))<<std::endl;
+//  std::cout<<" primary vertex time set at: "<<vtxInfo->GetPrimaryVertexTime()<<"ns"<<std::endl;
+  for ( Hv_iterator v = newEvt->vertices_begin();v != newEvt->vertices_end(); ++v )
+  {
+    if (printLev>4) std::cout<<" new vertex being processed "<<std::endl<<
+	*(*v)<<std::endl;
+
+    // Check if we've already modified this vertex
+    bool IsUsed=false;
+    for (unsigned int i=0;i<m_modded->size() && IncludeParentsInG4Event;i++){
+      if ( (*m_modded)[i] == (*v)->barcode() ){
+        IsUsed=true;
+        break;
+      }
+    }
+    if (IsUsed){
+      if (printLev>3) std::cout<< "Cutting a vertex because it's been used." << std::endl;
+      continue;
+    }
+
+    int nStableParticles=0;
+    IsFinalState isStable;
+
+    // create a G4PrimaryVertex - destroyed afterwards if not to be kept
+    //
+    G4PrimaryVertex *vert=ConstructG4PrimaryVertex((*v));
+    G4ThreeVector vtxPos1=vert->GetPosition();
+    FADS::vtxModifiers::const_iterator vit;
+    bool vGood=true;
+    for (vit=gc->BeginVertexManipulator();vit!=gc->EndVertexManipulator();++vit)
+    {
+      if ((*vit).second->IsOn())
+      vGood=vGood&&(*vit).second->EditVertex(vert);
+      if (!vGood) break;
+    }
+
+    for (vit=gc->BeginVertexManipulator();vit!=gc->EndVertexManipulator();++vit)
+    {
+      if ((*vit).second->GetName()=="VertexRangeChecker" && (*vit).second->IsOn()){
+        vGood=vGood&&(*vit).second->EditVertex(vert);
+        break;
+      }
+    }
+
+    if (!vGood)
+    {
+      // the vertex must be discarded
+      delete vert;
+    }
+
+
+    if (vGood)
+    {
+      TransformHepMCVertex((*v),vert);
+
+      std::map< int , HepMC::GenParticle*, std::less<int> > pMap;
+      std::map< int , HepMC::GenParticle*, std::less<int> >::const_iterator iit;
+
+      for (Hp_iterator it=(*v)->particles_begin(HepMC::children);
+		  it!=(*v)->particles_end(HepMC::children);++it)
+      {
+        int bc=(*it)->barcode();
+        pMap[bc]=(*it);
+      }
+
+      for (iit=pMap.begin();iit!=pMap.end();iit++)
+      {
+        // If it is stable or it is known
+        bool IsKnown = partTable &&
+                       partTable->FindParticle( ((*iit).second)->pdg_id() );
+        if (isStable((*iit).second) || (IsKnown && IncludeParentsInG4Event))
+        {
+          G4PrimaryParticle *part =ConstructG4PrimaryParticle((*iit).second);
+          if (0==part) continue;
+
+          bool pGood=true;
+          FADS::particleModifiers::const_iterator jt;
+
+          for (jt=gc->BeginParticleManipulator();jt!=gc->EndParticleManipulator();
+			++jt)
+          {
+            if ((*jt).second->IsOn())
+            pGood=pGood&&(*jt).second->EditParticle(part);
+            if (!pGood) break;
+          }
+          if (pGood)
+          {
+            if (printLev>3) std::cout<<" particle accepted "<<std::endl;
+            TransformHepMCParticle((*iit).second, part);
+            nStableParticles++;
+            PrimaryParticleInformation* ppi=new PrimaryParticleInformation;
+
+            ppi->SetParticle((*iit).second);
+            ppi->SetRegenerationNr(0);
+            part->SetUserInformation(ppi);
+            vert->SetPrimary(part);
+            particleVector.push_back(part);
+
+            n_particles++;
+            if (IncludeParentsInG4Event &&
+                IsKnown &&
+                ( (*iit).second )->end_vertex() ){
+               ModifyVertex( &(*part), ((*iit).second)->end_vertex() );
+            }
+            if ( !((*iit).second)->end_vertex() && ((*iit).second)->status() != 1){
+              if (printLev>2)
+                std::cout << "Used a known(" << IsKnown << ") part with EV(" << ((*iit).second)->end_vertex()
+                          << ") and status code " << ((*iit).second)->status() << std::endl;
+            }
+          }
+		  else {
+            delete part;
+          }
+        }
+      }
+      if (nStableParticles){
+        n_vertices++;
+        anEvent->AddPrimaryVertex(vert);
+        vertexVector.push_back(vert);
+      } else {
+        delete vert;
+      }
+    }
+  }
+  
+  EventInformation *eventInfo=new EventInformation;
+  eventInfo->SetNrOfPrimaryParticles(n_particles);
+  eventInfo->SetNrOfPrimaryVertices(n_vertices);
+  eventInfo->SetHepMCEvent(newEvt);
+  anEvent->SetUserInformation(eventInfo);
+
+// allow for event-by-event particle-level analysis
+  for (eit=gc->BeginEventAnalyzer();eit!=gc->EndEventAnalyzer();eit++)
+	if ((*eit).second->IsOn()) (*eit).second->EventAnalysis(vertexVector,particleVector);
+
+  // publish the truth to SG
+  if (printLev>=3) std::cout<<" recording the truth event to SG "<<std::endl;
+
+  std::string   key = "TruthEvent";
+  McEventCollection* mcEvtColl;
+
+  if (storeGate->contains<McEventCollection>(key))
+  {
+        StatusCode status = storeGate->retrieve(mcEvtColl,key);
+		if (status.isSuccess())
+		std::cout << "found an McEventCollection in store" << std::endl;
+  }
+  else
+  {
+	// McCollection doesn't exist. Create it and fill it with the truth
+	mcEvtColl = new McEventCollection;
+		mcEvtColl->push_back(newEvt);
+	StatusCode status=storeGate->record( mcEvtColl, key );
+		if (status.isFailure())
+			std::cout << "TruthHepMCEventConverter: could not record MC evt collection to storeGate!"<<std::endl;
+  }
+
+}
+
+// Propagating a change using a primary particle and its decay vertex
+void TruthHepMCEventConverter::ModifyVertex(G4PrimaryParticle *pp, HepMC::GenVertex *v) const
+{
+  FADS::GeneratorCenter *gc= FADS::GeneratorCenter::GetGeneratorCenter();
+
+  // One incoming particle
+  G4LorentzVector lv(v->position().x(),
+                     v->position().y(),
+                     v->position().z(),
+                     v->position().t());
+  if ( v->particles_in_size() < 1 ){
+    // Bark
+    std::cout << "ERROR: No particles going into a decay vertex!" << std::endl;
+    return;
+  }
+
+   G4LorentzVector lv0((*(v->particles_begin(HepMC::parents)))->production_vertex()->position().x(),
+                       (*(v->particles_begin(HepMC::parents)))->production_vertex()->position().y(),
+                       (*(v->particles_begin(HepMC::parents)))->production_vertex()->position().z(),
+                       (*(v->particles_begin(HepMC::parents)))->production_vertex()->position().t());
+   pp->SetProperTime( (lv-lv0).mag()/CLHEP::c_light );
+
+  // Loop over daughters
+  for (HepMC::GenVertex::particle_iterator it = v->particles_begin(HepMC::children);
+       it != v->particles_end(HepMC::children);
+       it++){
+
+    // Either way we will add this daughter to the pp's daughters...
+    G4PrimaryParticle *daughter = ConstructG4PrimaryParticle( (*it) );
+    bool pGood=true;
+    FADS::particleModifiers::const_iterator jt;
+
+    for (jt=gc->BeginParticleManipulator();jt!=gc->EndParticleManipulator();
+              ++jt)
+     {
+             if ((*jt).second->IsOn())
+             pGood=pGood&&(*jt).second->EditParticle(daughter);
+             if (!pGood) break;
+     }
+     if (pGood){
+
+       pp->SetDaughter( daughter );
+
+       if ( (*it)->end_vertex() ) {
+         // Send the daughter with its end vertex back to this method
+         ModifyVertex( daughter, (*it)->end_vertex() );
+       }
+    }
+  }
+
+  // add the vertex to our list
+  m_modded->push_back( v->barcode() );
+
+}
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/components/G4AtlasAlg_entries.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/components/G4AtlasAlg_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fea85a8f9282d83d1540edea1b4514aa4504fe7d
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/components/G4AtlasAlg_entries.cxx
@@ -0,0 +1,10 @@
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+#include "G4AtlasAlg/G4AtlasAlg.h"
+
+DECLARE_FACTORY_ENTRIES(G4AtlasAlg) {
+  DECLARE_ALGORITHM( G4AtlasAlg )
+}
+
+DECLARE_ALGORITHM_FACTORY( G4AtlasAlg )
+
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/components/G4AtlasAlg_load.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/components/G4AtlasAlg_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1931cdab48ca67195cafc827321471ca69b4c404
--- /dev/null
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/components/G4AtlasAlg_load.cxx
@@ -0,0 +1,4 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(G4AtlasAlg)
+