diff --git a/Generators/HepMCWeightSvc/CMakeLists.txt b/Generators/HepMCWeightSvc/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3443c1b77c30971fd58e66fd65bb7e887201953d
--- /dev/null
+++ b/Generators/HepMCWeightSvc/CMakeLists.txt
@@ -0,0 +1,26 @@
+################################################################################
+# Package: HepMCWeightSvc
+################################################################################
+
+# Declare the package name:
+atlas_subdir( HepMCWeightSvc )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          GaudiKernel
+                          PRIVATE
+                          Control/AthenaBaseComps
+                          Database/AthenaPOOL/AthenaPoolUtilities
+                          Database/IOVDbDataModel
+                          Database/IOVDbMetaDataTools
+                          Event/EventInfo )
+
+# Component(s) in the package:
+atlas_add_component( HepMCWeightSvc
+                     src/*.cxx
+                     src/components/*.cxx
+                     LINK_LIBRARIES GaudiKernel AthenaBaseComps AthenaPoolUtilities IOVDbDataModel EventInfo )
+
+# Install files from the package:
+atlas_install_headers( HepMCWeightSvc )
+
diff --git a/Generators/HepMCWeightSvc/HepMCWeightSvc/IHepMCWeightSvc.h b/Generators/HepMCWeightSvc/HepMCWeightSvc/IHepMCWeightSvc.h
new file mode 100644
index 0000000000000000000000000000000000000000..b2958657a0eb7307504810bc526479ed449ccdf8
--- /dev/null
+++ b/Generators/HepMCWeightSvc/HepMCWeightSvc/IHepMCWeightSvc.h
@@ -0,0 +1,33 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef EVGENPRODTOOLS_IHEPMCWEIGHTSVC_H
+#define EVGENPRODTOOLS_IHEPMCWEIGHTSVC_H
+
+#include "GaudiKernel/IInterface.h"
+#include <string>
+
+/// @brief IService to read/write HepMC's WeightContainer key names from/to IOVMetaDataContainers
+///  author: will buttinger , NLAA
+/// 
+///
+
+static const InterfaceID IID_IHepMCWeightSvc("IHepMCWeightSvc", 1 , 0);
+
+class IHepMCWeightSvc : virtual public IInterface {
+public:
+
+
+   ///checks for any changes to weightnames ... none are allowed. Then records to metadata
+   virtual StatusCode setWeightNames(const std::map<std::string, std::size_t>& weightNames)= 0;
+
+   ///returns the current weight names ... will only change at file boudaries, it is assumed all events in a given file will have same weights in SAME ORDER
+   virtual const std::map<std::string, std::size_t>& weightNames() = 0;
+
+  static const InterfaceID& interfaceID() { return IID_IHepMCWeightSvc; }
+
+
+};
+
+#endif
diff --git a/Generators/HepMCWeightSvc/cmt/requirements b/Generators/HepMCWeightSvc/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..76f08de47a351bd6464eba111939ea9af9bb5dfc
--- /dev/null
+++ b/Generators/HepMCWeightSvc/cmt/requirements
@@ -0,0 +1,35 @@
+## automatically generated CMT requirements file
+package HepMCWeightSvc
+author  will
+
+## for athena policies: this has to be the first use statement
+use AtlasPolicy 	AtlasPolicy-*
+
+## for gaudi tools, services and objects
+use GaudiInterface 	GaudiInterface-* 	External
+
+private
+use EventInfo         EventInfo-*         Event
+use AthenaBaseComps AthenaBaseComps-* Control
+use IOVDbMetaDataTools IOVDbMetaDataTools-* Database
+use AthenaPoolUtilities AthenaPoolUtilities-* Database/AthenaPOOL
+use IOVDbDataModel IOVDbDataModel-* Database
+end_private
+
+## put here your package dependencies...
+
+##
+
+branches src src/components doc python share
+
+private
+## default is to make component library
+library HepMCWeightSvc *.cxx components/*.cxx
+
+apply_pattern component_library
+apply_pattern declare_joboptions files="*.py"
+apply_pattern declare_python_modules files="*.py"
+
+end_private
+
+
diff --git a/Generators/HepMCWeightSvc/src/HepMCWeightSvc.cxx b/Generators/HepMCWeightSvc/src/HepMCWeightSvc.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..192fc330cb454e076eb55e42253b06965cd679bf
--- /dev/null
+++ b/Generators/HepMCWeightSvc/src/HepMCWeightSvc.cxx
@@ -0,0 +1,169 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "HepMCWeightSvc.h"
+
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventType.h"
+#include "EventInfo/EventID.h"
+#include "EventInfo/EventStreamInfo.h"
+
+#include "IOVDbDataModel/IOVMetaDataContainer.h"
+
+HepMCWeightSvc::HepMCWeightSvc(const std::string& name, ISvcLocator* pSvcLocator)
+  : AthService(name, pSvcLocator),
+   m_metaDataTool("IOVDbMetaDataTool"),m_weightNamesLoaded(false)
+{
+
+}
+
+
+bool HepMCWeightSvc::weightNamesChanged(const std::map<std::string, std::size_t>& weightNames) {
+   
+   //check all weights are the same 
+   if(m_currentWeightNames.size() != weightNames.size()) {
+      return true;
+   }
+   auto itr1 = m_currentWeightNames.begin();
+   auto itr2 = weightNames.begin();
+
+   for(;itr1!=m_currentWeightNames.end();++itr1,++itr2) {
+      if( itr1->first != itr2->first ) return true;
+      if( itr1->second != itr2->second ) return true;
+   }
+   return false;
+}
+
+StatusCode HepMCWeightSvc::initialize() {
+   ServiceHandle<IIncidentSvc> incsvc("IncidentSvc",name());
+   int priority = 100;
+   incsvc->addListener( this, IncidentType::BeginInputFile, priority);
+   return StatusCode::SUCCESS;
+}
+
+void HepMCWeightSvc::handle(const Incident& inc) {
+   if(inc.type()==IncidentType::BeginInputFile) { //resets the weight names
+      m_weightNamesLoaded = false; 
+      m_currentWeightNames.clear();
+   }
+}
+
+StatusCode HepMCWeightSvc::loadWeights() {
+   //clear the currentWeightNames 
+   m_currentWeightNames.clear();
+   m_weightNamesLoaded = true; //regardless of success or failure, we will say the weights are loaded!
+
+   //read the weight map from the metadata, it will be std::map<std::string,int> so we need to convert to our internal type 
+   ServiceHandle<StoreGateSvc> inputMetaStore("StoreGateSvc/InputMetaDataStore",name());
+   CHECK( inputMetaStore.retrieve() );
+   
+   const IOVMetaDataContainer* cont = 0;
+   if(inputMetaStore->retrieve(cont,"/Generation/Parameters").isFailure()) {
+     //exit quietly... 
+     return StatusCode::SUCCESS;
+   }
+   //payload is a collection of condattrlistcollections
+   //only look a the first one, assuming it exists, and within that only look at the first channel;
+   if(! (cont->payloadContainer()->size()>0 && cont->payloadContainer()->at(0)->size()>0) ) return StatusCode::FAILURE;
+
+   //need to retrieve the EventStreamInfo to get at the channel number 
+   const EventStreamInfo* esi = 0;
+   CHECK( inputMetaStore->retrieve(esi) );
+   if(esi->getEventTypes().size() == 0) return StatusCode::FAILURE;
+   int chanNum = esi->getEventTypes().begin()->mc_channel_number();
+   if(chanNum==0) {
+      //perhaps channel number not set yet, use the first run number instead 
+      if(esi->getRunNumbers().size()==0) return StatusCode::FAILURE;
+      chanNum = *esi->getRunNumbers().begin();
+   }
+   const coral::Attribute& attr = cont->payloadContainer()->at(0)->attributeList(chanNum)["HepMCWeightNames"];
+
+   std::map<std::string, int> in; 
+
+   CHECK( Gaudi::Parsers::parse(in,attr.data<std::string>()) );
+
+   ATH_MSG_DEBUG("Loaded weightnames: " << attr.data<std::string>());
+
+   
+   for(auto& i : in) m_currentWeightNames[i.first] = i.second;
+
+
+
+   return StatusCode::SUCCESS;
+
+
+}
+
+StatusCode HepMCWeightSvc::setWeightNames(const std::map<std::string, std::size_t>& weightNames) {
+
+   //ignore any attempt to set 'nothing' for the weight names
+   if(weightNames.size()==0 || (weightNames.size()==1 && weightNames.begin()->first=="0") ) return StatusCode::SUCCESS;
+
+   if(m_weightNamesLoaded) return StatusCode::SUCCESS; //we only allow setting of weightNames ONCE! ... if the weights have ever been loaded, we will not allow them to be set again!
+   //effectively means the weights are only set in evgen jobs.
+
+   //check that the weight names correspond to what we have currently. 
+   //if( weightNamesChanged(weightNames) ) {
+      m_currentWeightNames = weightNames;
+
+      //create and register the metadata containter with these weight names 
+      //use the MetaDataTool to do this 
+      CHECK( m_metaDataTool->registerFolder("/Generation/Parameters","Metadata created during Event Generation") );
+
+      //create a new attributelist collection for it ...
+      CondAttrListCollection* cont = new CondAttrListCollection(true /* use regular timestamps, not run-lumiblock timestamps */);
+      //create a single attribute list
+      CondAttrListCollection::AttributeList  myAttributes;
+
+      //store as strings ... when read back in we use a gaudi parser to parse the list
+      myAttributes.extend("HepMCWeightNames","string");
+      
+      std::string stringToStore = "{";
+      for(auto& name : weightNames) {
+         if(stringToStore != "{") stringToStore += ", ";
+         std::stringstream ss;
+         ss << "'" << name.first << "':" << name.second; stringToStore += ss.str();
+      }
+      stringToStore += "}";
+      myAttributes["HepMCWeightNames"].data<std::string>() = stringToStore;
+
+      //use the run-number as the 'channel' ... all weightnames should be the same for the same channel 
+
+      //set the start time ... do we set the stop time?  
+      const EventInfo* evt = 0;
+      ServiceHandle<StoreGateSvc> evtStore("StoreGateSvc/StoreGateSvc",name());
+      CHECK( evtStore->retrieve(evt) );
+      //IOVTime evtTime;
+      //evtTime.setRunEvent(evt->event_ID()->run_number(), evt->event_ID()->lumi_block());
+      //uint64_t nsTime=evt->event_ID()->time_stamp()*1000000000LL;
+      //nsTime += evt->event_ID()->time_stamp_ns_offset();
+      //evtTime.setTimestamp(nsTime);
+      //cont->addNewStart(evtTime);
+      cont->add(evt->event_ID()->run_number(),myAttributes);
+
+
+
+      ATH_MSG_INFO("Storing /Generation/Parameters :: WeightNames = " << stringToStore);
+
+      //and assign it to 'channel 0' .. consistent with other metadata
+      
+      CHECK( m_metaDataTool->addPayload("/Generation/Parameters",cont) );
+
+      m_weightNamesLoaded=true;
+
+   //}
+
+   return StatusCode::SUCCESS;
+}
+
+
+const std::map<std::string,std::size_t>& HepMCWeightSvc::weightNames() {
+   if(!m_weightNamesLoaded) {
+      if(loadWeights().isFailure()) { ATH_MSG_WARNING("Unable to load weightnames from metadata ... do not trust the weightnames!"); }
+   }
+   return m_currentWeightNames;
+}
diff --git a/Generators/HepMCWeightSvc/src/HepMCWeightSvc.h b/Generators/HepMCWeightSvc/src/HepMCWeightSvc.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4a6da6013248739f87543c4cc81d015d3145146
--- /dev/null
+++ b/Generators/HepMCWeightSvc/src/HepMCWeightSvc.h
@@ -0,0 +1,65 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef EVGENPRODTOOLS_HEPMCWEIGHTSVC_H
+#define EVGENPRODTOOLS_HEPMCWEIGHTSVC_H
+
+#include "AthenaBaseComps/AthService.h"
+#include "HepMCWeightSvc/IHepMCWeightSvc.h"
+#include <string>
+
+#include "IOVDbMetaDataTools/IIOVDbMetaDataTool.h"
+
+#include "GaudiKernel/IIncidentListener.h"
+#include "GaudiKernel/IIncidentSvc.h"
+
+#include "GaudiKernel/ToolHandle.h"
+
+/// @brief Service to read/write HepMC's WeightContainer key names from/to IOVMetaDataContainers
+///  author: will buttinger , NLAA
+/// 
+///
+class HepMCWeightSvc : public AthService , public IHepMCWeightSvc, virtual public IIncidentListener  {
+public:
+
+
+
+  // Constructor and destructor
+  HepMCWeightSvc(const std::string& name, ISvcLocator* pSvcLocator);
+
+  ~HepMCWeightSvc() {;}
+
+  ///checks for any changes to weightnames ... none are allowed. Then records to metadata
+  virtual StatusCode setWeightNames(const std::map<std::string, std::size_t>& weightNames);
+
+   ///returns the current weight names ... will only change at file boudaries, it is assumed all events in a given file will have same weights in SAME ORDER
+   virtual const std::map<std::string, std::size_t>& weightNames();
+
+
+   virtual StatusCode initialize();
+
+   virtual void handle(const Incident& inc); //listen for beginInputFile and load the weights at that point 
+
+  StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface) {
+      if(IID_IHepMCWeightSvc == riid) {
+         *ppvInterface = dynamic_cast<IHepMCWeightSvc*>(this);
+         return StatusCode::SUCCESS;
+      }
+      return AthService::queryInterface(riid,ppvInterface);
+   }
+
+private:
+   bool weightNamesChanged(const std::map<std::string, std::size_t>& weightNames);
+
+   StatusCode loadWeights(); //reads from the IOVMetaData
+
+   std::map<std::string, std::size_t> m_currentWeightNames;
+
+   ToolHandle<IIOVDbMetaDataTool> m_metaDataTool;
+
+   bool m_weightNamesLoaded;
+
+};
+
+#endif
diff --git a/Generators/HepMCWeightSvc/src/components/HepMCWeightSvc_entries.cxx b/Generators/HepMCWeightSvc/src/components/HepMCWeightSvc_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..18dfea8a06c2e59c454fc87e7b71361e256d3ed3
--- /dev/null
+++ b/Generators/HepMCWeightSvc/src/components/HepMCWeightSvc_entries.cxx
@@ -0,0 +1,8 @@
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+#include "../HepMCWeightSvc.h"
+DECLARE_SERVICE_FACTORY(HepMCWeightSvc)
+
+DECLARE_FACTORY_ENTRIES( HepMCWeightSvc ) {
+  DECLARE_SERVICE(HepMCWeightSvc)
+}
diff --git a/Generators/HepMCWeightSvc/src/components/HepMCWeightSvc_load.cxx b/Generators/HepMCWeightSvc/src/components/HepMCWeightSvc_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..573c3c5a41d8531f40697f2d820d2be8dcbbe19e
--- /dev/null
+++ b/Generators/HepMCWeightSvc/src/components/HepMCWeightSvc_load.cxx
@@ -0,0 +1,3 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(HepMCWeightSvc)