diff --git a/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorTool.h b/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorAlgorithm.h
similarity index 50%
rename from Reconstruction/eflowRec/eflowRec/PFOChargedCreatorTool.h
rename to Reconstruction/eflowRec/eflowRec/PFOChargedCreatorAlgorithm.h
index 2ea32817837e319945ba2e0aae5d1e928effe6d0..0473f0d4bf6ae55d405ce64326fc5bdc6b8d9795 100644
--- a/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorTool.h
+++ b/Reconstruction/eflowRec/eflowRec/PFOChargedCreatorAlgorithm.h
@@ -1,9 +1,9 @@
-#ifndef PFOCHARGEDCREATORTOOL_H
-#define PFOCHARGEDCREATORTOOL_H
+#ifndef PFOCHARGEDCREATORALGORITHM_H
+#define PFOCHARGEDCREATORALGORITHM_H
 
-#include "eflowRec/IPFBaseTool.h"
+#include "eflowRec/eflowCaloObject.h"
 
-#include "AthenaBaseComps/AthAlgTool.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
 #include "GaudiKernel/ToolHandle.h"
 #include "StoreGate/DataHandle.h"
 
@@ -12,31 +12,22 @@
 #include "xAODPFlow/PFOContainer.h"
 #include "xAODTracking/VertexContainer.h"
 
-class eflowCaloObject;
-class eflowCaloObjectContainer;
-class eflowRecCluster;
-
-static const InterfaceID IID_PFOChargedCreatorTool("PFOChargedCreatorTool", 1, 0);
-
-class PFOChargedCreatorTool : virtual public IPFBaseTool, public AthAlgTool {
+class PFOChargedCreatorAlgorithm : public AthAlgorithm {
   
 public:
   
-  PFOChargedCreatorTool(const std::string& type,const std::string& name,const IInterface* parent);
-
-  ~PFOChargedCreatorTool() {}
+  PFOChargedCreatorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
 
-  static const InterfaceID& interfaceID();
+  ~PFOChargedCreatorAlgorithm() {}
 
   StatusCode initialize();
-  StatusCode execute(eflowCaloObject* energyFlowCaloObject);
-  void execute(eflowCaloObjectContainer* theEflowCaloObjectContainer, xAOD::CaloClusterContainer& theCaloClusterContainer);
+  void execute(const eflowCaloObject& energyFlowCaloObject);
+  StatusCode execute();
   StatusCode finalize();
 
 private:
-  StatusCode setupPFOContainers();
   /** Create the charged PFO */ 
-  void createChargedPFO(eflowCaloObject* energyFlowCaloObject, bool addClusters = false);
+  void createChargedPFO(const eflowCaloObject& energyFlowCaloObject, bool addClusters = false);
   /** Function to add links to the vertex to which a charged PFO is matched (using the tracking CP loose vertex association tool) */
   void addVertexLinksToChargedPFO(const xAOD::VertexContainer& theVertexContainer);
 
@@ -48,16 +39,13 @@ private:
 
   /** ReadHandle for vertex container */
   SG::ReadHandle<xAOD::VertexContainer> m_vertexContainerReadHandle;
+
+  /** ReadHandle for eflowCaloObjectContainer */
+  SG::ReadHandle<eflowCaloObjectContainer> m_eflowCaloObjectContainerReadHandle;
   
   /** WriteHandle for charged PFO */
   SG::WriteHandle<xAOD::PFOContainer> m_chargedPFOContainerWriteHandle;
   
   
 };
-
-inline const InterfaceID& PFOChargedCreatorTool::interfaceID()
-{ 
-  return IID_PFOChargedCreatorTool;
-}
-
 #endif
diff --git a/Reconstruction/eflowRec/eflowRec/PFONeutralCreatorAlgorithm.h b/Reconstruction/eflowRec/eflowRec/PFONeutralCreatorAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..0922ac7c8dd3646992bada4dda52197f3f23b967
--- /dev/null
+++ b/Reconstruction/eflowRec/eflowRec/PFONeutralCreatorAlgorithm.h
@@ -0,0 +1,51 @@
+#ifndef PFONEUTRALCREATORALGORITHM_H
+#define PFONEUTRALCREATORALGORITHM_H
+
+#include "eflowRec/eflowCaloObject.h"
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "StoreGate/DataHandle.h"
+
+#include "xAODCaloEvent/CaloCluster.h"
+#include "xAODPFlow/PFO.h"
+#include "xAODPFlow/PFOContainer.h"
+
+class PFONeutralCreatorAlgorithm :  public AthAlgorithm {
+  
+public:
+  
+  PFONeutralCreatorAlgorithm(const std::string& name,ISvcLocator* pSvcLocator);
+
+  ~PFONeutralCreatorAlgorithm() {}
+
+  static const InterfaceID& interfaceID();
+
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+private:
+  /** Create the chargedneutral PFO */ 
+  void createNeutralPFO(const eflowCaloObject& energyFlowCaloObject);
+
+  /** Function to add cluster moments onto PFO */
+  void addMoment(const xAOD::CaloCluster::MomentType& momentType, const xAOD::PFODetails::PFOAttributes& pfoAttribute, const xAOD::CaloCluster& theCluster, xAOD::PFO& thePFO);
+ 
+  /** Toggle e/p mode */
+  bool m_eOverPMode;
+
+  /** Bool to toggle which jetetmiss configuration we are in - EM cluster input or LC cluster input */
+  bool m_LCMode;
+
+  /** ReadHandle for eflowCaloObjectContainer */
+  SG::ReadHandle<eflowCaloObjectContainer> m_eflowCaloObjectContainerReadHandle;
+  
+  /** WriteHandle for neutral PFO */
+  SG::WriteHandle<xAOD::PFOContainer> m_neutralPFOContainerWriteHandle;
+
+  /** WriteHandle for non-modified neutral PFO - only used in LC mode */
+  SG::WriteHandle<xAOD::PFOContainer> m_neutralPFOContainerWriteHandle_nonModified;  
+  
+};
+#endif
diff --git a/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h b/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h
index f52a29322848efd0e342f28c520b58a6d07a466a..5c7b9f124a658f289d28ba05883237acf2250eb5 100644
--- a/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h
+++ b/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h
@@ -54,12 +54,12 @@ public:
   }
 
   /* Track accessor methods */
