diff --git a/Service/EventSeeder/CMakeLists.txt b/Service/EventSeeder/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8bf504d85fbab7043e0fcd82e7b45043fc9b7347
--- /dev/null
+++ b/Service/EventSeeder/CMakeLists.txt
@@ -0,0 +1,14 @@
+gaudi_subdir(EventSeeder v0r0)
+
+#find_package(GEAR REQUIRED)
+
+set(EventSeeder_srcs
+    src/*.cpp
+)
+
+gaudi_install_headers(EventSeeder)
+
+gaudi_add_module(EventSeeder ${EventSeeder_srcs}
+    INCLUDE_DIRS GaudiKernel
+    LINK_LIBRARIES GaudiKernel
+)
diff --git a/Service/EventSeeder/EventSeeder/IEventSeeder.h b/Service/EventSeeder/EventSeeder/IEventSeeder.h
new file mode 100644
index 0000000000000000000000000000000000000000..20365853bbddea35304d7b8937d3a9c9c04847e9
--- /dev/null
+++ b/Service/EventSeeder/EventSeeder/IEventSeeder.h
@@ -0,0 +1,21 @@
+#ifndef I_EVENT_SEEDER_H
+#define I_EVENT_SEEDER_H
+
+#include "GaudiKernel/IService.h"
+
+class Algorithm;
+
+class IEventSeeder: virtual public IService {
+public:
+    DeclareInterfaceID(IEventSeeder, 0, 1); // major/minor version
+    
+    virtual ~IEventSeeder() = default;
+
+    // Register an algorithm for the seeding service
+    virtual void registerAlg( Algorithm* alg ) = 0;
+
+    // Get the seed corelated to current event and algorithm
+    virtual unsigned int getSeed(Algorithm* alg, int eventNumber, int runNumber) = 0;
+};
+
+#endif
diff --git a/Service/EventSeeder/README.md b/Service/EventSeeder/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..79d3d8e72ee35defe3dcfd8e83a79770183ca3ed
--- /dev/null
+++ b/Service/EventSeeder/README.md
@@ -0,0 +1,5 @@
+# EventSeeder
+
+This package is used to provide independent pseudo-randomly generated seeds for registered algorithms on an event by event basis.
+
+Currently the only implementation, MarlinEvtSeeder, is migrated from marlin::ProcessorEventSeeder. Please refer to https://github.com/iLCSoft/Marlin
diff --git a/Service/EventSeeder/src/MarlinEvtSeeder.cpp b/Service/EventSeeder/src/MarlinEvtSeeder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7acfdadf00ea47e20a83a3a4d21422d0d8741f0
--- /dev/null
+++ b/Service/EventSeeder/src/MarlinEvtSeeder.cpp
@@ -0,0 +1,82 @@
+#include "MarlinEvtSeeder.h"
+#include "jenkinsHash.h"
+#include "GaudiKernel/Algorithm.h"
+
+#include <stdlib.h>
+#include <limits>
+#include <algorithm>
+
+DECLARE_COMPONENT(MarlinEvtSeeder)
+
+MarlinEvtSeeder::MarlinEvtSeeder(const std::string& name, ISvcLocator* svc) 
+  : base_class(name, svc),
+    _evtNo(-1),
+    _runNo(-1)
+{
+} 
+
+void MarlinEvtSeeder::registerAlg ( Algorithm* alg )
+{
+  srand( _globalSeed );
+  debug() << "initialised with global seed " << _globalSeed << endmsg; 
+
+  _vAlgSeed.push_back( std::make_pair( alg, rand() ) );
+  debug() << alg->name() << "registered for random seed service. Allocated "
+          <<  _vAlgSeed.back().second << " as initial seed."
+          << endmsg; 
+}
+
+void MarlinEvtSeeder::refreshSeeds()
+{
+  // get hashed seed using jenkins_hash
+  unsigned int seed = 0 ; // initial state
+  unsigned int eventNumber = _evtNo;  //evt->getEventNumber() ;
+  unsigned int runNumber = _runNo;  //evt->getRunNumber() ;
+
+  unsigned char * c = (unsigned char *) &eventNumber ;
+  seed = jenkins_hash( c, sizeof eventNumber, seed) ;
+
+  c = (unsigned char *) &runNumber ;
+  seed = jenkins_hash( c, sizeof runNumber, seed) ;
+
+  int _global_seed = _globalSeed;
+  c = (unsigned char *) &_global_seed ;
+  seed = jenkins_hash( c, sizeof _global_seed, seed) ;
+
+  // set the seed for rand() for this event
+  if ( seed == 1 ) seed = 123456789 ; // can't used a seed value of 1 as srand(1) sets rand() back the state of the last call to srand( seed ).
+
+  debug() << "MarlinEvtSeeder: Refresh Seeds using " << seed << " as seed for srand( seed )" << endmsg; 
+  srand( seed );
+
+  // fill vector with seeds for each registered processor using rand() 
+  for( auto& iAlgSeed : _vAlgSeed ) 
+  {
+    iAlgSeed.second = rand();
+  }
+}
+
+unsigned int MarlinEvtSeeder::getSeed(Algorithm* alg, int eventNumber, int runNumber)
+{
+  if ( eventNumber != _evtNo || runNumber != _runNo ) {
+    _evtNo = eventNumber;
+    _runNo = runNumber;
+    refreshSeeds();
+  }
+
+  typedef std::pair<Algorithm*, unsigned int> Pair;
+
+  auto it = find_if( _vAlgSeed.begin(), _vAlgSeed.end(), [&](Pair const& pair){ return pair.first == alg;  }  );
+
+  return ( it != _vAlgSeed.end() ? it->second : throw  ) ;
+}
+
+StatusCode MarlinEvtSeeder::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+StatusCode MarlinEvtSeeder::finalize()
+{
+  return StatusCode::SUCCESS;
+}
diff --git a/Service/EventSeeder/src/MarlinEvtSeeder.h b/Service/EventSeeder/src/MarlinEvtSeeder.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed4a5d6ed2e10b9d8b25df1788654e742ed2e16b
--- /dev/null
+++ b/Service/EventSeeder/src/MarlinEvtSeeder.h
@@ -0,0 +1,86 @@
+#ifndef MARLIN_EVT_SEEDER_H
+#define MARLIN_EVT_SEEDER_H 1
+
+#include "EventSeeder/IEventSeeder.h"
+#include <GaudiKernel/Service.h>
+#include <vector>
+#include <map>
+
+/** Processor event seeder - provides independent pseudo-randomly generated seeds 
+ *  for registered processors on an event by event basis.   
+ * 
+ *      This Class is used to provide individual pseudo-random numbers to Processors on
+ *      an event-by-event and run-by-run basis. These may be used by Processors to 
+ *	  seed their random number generator of choice. In order to use this service 
+ *	  a Processor must register itself in the init method using:
+ *
+ *             Global::EVENTSEEDER->registerProcessor(this);
+ *
+ *      and should retrieve its allocated event seed during processEvent using:
+ *
+ *             int eventSeed = Global::EVENTSEEDER->getSeed(this);
+ *
+ *	  and include the header file:
+ *
+ *	  	#include "marlin/ProcessorEventSeeder.h"	      	
+ *
+ *      The global seed is used for a complete job and is set in the Global steering parameters thus:
+ *     
+ *             <parameter name="RandomSeed" value="1234567890"/>
+ *
+ *      Note that the value must be a positive integer, with max value 2,147,483,647
+ *      A pseudo-random event seed is generated using a three step hashing function of unsigned ints,
+ *	  in the following order: event_number, run_number, RandomSeed. The hashed int from each step 
+ *	  in the above order is used as input to the next hash step. This is used to ensure that in 
+ *	  the likely event of similar values of event_number, run_number and RandomSeed, different 
+ *	  event seeds will be generated. 
+ *    
+ *	  The event seed is then used to seed rand via srand(seed) and then rand is used to 
+ *	  generate one seed per registered processor.
+ *
+ *	  This mechanism ensures reproducible results for every event, regardless of the sequence 
+ *	  in which the event is processed in a Marlin job, whilst maintaining the full 32bit range 
+ *	  for event and run numbers.
+ *   
+ *      If a call is made to getSeed( Processor* ) preceededing a call to registerProcessor( Processor* )
+ *      an exception will be thrown.
+ *
+ *  @author S.J. Aplin, DESY
+ */
+
+class MarlinEvtSeeder : public extends<Service, IEventSeeder>
+{
+  public:
+
+    /** Constructor and Destructor */
+    MarlinEvtSeeder(const std::string& name, ISvcLocator* svc);
+    ~MarlinEvtSeeder() { } ;
+
+    /** Called by Algorithms to register themselves for the seeding service. 
+    */
+    void registerAlg( Algorithm* alg ) override;
+
+    /** Called by Algorithms to obtain seed assigned to it for the current event.
+    */
+    unsigned int getSeed(Algorithm* alg, int eventNumber, int runNumber) override;
+
+    StatusCode initialize() override;
+    StatusCode finalize() override;
+
+  private:
+
+    void refreshSeeds();
+
+    int _evtNo;
+    int _runNo;
+
+    /** Global seed for current Job. Set in steering file.
+    */
+    Gaudi::Property<int> _globalSeed{this, "RandomSeed", 0};
+
+    /** Vector to hold pair of pointers to the registered processors and their assigned seeds
+    */
+    std::vector< std::pair<Algorithm*, unsigned int> > _vAlgSeed;
+} ;
+
+#endif
diff --git a/Service/EventSeeder/src/jenkinsHash.h b/Service/EventSeeder/src/jenkinsHash.h
new file mode 100644
index 0000000000000000000000000000000000000000..19b5722044a4af33f82d11fca28f785c1ff289e7
--- /dev/null
+++ b/Service/EventSeeder/src/jenkinsHash.h
@@ -0,0 +1,131 @@
+#ifndef JENKINSHASH_INCLUDED
+#define JENKINSHASH_INCLUDED
+
+/*
+
+Original source by Bob Jenkins
+
+http://www.burtleburtle.net/bob/hash/doobs.html
+
+Hash a variable-length key into a 32-bit value
+
+*/
+
+#define hashsize(n) ( 1U << (n) )
+#define hashmask(n) ( hashsize ( n ) - 1 )
+
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bits set, and the deltas of all three
+  high bits or all three low bits, whether the original value of a,b,c
+  is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+  have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+  2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a 
+  structure that could supported 2x parallelism, like so:
+      a -= b; 
+      a -= c; x = (c>>13);
+      b -= c; a ^= x;
+      b -= a; x = (a<<8);
+      c -= a; b ^= x;
+      c -= b; x = (b>>13);
+      ...
+  Unfortunately, superscalar Pentiums and Sparcs can't take advantage 
+  of that parallelism.  They've also turned some of those single-cycle
+  latency instructions into multi-cycle latency instructions.  Still,
+  this is the fastest good hash I could find.  There were about 2^^68
+  to choose from.  I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+  a -= b; a -= c; a ^= (c>>13); \
+  b -= c; b -= a; b ^= (a<<8); \
+  c -= a; c -= b; c ^= (b>>13); \
+  a -= b; a -= c; a ^= (c>>12);  \
+  b -= c; b -= a; b ^= (a<<16); \
+  c -= a; c -= b; c ^= (b>>5); \
+  a -= b; a -= c; a ^= (c>>3);  \
+  b -= c; b -= a; b ^= (a<<10); \
+  c -= a; c -= b; c ^= (b>>15); \
+}
+
+/*
+--------------------------------------------------------------------
+jenkins_hash() -- hash a variable-length key into a 32-bit value
+  k       : the key (the unaligned variable-length array of bytes)
+  len     : the length of the key, counting by bytes
+  initval : can be any 4-byte value
+Returns a 32-bit value.  Every bit of the key affects every bit of
+the return value.  Every 1-bit and 2-bit delta achieves avalanche.
+About 6*len+35 instructions.
+
+The best hash table sizes are powers of 2.  There is no need to do
+mod a prime (mod is sooo slow!).  If you need less than 32 bits,
+use a bitmask.  For example, if you need only 10 bits, do
+  h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+  for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
+
+By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use this
+code any way you wish, private, educational, or commercial.  It's free.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^^32 is
+acceptable.  Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+unsigned jenkins_hash ( unsigned char *k, unsigned length, unsigned initval )
+{
+  unsigned a, b;
+  unsigned c = initval;
+  unsigned len = length;
+ 
+  a = b = 0x9e3779b9;
+  
+  while ( len >= 12 ) {
+    a += ( k[0] + ( (unsigned)k[1] << 8 ) 
+	   + ( (unsigned)k[2] << 16 )
+	   + ( (unsigned)k[3] << 24 ) );
+    b += ( k[4] + ( (unsigned)k[5] << 8 ) 
+	   + ( (unsigned)k[6] << 16 )
+	   + ( (unsigned)k[7] << 24 ) );
+    c += ( k[8] + ( (unsigned)k[9] << 8 ) 
+	   + ( (unsigned)k[10] << 16 )
+	   + ( (unsigned)k[11] << 24 ) );
+    
+    mix ( a, b, c );
+    
+    k += 12;
+    len -= 12;
+  }
+  
+  c += length;
+  
+  switch ( len ) {
+  case 11: c += ( (unsigned)k[10] << 24 );
+  case 10: c += ( (unsigned)k[9] << 16 );
+  case 9 : c += ( (unsigned)k[8] << 8 );
+    /* First byte of c reserved for length */
+  case 8 : b += ( (unsigned)k[7] << 24 );
+  case 7 : b += ( (unsigned)k[6] << 16 );
+  case 6 : b += ( (unsigned)k[5] << 8 );
+  case 5 : b += k[4];
+  case 4 : a += ( (unsigned)k[3] << 24 );
+  case 3 : a += ( (unsigned)k[2] << 16 );
+  case 2 : a += ( (unsigned)k[1] << 8 );
+  case 1 : a += k[0];
+  }
+  
+  mix ( a, b, c );
+  
+  return c;
+}
+
+#endif
diff --git a/Service/GearSvc/CMakeLists.txt b/Service/GearSvc/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f78d581ad47f95e7a74ffb61883c152cceffca7e
--- /dev/null
+++ b/Service/GearSvc/CMakeLists.txt
@@ -0,0 +1,14 @@
+gaudi_subdir(GearSvc v0r0)
+
+find_package(GEAR REQUIRED)
+
+set(GearSvc_srcs
+    src/*.cpp
+)
+
+gaudi_install_headers(GearSvc)
+
+gaudi_add_module(GearSvc ${GearSvc_srcs}
+    INCLUDE_DIRS GaudiKernel gear
+    LINK_LIBRARIES GaudiKernel $ENV{GEAR}/lib/libgear.so $ENV{GEAR}/lib/libgearxml.so
+)
diff --git a/Service/GearSvc/GearSvc/IGearSvc.h b/Service/GearSvc/GearSvc/IGearSvc.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6f4dff77430c960237b7cfdd62a4e16430d2029
--- /dev/null
+++ b/Service/GearSvc/GearSvc/IGearSvc.h
@@ -0,0 +1,21 @@
+#ifndef I_GEAR_SVC_H
+#define I_GEAR_SVC_H
+
+#include "GaudiKernel/IService.h"
+#include "gear/GearMgr.h"
+
+// IGearSvc is the interface between Gaudi and GEAR.
+
+class IGearSvc: virtual public IService {
+public:
+    DeclareInterfaceID(IGearSvc, 0, 1); // major/minor version
+    
+    virtual ~IGearSvc() = default;
+
+    // Get the GEAR Manager
+    virtual gear::GearMgr* getGearMgr() = 0;
+
+};
+
+
+#endif
diff --git a/Service/GearSvc/src/GearSvc.cpp b/Service/GearSvc/src/GearSvc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7aafb84e56cc3c121826cf752582d77453a31d9c
--- /dev/null
+++ b/Service/GearSvc/src/GearSvc.cpp
@@ -0,0 +1,44 @@
+#include "GearSvc.h"
+#include "gearxml/GearXML.h"
+#include "gearimpl/GearMgrImpl.h"
+
+DECLARE_COMPONENT(GearSvc)
+
+GearSvc::GearSvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc),
+      m_gearMgr(nullptr)
+{
+}
+
+GearSvc::~GearSvc()
+{
+}
+
+gear::GearMgr* GearSvc::getGearMgr()
+{
+    return m_gearMgr;
+}
+
+StatusCode GearSvc::initialize()
+{
+    if ( m_gearFile.size() > 0 ) {
+        info() << "instantiated GEAR from file " << m_gearFile << endmsg;
+        m_gearMgr = gear::GearXML(m_gearFile).createGearMgr();
+    }
+    else {
+        warning() << "no GEAR XML file given ..." << endmsg;
+        m_gearMgr = new gear::GearMgrImpl;
+    }
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode GearSvc::finalize()
+{
+    if ( m_gearMgr ) {
+        delete m_gearMgr;
+        m_gearMgr = nullptr;
+    }
+
+    return StatusCode::SUCCESS;
+}
diff --git a/Service/GearSvc/src/GearSvc.h b/Service/GearSvc/src/GearSvc.h
new file mode 100644
index 0000000000000000000000000000000000000000..00a8045834baba425c732aab2bf754313d01f663
--- /dev/null
+++ b/Service/GearSvc/src/GearSvc.h
@@ -0,0 +1,25 @@
+#ifndef GEAR_SVC_H
+#define GEAR_SVC_H
+
+#include "GearSvc/IGearSvc.h"
+#include <GaudiKernel/Service.h>
+
+class GearSvc : public extends<Service, IGearSvc>
+{
+    public:
+        GearSvc(const std::string& name, ISvcLocator* svc);
+        ~GearSvc();
+
+        gear::GearMgr* getGearMgr() override;
+
+        StatusCode initialize() override;
+        StatusCode finalize() override;
+
+    private:
+
+        Gaudi::Property<std::string> m_gearFile{this, "GearXMLFile", ""};
+
+        gear::GearMgr* m_gearMgr;
+};
+
+#endif