diff --git a/FullSimLight/CMakeLists.txt b/FullSimLight/CMakeLists.txt
index 5689c483a9f5db8bd814c7bf5930e46e35d48d7e..4eb3ca1aca317a8e2ecf41e9793aba938ab06e08 100644
--- a/FullSimLight/CMakeLists.txt
+++ b/FullSimLight/CMakeLists.txt
@@ -294,6 +294,7 @@ install( TARGETS FullSimLight
    
 install(FILES include/FSLSensitiveDetectorPlugin.h 
               include/MagFieldPlugin.h 
+              include/FSLPhysicsListPlugin.h
 	      include/FSLUserActionPlugin.h
               include/FSLUserRunActionPlugin.h
               include/FSLUserEventActionPlugin.h
diff --git a/FullSimLight/fullSimLight.cc b/FullSimLight/fullSimLight.cc
index f46261ece2401a677c44d4a91cfe238c5321d122..ee219783bcf5611bf1bd8313702455cd594fe1ca 100644
--- a/FullSimLight/fullSimLight.cc
+++ b/FullSimLight/fullSimLight.cc
@@ -13,19 +13,14 @@
 #include "G4UIsession.hh"
 #include "G4UIterminal.hh"
 
-#include "G4PhysListFactory.hh"
-#include "G4VUserPhysicsList.hh"
-#include "G4VModularPhysicsList.hh"
 
 #include "Randomize.hh"
 #include "FSLDetectorConstruction.hh"
-#include "StandardEmWithWoodcock.hh"
-#include "EmExtraPhysics.hh"
-#include "G4NeutronTrackingCut.hh"
+#include "FSLPhysListFactory.hh"
+#include "G4VModularPhysicsList.hh"
 
 #include "GeoModelKernel/GeoPluginLoader.h"
 
-
 #include "FSLActionInitialization.hh"
 #include "FSLConfigurator.hh"
 #include "PythiaPrimaryGeneratorAction.hh"
@@ -41,7 +36,7 @@
 #include <nlohmann/json.hpp>
 #include <fstream>
 
-                               
+
 static const std::string fullSimLightShareDir=FULLSIMLIGHTSHAREDIR;
 static std::string  parMacroFileName   = fullSimLightShareDir+"/macro.g4";
 static bool         parIsPerformance   = false;
@@ -168,36 +163,10 @@ int main(int argc, char** argv) {
 #endif
         }
     }
-    G4bool activateRegions = false;
-    G4VModularPhysicsList* physList = nullptr;
-    G4PhysListFactory factory;
-    if (factory.IsReferencePhysList(parPhysListName)) {
-        physList = factory.GetReferencePhysList(parPhysListName);
-    } else if (parPhysListName==G4String("FTFP_BERT_ATL_WDCK")) {
-        G4cout << "<<< Geant4 FTFP_BERT_ATL physics list with the local Woodcock settings " << G4endl;
-        physList = factory.GetReferencePhysList("FTFP_BERT_ATL");
-        // the local em-standard physics with Woodcock tracking for gamma
-        StandardEmWithWoodcock* em0AndWDCK = new StandardEmWithWoodcock;
-        // set the region name and low energy limit for Woodcock tracking
-        em0AndWDCK->SetRegionNameForWoodcockTracking("EMEC");
-        em0AndWDCK->SetLowEnergyLimitForWoodcockTracking(200.0*CLHEP::keV);
-        physList->ReplacePhysics(em0AndWDCK);
-        // the local version of the `G4EmExtraPhysics` that will use the local `GammaGeneralProcess`
-        G4VPhysicsConstructor* emExtra = new EmExtraPhysics;
-        physList->ReplacePhysics(emExtra);
-        //physList->RemovePhysics("G4GammaLeptoNuclearPhys");
-        // make sure that regions will also be added to the detector
-        activateRegions = true;
-    } else {
-        G4cerr << "ERROR: Physics List " << parPhysListName << " UNKNOWN!" << G4endl;
-        return -1;
-    }
-    // In cases of ATLAS physics lists, set the neutron tracking cut to be 150 [ns] as in Athena
-    if (parPhysListName.find("ATL") != std::string::npos) {
-        G4NeutronTrackingCut* neutronCut = new G4NeutronTrackingCut("neutronCutphysics", 1);
-        neutronCut->SetTimeLimit(150.0*CLHEP::ns);
-        physList->ReplacePhysics(neutronCut);
-    }
+
+    const FSLPhysListFactory *phyListFactory = FSLPhysListFactory::GetInstance();
+    G4VModularPhysicsList *physList = phyListFactory->GetPhysList(parPhysListName);
+    G4bool activateRegions = phyListFactory->GetActivateRegionsFlag();
     
     // register the final version of the physics list in the run manager
     runManager->SetUserInitialization(physList);
diff --git a/FullSimLight/include/FSLPhysListFactory.hh b/FullSimLight/include/FSLPhysListFactory.hh
new file mode 100644
index 0000000000000000000000000000000000000000..5e3a7458fa8ceabdc8c43afed649551dbb2c836d
--- /dev/null
+++ b/FullSimLight/include/FSLPhysListFactory.hh
@@ -0,0 +1,32 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef __FSLPhysListFactory_HH__
+#define __FSLPhysListFactory_HH__
+
+#include "G4VModularPhysicsList.hh"
+
+#include <string>
+
+
+
+class FSLPhysListFactory
+{
+public:
+    FSLPhysListFactory();
+    ~FSLPhysListFactory();
+
+    static G4VModularPhysicsList *GetPhysList(const std::string physListNameOrPluginPath);
+
+    static bool GetActivateRegionsFlag() {return fActivateRegionsFlag;}
+
+    static const FSLPhysListFactory* GetInstance();
+
+private:
+
+    static bool fActivateRegionsFlag;
+    
+    static const FSLPhysListFactory* fgInstance;
+};
+
+#endif //__FSLPhysListFactory_HH__
\ No newline at end of file
diff --git a/FullSimLight/include/FSLPhysicsListPlugin.h b/FullSimLight/include/FSLPhysicsListPlugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..205af0a934035dc946d0c00af5d43d2fe05b313a
--- /dev/null
+++ b/FullSimLight/include/FSLPhysicsListPlugin.h
@@ -0,0 +1,21 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef __FSLPhysicsListPlugin_h__
+#define __FSLPhysicsListPlugin_h__
+
+class G4VModularPhysicsList;
+
+class FSLPhysicsListPlugin
+{
+public:
+    FSLPhysicsListPlugin()=default;
+    ~FSLPhysicsListPlugin()=default;
+
+    virtual G4VModularPhysicsList* GetPhysicsList() const {return nullptr;}
+    virtual bool GetActivateRegionsFlag() const {return false;}
+
+};
+
+
+#endif //__FSLPhysicsListPlugin_h__
\ No newline at end of file
diff --git a/FullSimLight/src/FSLPhysListFactory.cc b/FullSimLight/src/FSLPhysListFactory.cc
new file mode 100644
index 0000000000000000000000000000000000000000..34e9584786dd240144e743ef65c31986089bd427
--- /dev/null
+++ b/FullSimLight/src/FSLPhysListFactory.cc
@@ -0,0 +1,110 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+#include "FSLPhysListFactory.hh"
+
+#include "G4VModularPhysicsList.hh"
+#include "G4PhysListFactory.hh"
+#include "G4NeutronTrackingCut.hh"
+
+#include "StandardEmWithWoodcock.hh"
+#include "EmExtraPhysics.hh"
+
+#include "GeoModelKernel/GeoPluginLoader.h"
+#include "FSLPhysicsListPlugin.h"
+
+#include <string>
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+const FSLPhysListFactory* FSLPhysListFactory::fgInstance = nullptr;
+
+bool FSLPhysListFactory::fActivateRegionsFlag;
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+const FSLPhysListFactory* FSLPhysListFactory::GetInstance()
+{
+    return fgInstance;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+FSLPhysListFactory::FSLPhysListFactory()
+{
+    fgInstance=this;
+    fActivateRegionsFlag = false;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+FSLPhysListFactory::~FSLPhysListFactory()
+{
+    delete fgInstance;
+    fgInstance = nullptr;
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+
+G4VModularPhysicsList* FSLPhysListFactory::GetPhysList(const std::string physListNameOrPluginPath)
+{
+
+    G4VModularPhysicsList* physList = nullptr;
+
+    if ( (physListNameOrPluginPath.find(".dylib") != std::string::npos) || //for macOS devices
+         (physListNameOrPluginPath.find(".so") != std::string::npos   )  ) //for Linux devices
+    {   //if the physics list comes from the plugin
+        std::string pluginPath = physListNameOrPluginPath;
+
+        GeoPluginLoader<FSLPhysicsListPlugin> loader;
+        FSLPhysicsListPlugin *plugin = loader.load(pluginPath);
+
+        physList = plugin->GetPhysicsList();
+        fActivateRegionsFlag = plugin->GetActivateRegionsFlag();
+
+        if (!physList)
+        {
+            G4cerr << "ERROR: The physics list is not set through the plugin" << pluginPath <<G4endl;
+            exit(-1);
+        }
+    }
+    else 
+    {   //if the physics list comes from a predefined name
+        
+        std::string parPhysListName = physListNameOrPluginPath;
+
+        G4PhysListFactory factory;
+        if (factory.IsReferencePhysList(parPhysListName)) {
+            physList = factory.GetReferencePhysList(parPhysListName);
+        } else if (parPhysListName==G4String("FTFP_BERT_ATL_WDCK")) {
+            G4cout << "<<< Geant4 FTFP_BERT_ATL physics list with the local Woodcock settings " << G4endl;
+            physList = factory.GetReferencePhysList("FTFP_BERT_ATL");
+            // the local em-standard physics with Woodcock tracking for gamma
+            StandardEmWithWoodcock* em0AndWDCK = new StandardEmWithWoodcock;
+            // set the region name and low energy limit for Woodcock tracking
+            em0AndWDCK->SetRegionNameForWoodcockTracking("EMEC");
+            em0AndWDCK->SetLowEnergyLimitForWoodcockTracking(200.0*CLHEP::keV);
+            physList->ReplacePhysics(em0AndWDCK);
+            // the local version of the `G4EmExtraPhysics` that will use the local `GammaGeneralProcess`
+            G4VPhysicsConstructor* emExtra = new EmExtraPhysics;
+            physList->ReplacePhysics(emExtra);
+            //physList->RemovePhysics("G4GammaLeptoNuclearPhys");
+            // make sure that regions will also be added to the detector
+            fActivateRegionsFlag = true;
+        } else {
+            G4cerr << "ERROR: Physics List " << parPhysListName << " UNKNOWN!" << G4endl;
+            exit(-1);
+        }
+        // In cases of ATLAS physics lists, set the neutron tracking cut to be 150 [ns] as in Athena
+        if (parPhysListName.find("ATL") != std::string::npos) {
+            G4NeutronTrackingCut* neutronCut = new G4NeutronTrackingCut("neutronCutphysics", 1);
+            neutronCut->SetTimeLimit(150.0*CLHEP::ns);
+            physList->ReplacePhysics(neutronCut);
+        }
+    }
+
+    return physList;
+
+}
+
+//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
\ No newline at end of file