-  eflowRecTrack* efRecTrack(int i) { return m_eflowRecTracks[i]; }
+  eflowRecTrack* efRecTrack(int i) const { return m_eflowRecTracks[i]; }
   unsigned nTracks() const{ return m_eflowRecTracks.size(); }
   void clearTracks() { m_eflowRecTracks.clear(); }
 
   /* Cluster accessor methods */
-  eflowRecCluster* efRecCluster(int i) { return m_eflowRecClusters[i]; }
+  eflowRecCluster* efRecCluster(int i) const { return m_eflowRecClusters[i]; }
   unsigned nClusters() const{ return m_eflowRecClusters.size(); }
   void clearClusters() { m_eflowRecClusters.clear(); }
 
diff --git a/Reconstruction/eflowRec/src/PFOChargedCreatorTool.cxx b/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx
similarity index 80%
rename from Reconstruction/eflowRec/src/PFOChargedCreatorTool.cxx
rename to Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx
index a29ec3aa36f560344eb66fd400ff30dd79005f23..56cd35bfa376c9ce11e636c2d94e2ccfe96d0100 100644
--- a/Reconstruction/eflowRec/src/PFOChargedCreatorTool.cxx
+++ b/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx
@@ -1,19 +1,18 @@
-#include "eflowRec/PFOChargedCreatorTool.h"
+#include "eflowRec/PFOChargedCreatorAlgorithm.h"
 
-#include "eflowRec/eflowCaloObject.h"
 #include "eflowRec/eflowRecCluster.h"
 #include "eflowRec/eflowRecTrack.h"
 
 #include "xAODPFlow/PFOAuxContainer.h"
 
-PFOChargedCreatorTool::PFOChargedCreatorTool(const std::string& type, const std::string& name, const IInterface* parent) :
-    AthAlgTool(type, name, parent),
+PFOChargedCreatorAlgorithm::PFOChargedCreatorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator) :
+  AthAlgorithm(name,pSvcLocator) ,
     m_eOverPMode(false),
     m_trackVertexAssociationTool("",this),
     m_vertexContainerReadHandle("PrimaryVertices"),
+    m_eflowCaloObjectContainerReadHandle("eflowCaloObjects"),
     m_chargedPFOContainerWriteHandle("JetETMissChargedParticleFlowObjectsV2")
 {
-  declareInterface<PFOChargedCreatorTool>(this);
   /* Name of  eflow Container to be created */
   declareProperty("EOverPMode", m_eOverPMode);
   declareProperty("TrackVertexAssociationTool", m_trackVertexAssociationTool);
@@ -21,59 +20,56 @@ PFOChargedCreatorTool::PFOChargedCreatorTool(const std::string& type, const std:
   declareProperty("PFOOutputName", m_chargedPFOContainerWriteHandle);
 }
 
-StatusCode PFOChargedCreatorTool::initialize(){
+StatusCode PFOChargedCreatorAlgorithm::initialize(){
 
   ATH_CHECK(m_trackVertexAssociationTool.retrieve());
 
   ATH_CHECK(m_vertexContainerReadHandle.initialize());
+  ATH_CHECK(m_eflowCaloObjectContainerReadHandle.initialize());
 
   ATH_CHECK(m_chargedPFOContainerWriteHandle.initialize());
   
   return StatusCode::SUCCESS;
 }
 
-StatusCode  PFOChargedCreatorTool::execute(eflowCaloObject* energyFlowCaloObject){
+void PFOChargedCreatorAlgorithm::execute(const eflowCaloObject& energyFlowCaloObject){
 
-  ATH_MSG_DEBUG("Executing eflowObjectCreatorTool ");
+  ATH_MSG_DEBUG("Processing eflowCaloObject");
   
   if (m_eOverPMode) createChargedPFO(energyFlowCaloObject, true);
   else createChargedPFO(energyFlowCaloObject);
 
   const xAOD::VertexContainer* theVertexContainer = m_vertexContainerReadHandle.ptr();  
   addVertexLinksToChargedPFO(*theVertexContainer);
-
-  return StatusCode::SUCCESS;
   
 }
 
-void PFOChargedCreatorTool::execute(eflowCaloObjectContainer* theEflowCaloObjectContainer, xAOD::CaloClusterContainer& theCaloClusterContainer){
+StatusCode  PFOChargedCreatorAlgorithm::execute(){
 
   ATH_MSG_DEBUG("Processing eflowCaloObjectContainer");
 
   m_chargedPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>());
-
+  
   /* Create Charged PFOs from all eflowCaloObjects */
-  unsigned int nEFCaloObs = theEflowCaloObjectContainer->size();
+  unsigned int nEFCaloObs = m_eflowCaloObjectContainerReadHandle->size();
   for (unsigned int iEFCalOb = 0; iEFCalOb < nEFCaloObs; ++iEFCalOb){
-    eflowCaloObject* thisEflowCaloObject = theEflowCaloObjectContainer->at(iEFCalOb);
-    if (execute(thisEflowCaloObject).isFailure()){
-      ATH_MSG_WARNING("Execute failed for one eflowCaloObject. ");
-      continue;
-    }
+    const eflowCaloObject* thisEflowCaloObject = m_eflowCaloObjectContainerReadHandle->at(iEFCalOb);
+    execute(*thisEflowCaloObject);
   }
 
+  return StatusCode::SUCCESS;
   
 }
 
-StatusCode PFOChargedCreatorTool::finalize(){ return StatusCode::SUCCESS; }
+StatusCode PFOChargedCreatorAlgorithm::finalize(){ return StatusCode::SUCCESS; }
 
-void PFOChargedCreatorTool::createChargedPFO(eflowCaloObject* energyFlowCaloObject, bool addClusters){
+void PFOChargedCreatorAlgorithm::createChargedPFO(const eflowCaloObject& energyFlowCaloObject, bool addClusters){
 
   /* Loop over all tracks in the eflowCaloObject */
-  int nTracks = energyFlowCaloObject->nTracks();
+  int nTracks = energyFlowCaloObject.nTracks();
   for (int iTrack = 0; iTrack < nTracks; ++iTrack) {
 
-    eflowRecTrack* efRecTrack = energyFlowCaloObject->efRecTrack(iTrack);
+    eflowRecTrack* efRecTrack = energyFlowCaloObject.efRecTrack(iTrack);
 
     /* Skip tracks that haven't been subtracted */
     if (false == m_eOverPMode){
@@ -128,9 +124,9 @@ void PFOChargedCreatorTool::createChargedPFO(eflowCaloObject* energyFlowCaloObje
 
     /* Optionally we add the links to clusters to the xAOD::PFO */
     if (true == addClusters){
-       unsigned int nClusters = energyFlowCaloObject->nClusters();
+       unsigned int nClusters = energyFlowCaloObject.nClusters();
        for (unsigned int iCluster = 0; iCluster < nClusters; ++iCluster){
-	 eflowRecCluster* thisEfRecCluster = energyFlowCaloObject->efRecCluster(iCluster);
+	 eflowRecCluster* thisEfRecCluster = energyFlowCaloObject.efRecCluster(iCluster);
 	 ElementLink<xAOD::CaloClusterContainer> theClusLink = thisEfRecCluster->getClusElementLink();
 	 bool isSet = thisPFO->addClusterLink(theClusLink);
 	 if (!isSet) msg(MSG::WARNING) << "Could not set Cluster in PFO " << endmsg;
@@ -140,7 +136,7 @@ void PFOChargedCreatorTool::createChargedPFO(eflowCaloObject* energyFlowCaloObje
   }//loop over the tracks on the eflowCaloObject
 }
 
-void PFOChargedCreatorTool::addVertexLinksToChargedPFO(const xAOD::VertexContainer& theVertexContainer){
+void PFOChargedCreatorAlgorithm::addVertexLinksToChargedPFO(const xAOD::VertexContainer& theVertexContainer){
 
   //This is a loop on all xAOD::PFO with non-zero charge
   for (auto theChargedPFO : *m_chargedPFOContainerWriteHandle){
diff --git a/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx b/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a2e9d60c80644a72489cbe9bd554ab70a4da7850
--- /dev/null
+++ b/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx
@@ -0,0 +1,267 @@
+#include "eflowRec/PFONeutralCreatorAlgorithm.h"
+
+#include "eflowRec/eflowCaloObject.h"
+#include "eflowRec/eflowRecCluster.h"
+
+#include "xAODPFlow/PFOAuxContainer.h"
+
+PFONeutralCreatorAlgorithm::PFONeutralCreatorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator) :
+    AthAlgorithm(name, pSvcLocator),
+    m_eOverPMode(false),
+    m_LCMode(false),
+    m_eflowCaloObjectContainerReadHandle("eflowCaloObjects"),
+    m_neutralPFOContainerWriteHandle("JetETMissNeutralParticleFlowObjectsV2"),
+    m_neutralPFOContainerWriteHandle_nonModified("JetETMissNeutralParticleFlowObjects_nonModified")    
+{
+  /* Name of  eflow Container to be created */
+  declareProperty("EOverPMode", m_eOverPMode);
+  declareProperty("PFOOutputName", m_neutralPFOContainerWriteHandle);
+  declareProperty("PFOOutputName_nonModified", m_neutralPFOContainerWriteHandle_nonModified);
+}
+
+StatusCode PFONeutralCreatorAlgorithm::initialize(){
+
+  ATH_CHECK(m_eflowCaloObjectContainerReadHandle.initialize());
+  ATH_CHECK(m_neutralPFOContainerWriteHandle.initialize());
+  if (m_LCMode) ATH_CHECK(m_neutralPFOContainerWriteHandle_nonModified.initialize());
+  return StatusCode::SUCCESS;
+  
+}
+
+StatusCode PFONeutralCreatorAlgorithm::execute(){
+
+  ATH_MSG_DEBUG("Executing");
+  
+  m_neutralPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>());
+  if (m_LCMode) m_neutralPFOContainerWriteHandle_nonModified.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>());
+  
+  /* Create Neutral PFOs from all eflowCaloObjects */
+  unsigned int nEFCaloObs =  m_eflowCaloObjectContainerReadHandle->size();
+  for (unsigned int iEFCalOb = 0; iEFCalOb < nEFCaloObs; ++iEFCalOb){
+    const eflowCaloObject* thisEflowCaloObject =  m_eflowCaloObjectContainerReadHandle->at(iEFCalOb);
+    createNeutralPFO(*thisEflowCaloObject);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode PFONeutralCreatorAlgorithm::finalize(){ return StatusCode::SUCCESS; }
+
+void PFONeutralCreatorAlgorithm::createNeutralPFO(const eflowCaloObject& energyFlowCaloObject){
+
+   unsigned int nClusters = energyFlowCaloObject.nClusters();
+  for (unsigned int iCluster = 0; iCluster < nClusters; ++iCluster){
+    eflowRecCluster* thisEfRecCluster = energyFlowCaloObject.efRecCluster(iCluster);
+
+    /* Skip empty clusters (presumably subtraction remnants) */
+    const CaloClusterCellLink* theCellLink = energyFlowCaloObject.efRecCluster(iCluster)->getCluster()->getCellLinks();
+    CaloClusterCellLink::const_iterator it=theCellLink->begin();
+    CaloClusterCellLink::const_iterator it_e=theCellLink->end();
+    if (it == it_e) {
+      continue;
+    }
+    //this vetoes rare examples where only two cells are left, and they have equal and opposite energy
+    if (0.0 == energyFlowCaloObject.efRecCluster(iCluster)->getCluster()->e() ) continue;
+
+    /* Create the efo, add the cluster and set the four-momentum, charge and type */
+
+    xAOD::PFO* thisPFO = new xAOD::PFO();
+    if (m_LCMode) {
+      if (thisEfRecCluster->isTouchable()) {
+        m_neutralPFOContainerWriteHandle->push_back(thisPFO);
+      } else {
+	m_neutralPFOContainerWriteHandle_nonModified->push_back(thisPFO);
+      }
+    } else {
+      m_neutralPFOContainerWriteHandle->push_back(thisPFO);
+    }
+
+    ElementLink<xAOD::CaloClusterContainer> theClusterLink = thisEfRecCluster->getClusElementLink();
+    bool isSet = thisPFO->setClusterLink(theClusterLink);
+    if (!isSet) { msg(MSG::WARNING) << "Could not set Cluster in PFO " << endmsg; }
+
+    const xAOD::CaloCluster* cluster = thisEfRecCluster->getCluster();
+    //be careful here - cluster p4 methods do not store sign. Thus -ve energy clusters have +ve pt and hence +ve energy
+    if (!m_LCMode) {
+      //in EM->EM/LC mode we use eta,phi at EM scale for both 4-vectors
+      thisPFO->setP4(cluster->pt(), cluster->rawEta(), cluster->rawPhi(), cluster->m());
+      thisPFO->setP4EM(cluster->rawE()/cosh(cluster->rawEta()), cluster->rawEta(),cluster->rawPhi(),cluster->rawM());
+    }
+    else{
+      //in LC-> mode we use the LC 4-vector for the LC scale
+      thisPFO->setP4(cluster->pt(), cluster->eta(), cluster->phi(), cluster->m());
+      //we cannot access geometric weights for LC clusters, so we make an approximation of the EM energy by looping over the calocells
+      //Then the EM 4-vector uses the energy/pt at this EM scale + eta,phi from LC 4-vector
+      const CaloClusterCellLink* theCellLink = cluster->getCellLinks();
+      auto theFirstCell = theCellLink->begin();
+      auto theLastCell = theCellLink->end();
+      float emPt = 0.0;
+      for (; theFirstCell != theLastCell; ++theFirstCell){
+	const CaloCell* thisCell = *theFirstCell;
+	emPt += thisCell->e()/cosh(thisCell->eta());
+      }
+      thisPFO->setP4EM(emPt,cluster->eta(),cluster->phi(),0.0);//mass is always zero at EM scale
+
+    }
+
+    thisPFO->setCharge(0);
+
+    //now set the moments for touchable clusters (i.e. ones we modify) in LC mode or all clusters in EM mode
+    if ( (m_LCMode && thisEfRecCluster->isTouchable()) || !m_LCMode) {
+      this->addMoment(xAOD::CaloCluster::SECOND_R,xAOD::PFODetails::PFOAttributes::eflowRec_SECOND_R,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::CENTER_LAMBDA,xAOD::PFODetails::PFOAttributes::eflowRec_CENTER_LAMBDA,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::ENG_BAD_CELLS,xAOD::PFODetails::PFOAttributes::eflowRec_ENG_BAD_CELLS,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::N_BAD_CELLS,xAOD::PFODetails::PFOAttributes::eflowRec_N_BAD_CELLS,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::BADLARQ_FRAC,xAOD::PFODetails::PFOAttributes::eflowRec_BADLARQ_FRAC,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::ENG_POS,xAOD::PFODetails::PFOAttributes::eflowRec_ENG_POS,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::AVG_LAR_Q,xAOD::PFODetails::PFOAttributes::eflowRec_AVG_LAR_Q,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::AVG_TILE_Q,xAOD::PFODetails::PFOAttributes::eflowRec_AVG_TILE_Q,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::ISOLATION,xAOD::PFODetails::PFOAttributes::eflowRec_ISOLATION,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::SECOND_LAMBDA,xAOD::PFODetails::PFOAttributes::eflowRec_SECOND_LAMBDA,*cluster, *thisPFO);
+      this->addMoment(xAOD::CaloCluster::EM_PROBABILITY,xAOD::PFODetails::PFOAttributes::eflowRec_EM_PROBABILITY,*cluster, *thisPFO);
+    }
+
+    //First set all the layer energies
+    float layerEnergy_preSamplerB = cluster->eSample(xAOD::CaloCluster::CaloSample::PreSamplerB);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_PreSamplerB = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_PreSamplerB;
+    thisPFO->setAttribute( myAttribute_layerEnergy_PreSamplerB, layerEnergy_preSamplerB);
+
+    float layerEnergy_EMB1 = cluster->eSample(xAOD::CaloCluster::CaloSample::EMB1);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EMB1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EMB1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_EMB1, layerEnergy_EMB1);
+
+    float layerEnergy_EMB2 = cluster->eSample(xAOD::CaloCluster::CaloSample::EMB2);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EMB2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EMB2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_EMB2, layerEnergy_EMB2);
+
+    float layerEnergy_EMB3 = cluster->eSample(xAOD::CaloCluster::CaloSample::EMB3);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EMB3 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EMB3;
+    thisPFO->setAttribute( myAttribute_layerEnergy_EMB3, layerEnergy_EMB3);
+
+    float layerEnergy_preSamplerE = cluster->eSample(xAOD::CaloCluster::CaloSample::PreSamplerE);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_PreSamplerE = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_PreSamplerE;
+    thisPFO->setAttribute( myAttribute_layerEnergy_PreSamplerE, layerEnergy_preSamplerE);
+
+    float layerEnergy_EME1 = cluster->eSample(xAOD::CaloCluster::CaloSample::EME1);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EME1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EME1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_EME1, layerEnergy_EME1);
+
+    float layerEnergy_EME2 = cluster->eSample(xAOD::CaloCluster::CaloSample::EME2);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EME2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EME2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_EME2, layerEnergy_EME2);
+
+    float layerEnergy_EME3 = cluster->eSample(xAOD::CaloCluster::CaloSample::EME3);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EME3 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EME3;
+    thisPFO->setAttribute( myAttribute_layerEnergy_EME3, layerEnergy_EME3);
+
+    float layerEnergy_HEC0 = cluster->eSample(xAOD::CaloCluster::CaloSample::HEC0);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_HEC0 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_HEC0;
+    thisPFO->setAttribute( myAttribute_layerEnergy_HEC0, layerEnergy_HEC0);
+
+    float layerEnergy_HEC1 = cluster->eSample(xAOD::CaloCluster::CaloSample::HEC1);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_HEC1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_HEC1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_HEC1, layerEnergy_HEC1);
+
+    float layerEnergy_HEC2 = cluster->eSample(xAOD::CaloCluster::CaloSample::HEC2);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_HEC2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_HEC2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_HEC2, layerEnergy_HEC2);
+
+    float layerEnergy_HEC3 = cluster->eSample(xAOD::CaloCluster::CaloSample::HEC3);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_HEC3 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_HEC3;
+    thisPFO->setAttribute( myAttribute_layerEnergy_HEC3, layerEnergy_HEC3);
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileBar0 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileBar0;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileBar0, cluster->eSample(xAOD::CaloCluster::CaloSample::TileBar0));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileBar1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileBar1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileBar1, cluster->eSample(xAOD::CaloCluster::CaloSample::TileBar1));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileBar2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileBar2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileBar2, cluster->eSample(xAOD::CaloCluster::CaloSample::TileBar2));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileGap1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileGap1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileGap1, cluster->eSample(xAOD::CaloCluster::CaloSample::TileGap1));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileGap2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileGap2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileGap2, cluster->eSample(xAOD::CaloCluster::CaloSample::TileGap2));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileGap3 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileGap3;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileGap3, cluster->eSample(xAOD::CaloCluster::CaloSample::TileGap3));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileExt0 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileExt0;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileExt0, cluster->eSample(xAOD::CaloCluster::CaloSample::TileExt0));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileExt1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileExt1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileExt1, cluster->eSample(xAOD::CaloCluster::CaloSample::TileExt1));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_TileExt2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_TileExt2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_TileExt2, cluster->eSample(xAOD::CaloCluster::CaloSample::TileExt2));
+
+    float layerEnergy_FCAL0 = cluster->eSample(xAOD::CaloCluster::CaloSample::FCAL0);
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_FCAL0 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_FCAL0;
+    thisPFO->setAttribute( myAttribute_layerEnergy_FCAL0, layerEnergy_FCAL0);
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_FCAL1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_FCAL1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_FCAL1, cluster->eSample(xAOD::CaloCluster::CaloSample::FCAL1));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_FCAL2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_FCAL2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_FCAL2, cluster->eSample(xAOD::CaloCluster::CaloSample::FCAL2));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_MINIFCAL0 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_MINIFCAL0;
+    thisPFO->setAttribute( myAttribute_layerEnergy_MINIFCAL0, cluster->eSample(xAOD::CaloCluster::CaloSample::MINIFCAL0));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_MINIFCAL1 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_MINIFCAL1;
+    thisPFO->setAttribute( myAttribute_layerEnergy_MINIFCAL1, cluster->eSample(xAOD::CaloCluster::CaloSample::MINIFCAL1));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_MINIFCAL2 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_MINIFCAL2;
+    thisPFO->setAttribute( myAttribute_layerEnergy_MINIFCAL2, cluster->eSample(xAOD::CaloCluster::CaloSample::MINIFCAL2));
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_MINIFCAL3 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_MINIFCAL3;
+    thisPFO->setAttribute( myAttribute_layerEnergy_MINIFCAL3, cluster->eSample(xAOD::CaloCluster::CaloSample::MINIFCAL3));
+
+    //now set the layer energies for EMB3 and Tile0 - these are needed if we want to run a GSC style jet calibration, which is binned in EMB3 and Tile0 layer energies
+    
+    float layerEnergy_EM3 = layerEnergy_EMB3 + layerEnergy_EME3;
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EM3 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EM3;
+    thisPFO->setAttribute( myAttribute_layerEnergy_EM3, layerEnergy_EM3);
+
+    float layerEnergy_TileBar0 = cluster->eSample(xAOD::CaloCluster::CaloSample::TileBar0);
+    float layerEnergy_TileExt0 = cluster->eSample(xAOD::CaloCluster::CaloSample::TileExt0);
+    float layerEnergy_Tile0 = layerEnergy_TileBar0 + layerEnergy_TileExt0;
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_Tile0 = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_Tile0;
+    thisPFO->setAttribute(myAttribute_layerEnergy_Tile0, layerEnergy_Tile0);
+
+    //now set properties that are required for jet cleaning
+    float layerEnergy_HEC = layerEnergy_HEC0 + layerEnergy_HEC1 + layerEnergy_HEC2 + layerEnergy_HEC3;
+
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_HEC = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_HEC;
+    thisPFO->setAttribute(myAttribute_layerEnergy_HEC, layerEnergy_HEC);
+
+    float layerEnergy_EM = layerEnergy_preSamplerB + layerEnergy_preSamplerE + layerEnergy_EMB1 + layerEnergy_EMB2 + layerEnergy_EMB3 + layerEnergy_EME1 + layerEnergy_EME2 + layerEnergy_EME3 + layerEnergy_FCAL0;
+    xAOD::PFODetails::PFOAttributes myAttribute_layerEnergy_EM = xAOD::PFODetails::PFOAttributes::eflowRec_LAYERENERGY_EM;
+    thisPFO->setAttribute(myAttribute_layerEnergy_EM, layerEnergy_EM);
+    
+    float clusterTiming = cluster->time();
+
+    xAOD::PFODetails::PFOAttributes myAttribute_TIMING = xAOD::PFODetails::PFOAttributes::eflowRec_TIMING;
+    thisPFO->setAttribute(myAttribute_TIMING, clusterTiming);
+
+    if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Created neutral EFO with E, eta and phi of " << thisPFO->e() << ", " << thisPFO->eta() << " and " << thisPFO->phi() << std::endl;
+
+  }
+}
+
+void PFONeutralCreatorAlgorithm::addMoment(const xAOD::CaloCluster::MomentType& momentType, const xAOD::PFODetails::PFOAttributes& pfoAttribute, const xAOD::CaloCluster& theCluster, xAOD::PFO& thePFO){
+
+  double moment = 0.0;
+  bool isRetrieved = theCluster.retrieveMoment(momentType, moment);
+  if (true == isRetrieved) {
+    xAOD::PFODetails::PFOAttributes myAttribute = pfoAttribute;
+    float float_moment = static_cast<float>(moment);
+    thePFO.setAttribute(myAttribute, float_moment);
+  }
+  else if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << " Could not retrieve moment from the CaloCluster " << endmsg;
+
+}
diff --git a/Reconstruction/eflowRec/src/components/eflowRec_entries.cxx b/Reconstruction/eflowRec/src/components/eflowRec_entries.cxx
index b6f2d2b02eac082fc45aac844da33b109f63e272..80b6931d5fec22dac3d0c7560c6b98b06c7e7155 100644
--- a/Reconstruction/eflowRec/src/components/eflowRec_entries.cxx
+++ b/Reconstruction/eflowRec/src/components/eflowRec_entries.cxx
@@ -24,7 +24,8 @@
 #include "eflowRec/PFMomentCalculatorTool.h"
 #include "eflowRec/PFClusterCollectionTool.h"
 #include "eflowRec/PFLCCalibTool.h"
-#include "eflowRec/PFOChargedCreatorTool.h"
+#include "eflowRec/PFOChargedCreatorAlgorithm.h"
+#include "eflowRec/PFONeutralCreatorAlgorithm.h"
 #include "GaudiKernel/DeclareFactoryEntries.h"
 
 DECLARE_ALGORITHM_FACTORY( eflowBuilder )
@@ -37,12 +38,13 @@ DECLARE_ALGORITHM_FACTORY( PFLeptonSelector )
 DECLARE_ALGORITHM_FACTORY( PFClusterSelector )
 DECLARE_ALGORITHM_FACTORY( PFTrackSelector )
 DECLARE_ALGORITHM_FACTORY( PFAlgorithm )
+DECLARE_ALGORITHM_FACTORY( PFOChargedCreatorAlgorithm )
+DECLARE_ALGORITHM_FACTORY( PFONeutralCreatorAlgorithm )
 DECLARE_TOOL_FACTORY( PFCellLevelSubtractionTool )
 DECLARE_TOOL_FACTORY( PFRecoverSplitShowersTool )
 DECLARE_TOOL_FACTORY( PFMomentCalculatorTool )
 DECLARE_TOOL_FACTORY( PFClusterCollectionTool )
 DECLARE_TOOL_FACTORY( PFLCCalibTool )
-DECLARE_TOOL_FACTORY( PFOChargedCreatorTool )
 DECLARE_TOOL_FACTORY( eflowRecoverSplitShowersTool )
 DECLARE_TOOL_FACTORY( eflowCellLevelSubtractionTool )
 DECLARE_TOOL_FACTORY( eflowLCCalibTool )
@@ -66,12 +68,13 @@ DECLARE_FACTORY_ENTRIES(eflowRec) {
     DECLARE_ALGORITHM( PFClusterSelector )
     DECLARE_ALGORITHM( PFTrackSelector )
     DECLARE_ALGORITHM( PFAlgorithm )
+    DECLARE_ALGORITHM( PFOChargedCreatorAlgorithm )
+    DECLARE_ALGORITHM( PFONeutralCreatorAlgorithm )
     DECLARE_TOOL( PFCellLevelSubtractionTool )
     DECLARE_TOOL( PFRecoverSplitShowersTool )
     DECLARE_TOOL( PFMomentCalculatorTool )
     DECLARE_TOOL( PFClusterCollectionTool )
     DECLARE_TOOL( PFLCCalibTool )
-    DECLARE_TOOL( PFOChargedCreatorTool )
     DECLARE_TOOL ( eflowRecoverSplitShowersTool )
     DECLARE_TOOL ( eflowCellLevelSubtractionTool )
     DECLARE_TOOL ( eflowMomentCalculatorTool )