diff --git a/xAOD/xAODTruth/CMakeLists.txt b/xAOD/xAODTruth/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4d63992e69e11bb11f78d216565560daf12c584a
--- /dev/null
+++ b/xAOD/xAODTruth/CMakeLists.txt
@@ -0,0 +1,37 @@
+# $Id: CMakeLists.txt 761796 2016-07-14 08:06:02Z krasznaa $
+################################################################################
+# Package: xAODTruth
+################################################################################
+
+# Declare the package name:
+atlas_subdir( xAODTruth )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs(
+   PUBLIC
+   Control/AthContainers
+   Control/AthLinks
+   Event/xAOD/xAODBase
+   Event/xAOD/xAODCore
+   PRIVATE
+   Generators/TruthUtils )
+
+# Component(s) in the package:
+atlas_add_library( xAODTruth
+   xAODTruth/*.h xAODTruth/versions/*.h Root/*.h Root/*.cxx
+   PUBLIC_HEADERS xAODTruth
+   LINK_LIBRARIES AthContainers AthLinks xAODBase xAODCore
+   PRIVATE_LINK_LIBRARIES TruthUtils )
+
+atlas_add_dictionary( xAODTruthDict
+   xAODTruth/xAODTruthDict.h
+   xAODTruth/selection.xml
+   LINK_LIBRARIES xAODTruth
+   EXTRA_FILES Root/dict/*.cxx )
+
+atlas_generate_cliddb( xAODTruth )
+
+# Test(s) in the package:
+atlas_add_test( ut_xaodtruth_particle_test
+   SOURCES test/ut_xaodtruth_particle_test.cxx
+   LINK_LIBRARIES xAODTruth )
diff --git a/xAOD/xAODTruth/Root/TruthAccessors_v1.cxx b/xAOD/xAODTruth/Root/TruthAccessors_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1117f20d53901f2e30ae23d333cb70c86a3ed71e
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthAccessors_v1.cxx
@@ -0,0 +1,124 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthAccessors_v1.cxx 623284 2014-10-22 14:07:48Z krasznaa $
+
+// System include(s):
+#include <iostream>
+
+// Local include(s):
+#include "TruthAccessors_v1.h"
+
+/// Helper macro for managing cluster moment Accessor objects
+#define DEFINE_ACCESSOR( PARENT, TYPE, NAME )                \
+   case PARENT::NAME:                                        \
+      {                                                      \
+         static SG::AuxElement::Accessor< TYPE > a( #NAME ); \
+         return &a;                                          \
+      }                                                      \
+      break
+
+namespace xAOD {
+
+   SG::AuxElement::Accessor< float >*
+   polarizationAccessorV1( TruthParticle_v1::PolParam type ) {
+
+      switch( type ) {
+
+         DEFINE_ACCESSOR( TruthParticle_v1, float, polarizationTheta );
+         DEFINE_ACCESSOR( TruthParticle_v1, float, polarizationPhi );
+
+      default:
+         std::cerr << "xAOD::polarizationAccessorV1 ERROR Unknown PolParam ("
+                   << type << ") requested" << std::endl;
+         return 0;
+      }
+
+      return 0;
+   }
+
+   SG::AuxElement::Accessor< int >*
+   pdfInfoAccessorV1Int( TruthEvent_v1::PdfParam type ) {
+
+      switch( type ) {
+
+         DEFINE_ACCESSOR( TruthEvent_v1, int, PDGID1 );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, PDGID2 );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, PDFID1 );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, PDFID2 );
+
+      default:
+         std::cerr << "xAOD::pdfInfoAccessorV1Int ERROR Unknown PdfParam ("
+                   << type << ") requested" << std::endl;
+         return 0;
+      }
+
+      return 0;
+   }
+
+   SG::AuxElement::Accessor< float >*
+   pdfInfoAccessorV1Float( TruthEvent_v1::PdfParam type ) {
+
+      switch( type ) {
+
+         DEFINE_ACCESSOR( TruthEvent_v1, float, X1 );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, X2 );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, Q );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, XF1 );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, XF2 );
+
+      default:
+         std::cerr << "xAOD::pdfInfoAccessorV1Float ERROR Unknown ParamDef ("
+                   << type << ") requested" << std::endl;
+         return 0;
+      }
+
+      return 0;
+   }
+
+   SG::AuxElement::Accessor< int >*
+   heavyIonAccessorV1Int( TruthEvent_v1::HIParam type ) {
+
+      switch( type ) {
+
+         DEFINE_ACCESSOR( TruthEvent_v1, int, NCOLLHARD );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, NPARTPROJ );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, NPARTTARG );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, NCOLL );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, SPECTATORNEUTRONS );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, SPECTATORPROTONS );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, NNWOUNDEDCOLLISIONS );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, NWOUNDEDNCOLLISIONS );
+         DEFINE_ACCESSOR( TruthEvent_v1, int, NWOUNDEDNWOUNDEDCOLLISIONS );
+
+      default:
+         std::cerr << "xAOD::heavyIonAccessorV1Int ERROR Unknown HIParam ("
+                   << type << ") requested" << std::endl;
+         return 0;
+      }
+
+      return 0;
+   }
+
+   SG::AuxElement::Accessor< float >*
+   heavyIonAccessorV1Float( TruthEvent_v1::HIParam type ) {
+
+      switch( type ) {
+
+         DEFINE_ACCESSOR( TruthEvent_v1, float, IMPACTPARAMETER );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, EVENTPLANEANGLE );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, ECCENTRICITY );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, SIGMAINELNN );
+         DEFINE_ACCESSOR( TruthEvent_v1, float, CENTRALITY );
+
+      default:
+         std::cerr << "xAOD::heavyIonAccessorV1Float ERROR Unknown HIParam ("
+                   << type << ") requested" << std::endl;
+         return 0;
+      }
+
+      return 0;
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/TruthAccessors_v1.h b/xAOD/xAODTruth/Root/TruthAccessors_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..04d3a7d30b0bb469111ea04e44ca121db98a1faa
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthAccessors_v1.h
@@ -0,0 +1,44 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthAccessors_v1.h 623284 2014-10-22 14:07:48Z krasznaa $
+#ifndef XAODTRUTH_TRUTHACCESSORS_V1_H
+#define XAODTRUTH_TRUTHACCESSORS_V1_H
+
+// EDM include(s):
+#include "AthContainers/AuxElement.h"
+
+// Local include(s):
+#include "xAODTruth/TruthEvent.h"
+#include "xAODTruth/TruthParticle.h"
+
+namespace xAOD {
+
+   /// This function holds on to Accessor objects that can be used by each
+   /// TruthParticle_v1 object at runtime to get/set parameter values on
+   /// themselves.
+   SG::AuxElement::Accessor< float >*
+   polarizationAccessorV1( TruthParticle_v1::PolParam type );
+
+   /// Helper function for getting accessors for integer type PDF information
+   SG::AuxElement::Accessor< int >*
+   pdfInfoAccessorV1Int( TruthEvent_v1::PdfParam type );
+
+   /// Helper function for getting accessors for floating point PDF information
+   SG::AuxElement::Accessor< float >*
+   pdfInfoAccessorV1Float( TruthEvent_v1::PdfParam type );
+
+   /// Helper function for getting accessors for integer type HI information
+   SG::AuxElement::Accessor< int >*
+   heavyIonAccessorV1Int( TruthEvent_v1::HIParam type );
+
+   /// Helper function for getting accessors for floating point HI information
+   SG::AuxElement::Accessor< float >*
+   heavyIonAccessorV1Float( TruthEvent_v1::HIParam type );
+
+} // namespace xAOD
+
+#endif // XAODTRUTH_TRUTHACCESSORS_V1_H
diff --git a/xAOD/xAODTruth/Root/TruthEvent.cxx b/xAOD/xAODTruth/Root/TruthEvent.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f037380f3df5c7156fde83266bdd977c49d3e3e4
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthEvent.cxx
@@ -0,0 +1,338 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthEvent.cxx 761798 2016-07-14 08:15:01Z krasznaa $
+
+// System include(s):
+#include <cmath>
+
+// EDM include(s):
+#include "xAODCore/AuxStoreAccessorMacros.h"
+
+// Local include(s):
+#include "xAODTruth/TruthEvent.h"
+#include "TruthAccessors.h"
+
+namespace xAOD {
+
+
+   TruthEvent::TruthEvent()
+      : SG::AuxElement() {
+
+   }
+   
+   /////////////////////////////////////////////////////////////////////////////
+   // Implementation of the truth particle accessor functions
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent,
+                                      TruthEvent::TruthParticleLinks_t,
+                                      truthParticleLinks,
+                                      setTruthParticleLinks )
+
+   /// Accessor for the truth particles
+   static SG::AuxElement::Accessor< TruthEvent::TruthParticleLinks_t >
+      truthParticleLinksAcc( "truthParticleLinks" );
+
+   size_t TruthEvent::nTruthParticles() const {
+
+      // If the variable is not available, we don't have any truth particles
+      // associated...
+      if( ! truthParticleLinksAcc.isAvailable( *this ) ) {
+         return 0;
+      }
+
+      // Return the size of the vector:
+      return truthParticleLinksAcc( *this ).size();
+   }
+
+   const TruthEvent::TruthParticleLink_t&
+   TruthEvent::truthParticleLink( size_t index ) const {
+
+      return truthParticleLinksAcc( *this ).at( index );
+   }
+
+   const TruthParticle* TruthEvent::truthParticle( size_t index ) const {
+
+      // Check if the variable is available:
+      if( ! truthParticleLinksAcc.isAvailable( *this ) ) {
+         return 0;
+      }
+
+      // Check if the link is valid:
+      const TruthParticleLinks_t& links = truthParticleLinksAcc( *this );
+      if( ! links[ index ].isValid() ) {
+         return 0;
+      }
+
+      // Return the de-referenced link:
+      return *( links[ index ] );
+   }
+
+   void
+   TruthEvent::addTruthParticleLink( const TruthParticleLink_t& link ) {
+
+      truthParticleLinksAcc( *this ).push_back( link );
+      return;
+   }
+
+   void TruthEvent::clearTruthParticleLinks() {
+
+      truthParticleLinksAcc( *this ).clear();
+      return;
+   }
+
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   // Implementation of the truth vertex accessor functions
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent,
+                                      TruthEvent::TruthVertexLinks_t,
+                                      truthVertexLinks,
+                                      setTruthVertexLinks )
+
+   /// Accessor for the truth vertices
+   static SG::AuxElement::Accessor< TruthEvent::TruthVertexLinks_t >
+      truthVertexLinksAcc( "truthVertexLinks" );
+
+   size_t TruthEvent::nTruthVertices() const {
+
+      // If the variable is not available, we don't have any truth particles
+      // associated...
+      if( ! truthVertexLinksAcc.isAvailable( *this ) ) {
+         return 0;
+      }
+
+      // Return the size of the vector:
+      return truthVertexLinksAcc( *this ).size();
+   }
+
+   const TruthEvent::TruthVertexLink_t&
+   TruthEvent::truthVertexLink( size_t index ) const {
+
+      return truthVertexLinksAcc( *this ).at(index);
+   }
+
+   const TruthVertex* TruthEvent::truthVertex( size_t index ) const {
+
+      // Check if the variable is available:
+      if( ! truthVertexLinksAcc.isAvailable( *this ) ) {
+         return 0;
+      }
+
+      // Check if the link is valid:
+      const TruthVertexLinks_t& links = truthVertexLinksAcc( *this );
+      if( ! links[ index ].isValid() ) {
+         return 0;
+      }
+
+      // Return the de-referenced link:
+      return *( links[ index ] );
+   }
+
+   void TruthEvent::addTruthVertexLink( const TruthVertexLink_t& link ) {
+
+      truthVertexLinksAcc( *this ).push_back( link );
+      return;
+   }
+
+   void TruthEvent::clearTruthVertexLinks() {
+
+      truthVertexLinksAcc( *this ).clear();
+      return;
+   }
+
+   
+   /////////////////////////////////////////////////////////////////////////////
+   // Simple, always-present event properties
+
+   /// @todo Need upgrade to allow string-valued map-like access... or access a
+   /// corresponding vector of names
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent, std::vector< float >,
+                                      weights, setWeights )
+
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthEvent, float, crossSection,
+                                         setCrossSection )
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthEvent, float,
+                                         crossSectionError,
+                                         setCrossSectionError )
+
+   void TruthEvent::setCrossSection( float value, float error ) {
+
+      setCrossSection( value );
+      setCrossSectionError( error );
+      return;
+   }
+
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   // Optional PDF info accessors
+
+   bool TruthEvent::pdfInfoParameter( int& value,
+                                         PdfParam information ) const {
+
+      // Look for the accessor object:
+      auto* acc = pdfInfoAccessorV1Int( information );
+      if( ! acc ) return false;
+
+      // Get the value:
+      value = ( *acc )( *this );
+      return true;
+   }
+
+   bool TruthEvent::pdfInfoParameter( float& value,
+                                         PdfParam information ) const {
+
+      // Look for the accessor object:
+      auto* acc = pdfInfoAccessorV1Float( information );
+      if( ! acc ) return false;
+
+      // Get the value:
+      value = ( *acc )( *this );
+      return true;
+   }
+
+   bool TruthEvent::setPdfInfoParameter( int value,
+                                            PdfParam information ) {
+
+      // Look for the accessor object:
+      auto* acc = pdfInfoAccessorV1Int( information );
+      if( ! acc ) return false;
+
+      // Set the value:
+      ( *acc )( *this ) = value;
+      return true;
+   }
+
+   bool TruthEvent::setPdfInfoParameter( float value,
+                                            PdfParam information ) {
+
+      // Look for the accessor object:
+      auto* acc = pdfInfoAccessorV1Float( information );
+      if( ! acc ) return false;
+
+      // Set the value:
+      ( *acc )( *this ) = value;
+      return true;
+   }
+
+   TruthEvent::PdfInfo::PdfInfo()
+      : pdgId1( 0 ), pdgId2( 0 ), pdfId1( -1 ), pdfId2( -1 ),
+        x1( NAN ), x2( NAN ), Q( NAN ), xf1( NAN ), xf2( NAN ) {
+
+   }
+
+   bool TruthEvent::PdfInfo::valid() const {
+
+      return ( ( pdgId1 != 0 ) && ( pdgId2 != 0 ) &&
+               ( pdfId1 >= 0 ) && ( pdfId2 >= 0 ) &&
+               ( ! std::isnan( x1 ) ) && ( ! std::isnan( x2 ) ) &&
+               ( ! std::isnan( Q ) ) &&
+               ( ! std::isnan( xf1 ) ) && ( ! std::isnan( xf2 ) ) );
+   }
+
+   TruthEvent::PdfInfo TruthEvent::pdfInfo() const {
+
+      // The result object:
+      PdfInfo rtn;
+
+      // Retrieve all of its elements:
+      pdfInfoParameter( rtn.pdgId1, PDGID1 );
+      pdfInfoParameter( rtn.pdgId2, PDGID2 );
+      pdfInfoParameter( rtn.pdfId1, PDFID1 );
+      pdfInfoParameter( rtn.pdfId2, PDFID2 );
+      pdfInfoParameter( rtn.x1,     X1 );
+      pdfInfoParameter( rtn.x2,     X2 );
+      pdfInfoParameter( rtn.Q,      Q );
+      pdfInfoParameter( rtn.xf1,    XF1 );
+      pdfInfoParameter( rtn.xf2,    XF2 );
+
+      return rtn;
+   }
+
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   // Implementation for the links to truth particles/vertices
+
+   // Accessor for the signal vertex
+   static SG::AuxElement::Accessor< TruthEvent::TruthVertexLink_t >
+      signalProcessVertexLinkAcc( "signalProcessVertexLink" );
+
+   const TruthVertex* TruthEvent::signalProcessVertex() const {
+
+      // Check if the link variable is available:
+      if( ! signalProcessVertexLinkAcc.isAvailable( *this ) ) {
+         return 0;
+      }
+
+      // Get the link:
+      const TruthVertexLink_t& vertLink = signalProcessVertexLinkAcc( *this );
+
+      // Check if it's valid:
+      if( ! vertLink.isValid() ) {
+         return 0;
+      }
+
+      // Return the de-referenced link:
+      return *vertLink;
+   }
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent,
+                                      TruthEvent::TruthVertexLink_t,
+                                      signalProcessVertexLink,
+                                      setSignalProcessVertexLink )
+
+   // Accessors for the beam particles
+   static SG::AuxElement::Accessor< TruthEvent::TruthParticleLink_t >
+      primaryParticleLinkLinkAcc( "primaryParticleLink" );
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent,
+                                      TruthEvent::TruthParticleLink_t,
+                                      primaryParticleLink,
+                                      setPrimaryParticleLink )
+
+   /////////////////////////////////////////////////////////////////////////////
+
+   Type::ObjectType TruthEvent::type() const {
+
+      return Type::TruthEvent;
+   }
+
+   void TruthEvent::toPersistent() {
+
+      if( primaryParticleLinkLinkAcc.isAvailableWritable( *this ) ) {
+         primaryParticleLinkLinkAcc( *this ).toPersistent();
+      }
+
+      if( signalProcessVertexLinkAcc.isAvailableWritable( *this ) ) {
+         signalProcessVertexLinkAcc( *this ).toPersistent();
+      }
+
+      // Prepare the truth particle links for writing:
+      if( truthParticleLinksAcc.isAvailableWritable( *this ) ) {
+         TruthParticleLinks_t::iterator itr =
+            truthParticleLinksAcc( *this ).begin();
+         TruthParticleLinks_t::iterator end =
+            truthParticleLinksAcc( *this ).end();
+         for( ; itr != end; ++itr ) {
+            itr->toPersistent();
+         }
+      }
+
+      // Prepare the truth vertex links for writing:
+      if( truthVertexLinksAcc.isAvailableWritable( *this ) ) {
+         TruthVertexLinks_t::iterator itr =
+            truthVertexLinksAcc( *this ).begin();
+         TruthVertexLinks_t::iterator end =
+            truthVertexLinksAcc( *this ).end();
+         for( ; itr != end; ++itr ) {
+            itr->toPersistent();
+         }
+      }
+      return;
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/TruthEventAuxContainer.cxx b/xAOD/xAODTruth/Root/TruthEventAuxContainer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..45de1069323849d806be1e14093edd934c7ba9d9
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthEventAuxContainer.cxx
@@ -0,0 +1,20 @@
+// Local include(s):
+#include "xAODTruth/TruthEventAuxContainer.h"
+
+namespace xAOD {
+
+   TruthEventAuxContainer::TruthEventAuxContainer()
+      : AuxContainerBase() {
+
+      AUX_VARIABLE( signalProcessVertexLink );
+
+      AUX_VARIABLE( weights );
+
+      AUX_VARIABLE( crossSection );
+      AUX_VARIABLE( crossSectionError );
+
+      AUX_VARIABLE( truthVertexLinks );
+      AUX_VARIABLE( truthParticleLinks );
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/TruthMetaDataAuxContainer_v1.cxx b/xAOD/xAODTruth/Root/TruthMetaDataAuxContainer_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0d1d7a578c1cdbc2ffe0198a42335214d8f9ca6b
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthMetaDataAuxContainer_v1.cxx
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+
+// Local include(s):
+#include "xAODTruth/versions/TruthMetaDataAuxContainer_v1.h"
+
+namespace xAOD {
+
+   TruthMetaDataAuxContainer_v1::TruthMetaDataAuxContainer_v1()
+   : AuxContainerBase() {
+
+      AUX_VARIABLE( weightNames );
+      AUX_VARIABLE( mcChannelNumber );
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/TruthMetaData_v1.cxx b/xAOD/xAODTruth/Root/TruthMetaData_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3897c03340dc27adc67ae60ac6b05b922bd51a7f
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthMetaData_v1.cxx
@@ -0,0 +1,21 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+
+// xAOD include(s):
+#include "xAODCore/AuxStoreAccessorMacros.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthMetaData_v1.h"
+
+namespace xAOD {
+
+   TruthMetaData_v1::TruthMetaData_v1(): SG::AuxElement() {}
+
+   //Arguments for MACRO are as follows: AUXSTORE_OBJECT/PRIMITIVE_SETTER_AND_GETTER(CL, TYPE, NAME, SETTER)
+   AUXSTORE_OBJECT_SETTER_AND_GETTER(TruthMetaData_v1, std::vector < std::string >, weightNames, setWeightNames )
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(TruthMetaData_v1, uint32_t, mcChannelNumber, setMcChannelNumber )
+}
+ // 
diff --git a/xAOD/xAODTruth/Root/TruthParticleAuxContainer_v1.cxx b/xAOD/xAODTruth/Root/TruthParticleAuxContainer_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..015457c7f6347e8812ccecd6efa3bba023f9706c
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthParticleAuxContainer_v1.cxx
@@ -0,0 +1,27 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthParticleAuxContainer_v1.cxx 622193 2014-10-16 16:08:34Z krasznaa $
+
+// Local include(s):
+#include "xAODTruth/versions/TruthParticleAuxContainer_v1.h"
+
+namespace xAOD {
+
+   TruthParticleAuxContainer_v1::TruthParticleAuxContainer_v1()
+   : AuxContainerBase() {
+
+      AUX_VARIABLE( pdgId );
+      AUX_VARIABLE( barcode );
+      AUX_VARIABLE( status );
+      AUX_VARIABLE( prodVtxLink );
+      AUX_VARIABLE( decayVtxLink );
+      AUX_VARIABLE( px );
+      AUX_VARIABLE( py );
+      AUX_VARIABLE( pz );
+      AUX_VARIABLE( e );
+      AUX_VARIABLE( m );
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/TruthParticle_v1.cxx b/xAOD/xAODTruth/Root/TruthParticle_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..33ed93820354e2f383da618031041d50e002cef4
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthParticle_v1.cxx
@@ -0,0 +1,391 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthParticle_v1.cxx 690336 2015-08-20 10:54:57Z abuckley $
+
+// System include(s):
+#include <cmath>
+#include <iostream>
+#include <stdexcept>
+
+// Utility include(s):
+#include "TruthUtils/PIDHelpers.h"
+
+// xAOD include(s):
+#include "xAODCore/AuxStoreAccessorMacros.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthParticle_v1.h"
+#include "xAODTruth/TruthVertexContainer.h"
+#include "TruthAccessors_v1.h"
+
+namespace xAOD {
+
+   TruthParticle_v1::TruthParticle_v1()
+   : IParticle(), m_p4(), m_p4Cached( false ) {
+
+   }
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //  Implementation for functions identifying the particle in the MC record
+   //
+
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthParticle_v1, int, pdgId,
+                                         setPdgId )
+
+   int TruthParticle_v1::absPdgId() const {
+
+      return std::abs( pdgId() );
+   }
+
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthParticle_v1, int, barcode,
+                                         setBarcode )
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthParticle_v1, int, status,
+                                         setStatus )
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //                Implementation of the links to the vertices
+   //
+
+   /// Accessor for the production vertex
+   static SG::AuxElement::Accessor< ElementLink< TruthVertexContainer > >
+      prodVtxLinkAcc( "prodVtxLink" );
+   /// Accessor for the decay vertex
+   static SG::AuxElement::Accessor< ElementLink< TruthVertexContainer > >
+      decayVtxLinkAcc( "decayVtxLink" );
+
+   bool TruthParticle_v1::hasProdVtx() const {
+
+      return ( prodVtxLinkAcc.isAvailable( *this ) &&
+               prodVtxLinkAcc( *this ).isValid() );
+   }
+
+   const TruthVertex* TruthParticle_v1::prodVtx() const {
+
+      return hasProdVtx() ? *prodVtxLink() : 0;
+   }
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthParticle_v1,
+                                      ElementLink< TruthVertexContainer >,
+                                      prodVtxLink, setProdVtxLink )
+
+   bool TruthParticle_v1::hasDecayVtx() const {
+
+      return ( decayVtxLinkAcc.isAvailable( *this ) &&
+               decayVtxLinkAcc( *this ).isValid() );
+   }
+
+   const TruthVertex* TruthParticle_v1::decayVtx() const {
+
+      return hasDecayVtx() ? *decayVtxLink() : 0;
+   }
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthParticle_v1,
+                                      ElementLink< TruthVertexContainer >,
+                                      decayVtxLink, setDecayVtxLink )
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //                 Direct access to parents and children
+   //
+
+   size_t TruthParticle_v1::nParents() const {
+
+      return hasProdVtx() ? prodVtx()->nIncomingParticles() : 0;
+   }
+
+   const TruthParticle_v1* TruthParticle_v1::parent( size_t i ) const {
+
+      return hasProdVtx() ? prodVtx()->incomingParticle( i ) : 0;
+   }
+
+   size_t TruthParticle_v1::nChildren() const {
+
+      return hasDecayVtx() ? decayVtx()->nOutgoingParticles() : 0;
+   }
+
+   const TruthParticle_v1* TruthParticle_v1::child( size_t i ) const {
+
+      return hasDecayVtx() ? decayVtx()->outgoingParticle( i ) : 0;
+   }
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //               Implementation of the IParticle interface
+   //
+
+   double TruthParticle_v1::pt() const {
+
+      // Do the calculation by hand:
+      const double localPx = static_cast< double >( px() );
+      const double localPy = static_cast< double >( py() );
+      return std::sqrt( localPx * localPx + localPy * localPy );
+   }
+
+   double TruthParticle_v1::eta() const {
+
+      // Calculate the pseudo-rapidity using TLorentzVector.
+      // Could do something more lightweight later on.
+      return p4().Eta();
+   }
+
+   double TruthParticle_v1::phi() const {
+
+      // Calculate the azimuth angle using TLorentzVector.
+      // Could do something more lightweight later on.
+      return p4().Phi();
+   }
+
+   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TruthParticle_v1, float, double, m )
+   AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TruthParticle_v1, float, double, e )
+
+   double TruthParticle_v1::rapidity() const {
+
+      return p4().Rapidity();
+   }
+
+   const TruthParticle_v1::FourMom_t& TruthParticle_v1::p4() const {
+
+      // Cache the 4-momentum if it's not already:
+      if( ! m_p4Cached ) {
+         m_p4.SetPxPyPzE( px(), py(), pz(), e() );
+         m_p4Cached = true;
+      }
+
+      return m_p4;
+   }
+
+   Type::ObjectType TruthParticle_v1::type() const {
+
+      return Type::TruthParticle;
+   }
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //    Implementation of the truth particle specific 4-momentum functions
+   //
+
+   double TruthParticle_v1::abseta() const {
+
+      return std::abs( eta() );
+   }
+
+   double TruthParticle_v1::absrapidity() const {
+
+      return std::abs( rapidity() );
+   }
+
+   AUXSTORE_PRIMITIVE_GETTER( TruthParticle_v1, float, px )
+
+   void TruthParticle_v1::setPx( float value ) {
+      static Accessor< float > acc( "px" );
+      m_p4Cached = false;
+      acc( *this ) = value;
+      return;
+   }
+
+   AUXSTORE_PRIMITIVE_GETTER( TruthParticle_v1, float, py )
+
+   void TruthParticle_v1::setPy( float value ) {
+      static Accessor< float > acc( "py" );
+      m_p4Cached = false;
+      acc( *this ) = value;
+      return;
+   }
+
+   AUXSTORE_PRIMITIVE_GETTER( TruthParticle_v1, float, pz )
+
+   void TruthParticle_v1::setPz( float value ) {
+      static Accessor< float > acc( "pz" );
+      m_p4Cached = false;
+      acc( *this ) = value;
+      return;
+   }
+   
+   void TruthParticle_v1::setE( float value ) {
+      static Accessor< float > acc( "e" );
+      m_p4Cached = false;
+      acc( *this ) = value;
+      return;
+   }
+   
+   void TruthParticle_v1::setM( float value ) {
+      static Accessor< float > acc( "m" );
+      // note: this does not invalidate the cache
+      acc( *this ) = value;
+      return;
+   }
+   
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //         Implementation of the particle species decoder functions
+   //
+
+/// Helper macro to implement the functions that rely in functions from MC::PID
+#define MC_PID_HELPER( TYPE, FNAME )      \
+   TYPE TruthParticle_v1::FNAME() const { \
+      return MC::PID::FNAME( pdgId() );   \
+   }
+
+   MC_PID_HELPER( double, charge )
+   MC_PID_HELPER( int, threeCharge )
+
+   MC_PID_HELPER( bool, isCharged )
+   MC_PID_HELPER( bool, isNeutral )
+
+   MC_PID_HELPER( bool, isPhoton )
+   MC_PID_HELPER( bool, isLepton )
+   MC_PID_HELPER( bool, isChLepton )
+   MC_PID_HELPER( bool, isElectron )
+   MC_PID_HELPER( bool, isMuon )
+   MC_PID_HELPER( bool, isTau )
+   MC_PID_HELPER( bool, isNeutrino )
+
+   MC_PID_HELPER( bool, isHadron )
+   MC_PID_HELPER( bool, isMeson )
+   MC_PID_HELPER( bool, isBaryon )
+
+   MC_PID_HELPER( bool, hasStrange )
+   MC_PID_HELPER( bool, hasCharm )
+   MC_PID_HELPER( bool, hasBottom )
+
+   MC_PID_HELPER( bool, isLightMeson )
+   MC_PID_HELPER( bool, isLightBaryon )
+   MC_PID_HELPER( bool, isLightHadron )
+
+   MC_PID_HELPER( bool, isHeavyMeson )
+   MC_PID_HELPER( bool, isHeavyBaryon )
+   MC_PID_HELPER( bool, isHeavyHadron )
+
+   MC_PID_HELPER( bool, isBottomMeson )
+   MC_PID_HELPER( bool, isBottomBaryon )
+   MC_PID_HELPER( bool, isBottomHadron )
+
+   MC_PID_HELPER( bool, isCharmMeson )
+   MC_PID_HELPER( bool, isCharmBaryon )
+   MC_PID_HELPER( bool, isCharmHadron )
+
+   MC_PID_HELPER( bool, isStrangeMeson )
+   MC_PID_HELPER( bool, isStrangeBaryon )
+   MC_PID_HELPER( bool, isStrangeHadron )
+
+   MC_PID_HELPER( bool, isQuark )
+   MC_PID_HELPER( bool, isParton )
+   MC_PID_HELPER( bool, isTop )
+   MC_PID_HELPER( bool, isW )
+   MC_PID_HELPER( bool, isZ )
+   MC_PID_HELPER( bool, isHiggs )
+   MC_PID_HELPER( bool, isResonance )
+   MC_PID_HELPER( bool, isGenSpecific )
+
+// Forget about this macro:
+#undef MC_PID_HELPER
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //          Implementation of the optional polarization accessors
+   //
+
+   bool TruthParticle_v1::polarizationParameter( float& value,
+                                                 PolParam param ) const {
+
+      // Get the accessor object:
+      Accessor< float >* acc = polarizationAccessorV1( param );
+      if( ! acc ) {
+         // The user asked for a non-existent parameter type. o.O
+         std::cerr << "xAOD::TruthParticle_v1::polarizationParameter ERROR "
+                   << "Request for an unknown (" << param << ") polarization "
+                   << "parameter type" << std::endl;
+         return false;
+      }
+      // Check if the variable is available:
+      if( ! acc->isAvailable( *this ) ) {
+         // No, it is not.
+         return false;
+      }
+
+      // Read the value:
+      value = ( *acc )( *this );
+      return true;
+   }
+
+   bool TruthParticle_v1::setPolarizationParameter( float value,
+                                                    PolParam param ) {
+
+      // Get the accessor object:
+      Accessor< float >* acc = polarizationAccessorV1( param );
+      if( ! acc ) {
+         // The user asked for a non-existent parameter type. o.O
+         std::cerr << "xAOD::TruthParticle_v1::setPolarizationParameter ERROR "
+                   << "Request for an unknown (" << param << ") polarization "
+                   << "parameter type" << std::endl;
+         return false;
+      }
+
+      // Set the value:
+      ( *acc )( *this ) = value;
+      return true;
+   }
+
+   float TruthParticle_v1::polarizationPatameter( PolParam param ) const {
+
+      // Get the accessor object:
+      Accessor< float >* acc = polarizationAccessorV1( param );
+      if( ! acc ) {
+         // Throw an exception:
+         throw std::runtime_error( "Unrecognized polarization parameter "
+                                   "requested" );
+      }
+
+      // Read the value:
+      return ( *acc )( *this );
+   }
+
+   TruthParticle_v1::Polarization TruthParticle_v1::polarization() const {
+
+      // Construct the object:
+      Polarization rtn;
+      polarizationParameter( rtn.phi, polarizationPhi );
+      polarizationParameter( rtn.theta, polarizationTheta );
+
+      return rtn;
+   }
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   void TruthParticle_v1::toPersistent() {
+
+      if( prodVtxLinkAcc.isAvailableWritable( *this ) ) {
+         prodVtxLinkAcc( *this ).toPersistent();
+      }
+      if( decayVtxLinkAcc.isAvailableWritable( *this ) ) {
+         decayVtxLinkAcc( *this ).toPersistent();
+      }
+      return;
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/TruthVertexAuxContainer_v1.cxx b/xAOD/xAODTruth/Root/TruthVertexAuxContainer_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f3843bcd0a67f36be97c698b6ccb21d20cb995a1
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthVertexAuxContainer_v1.cxx
@@ -0,0 +1,25 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthVertexAuxContainer_v1.cxx 624338 2014-10-27 15:08:55Z krasznaa $
+
+// Local include(s):
+#include "xAODTruth/versions/TruthVertexAuxContainer_v1.h"
+
+namespace xAOD {
+
+   TruthVertexAuxContainer_v1::TruthVertexAuxContainer_v1()
+   : AuxContainerBase() {
+
+      AUX_VARIABLE( id );
+      AUX_VARIABLE( barcode );
+      AUX_VARIABLE( incomingParticleLinks );
+      AUX_VARIABLE( outgoingParticleLinks );
+      AUX_VARIABLE( x );
+      AUX_VARIABLE( y );
+      AUX_VARIABLE( z );
+      AUX_VARIABLE( t );
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/TruthVertex_v1.cxx b/xAOD/xAODTruth/Root/TruthVertex_v1.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c35ac3dccba3bed6e6ae5598b06696b358a4699d
--- /dev/null
+++ b/xAOD/xAODTruth/Root/TruthVertex_v1.cxx
@@ -0,0 +1,251 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthVertex_v1.cxx 624338 2014-10-27 15:08:55Z krasznaa $
+
+// System include(s):
+#include <cmath>
+
+// xAOD include(s):
+#include "xAODCore/AuxStoreAccessorMacros.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthVertex_v1.h"
+#include "xAODTruth/TruthParticleContainer.h"
+
+namespace xAOD {
+
+   TruthVertex_v1::TruthVertex_v1()
+   : SG::AuxElement(), m_v4(), m_v4Cached( false ) {
+
+   }
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //            Implementation for the "MC specific" functions
+   //
+
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthVertex_v1, int, id, setId )
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthVertex_v1, int, barcode,
+                                         setBarcode )
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //           Implementation for the links to the truth particles
+   //
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthVertex_v1, TruthVertex_v1::TPLinks_t,
+                                      incomingParticleLinks,
+                                      setIncomingParticleLinks )
+
+   /// Accessor for the incoming particles
+   static SG::AuxElement::Accessor< TruthVertex_v1::TPLinks_t >
+      incomingParticleLinksAcc( "incomingParticleLinks" );
+
+   size_t TruthVertex_v1::nIncomingParticles() const {
+   
+      // Check if the variable is available:
+      if( ! incomingParticleLinksAcc.isAvailable( *this ) ) {
+         // If not, just tell the user that there aren't any incoming particles:
+         return 0;
+      }
+
+      // Return the size of the vector:
+      return incomingParticleLinksAcc( *this ).size();
+   }
+
+   const TruthParticle* TruthVertex_v1::incomingParticle( size_t index ) const {
+
+      // Check that the variable exists, and that it has enough elements in it:
+      if( ( ! incomingParticleLinksAcc.isAvailable( *this ) ) ||
+          ( incomingParticleLinksAcc( *this ).size() <= index ) ) {
+         return 0;
+      }
+
+      // Retrieve the link object and check its validity:
+      const TPLink_t& ipl = incomingParticleLinksAcc( *this )[ index ];
+      if( ! ipl.isValid() ) {
+         return 0;
+      }
+
+      // Finally, de-reference the link:
+      return *ipl;
+   }
+
+   void TruthVertex_v1::addIncomingParticleLink( const TPLink_t& link ) {
+
+      incomingParticleLinksAcc( *this ).push_back( link );
+      return;
+   }
+
+   void TruthVertex_v1::clearIncomingParticleLinks() {
+
+      incomingParticleLinksAcc( *this ).clear();
+      return;
+   }
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthVertex_v1, TruthVertex_v1::TPLinks_t,
+                                      outgoingParticleLinks,
+                                      setOutgoingParticleLinks )
+
+   /// Accessor for the outgoing particles
+   static SG::AuxElement::Accessor< TruthVertex_v1::TPLinks_t >
+      outgoingParticleLinksAcc( "outgoingParticleLinks" );
+
+   size_t TruthVertex_v1::nOutgoingParticles() const {
+
+      // Check if the variable is available:
+      if( ! outgoingParticleLinksAcc.isAvailable( *this ) ) {
+         // If not, just tell the user that there aren't any outgoing particles:
+         return 0;
+      }
+
+      // Return the size of the vector:
+      return outgoingParticleLinksAcc( *this ).size();
+   }
+
+   const TruthParticle* TruthVertex_v1::outgoingParticle( size_t index ) const {
+
+      // Check that the variable exists, and that it has enough elements in it:
+      if( ( ! outgoingParticleLinksAcc.isAvailable( *this ) ) ||
+          ( outgoingParticleLinksAcc( *this ).size() <= index ) ) {
+         return 0;
+      }
+
+      // Retrieve the link object and check its validity:
+      const TPLink_t& opl = outgoingParticleLinksAcc( *this )[ index ];
+      if( ! opl.isValid() ) {
+         return 0;
+      }
+      
+      // Finally, de-reference the link:
+      return *opl;
+   }
+
+   void TruthVertex_v1::addOutgoingParticleLink( const TPLink_t& link ) {
+
+      outgoingParticleLinksAcc( *this ).push_back( link );
+      return;
+   }
+
+   void TruthVertex_v1::clearOutgoingParticleLinks() {
+
+      outgoingParticleLinksAcc( *this ).clear();
+      return;
+   }
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   /////////////////////////////////////////////////////////////////////////////
+   //
+   //     Implementation of the functions specifying the vertex's position
+   //
+
+   AUXSTORE_PRIMITIVE_GETTER( TruthVertex_v1, float, x )
+
+   void TruthVertex_v1::setX( float x ) {
+
+      static SG::AuxElement::Accessor< float > acc( "x" );
+      m_v4Cached = false;
+      acc( *this ) = x;
+      return;
+   }
+
+   AUXSTORE_PRIMITIVE_GETTER( TruthVertex_v1, float, y )
+
+   void TruthVertex_v1::setY( float y ) {
+
+      static SG::AuxElement::Accessor< float > acc( "y" );
+      m_v4Cached = false;
+      acc( *this ) = y;
+      return;
+   }
+
+   AUXSTORE_PRIMITIVE_GETTER( TruthVertex_v1, float, z )
+
+   void TruthVertex_v1::setZ( float z ) {
+
+      static SG::AuxElement::Accessor< float > acc( "z" );
+      m_v4Cached = false;
+      acc( *this ) = z;
+      return;
+   }
+
+   float TruthVertex_v1::perp() const {
+
+      // Do the calculation by hand. Could make it faster than this even in a
+      // future iteration...
+      return std::sqrt( x() * x() + y() * y() );
+   }
+
+   float TruthVertex_v1::eta() const {
+
+      // This is not necessarily what Andy was thinking about...
+      return v4().Eta();
+   }
+
+   float TruthVertex_v1::phi() const {
+
+      // This is not necessarily what Andy was thinking about...
+      return v4().Phi();
+   }
+
+   AUXSTORE_PRIMITIVE_GETTER( TruthVertex_v1, float, t )
+
+   void TruthVertex_v1::setT( float t ) {
+
+      static SG::AuxElement::Accessor< float > acc( "t" );
+      m_v4Cached = false;
+      acc( *this ) = t;
+      return;
+   }
+
+   const TruthVertex_v1::FourVec_t& TruthVertex_v1::v4() const {
+
+      // Cache the 4-vector if it's not already:
+      if( ! m_v4Cached ) {
+         m_v4.SetXYZT( x(), y(), z(), t() );
+         m_v4Cached = true;
+      }
+
+      // Return the cached object:
+      return m_v4;
+   }
+
+   //
+   /////////////////////////////////////////////////////////////////////////////
+
+   Type::ObjectType TruthVertex_v1::type() const {
+
+      return Type::TruthVertex;
+   }
+
+   void TruthVertex_v1::toPersistent() {
+
+      // Prepare the incoming particle links for persistification:
+      if( incomingParticleLinksAcc.isAvailableWritable( *this ) ) {
+         TPLinks_t::iterator itr = incomingParticleLinksAcc( *this ).begin();
+         TPLinks_t::iterator end = incomingParticleLinksAcc( *this ).end();
+         for( ; itr != end; ++itr ) {
+            itr->toPersistent();
+         }
+      }
+
+      // Prepare the outgoing particle links for persistification:
+      if( outgoingParticleLinksAcc.isAvailableWritable( *this ) ) {
+         TPLinks_t::iterator itr = outgoingParticleLinksAcc( *this ).begin();
+         TPLinks_t::iterator end = outgoingParticleLinksAcc( *this ).end();
+         for( ; itr != end; ++itr ) {
+            itr->toPersistent();
+         }
+      }
+
+      return;
+   }
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/Root/dict/ContainerProxies.cxx b/xAOD/xAODTruth/Root/dict/ContainerProxies.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f73d88fb073568eae416fd5ec2f808eade25c481
--- /dev/null
+++ b/xAOD/xAODTruth/Root/dict/ContainerProxies.cxx
@@ -0,0 +1,22 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ContainerProxies.cxx 670637 2015-05-28 15:49:43Z tbisanz $
+
+// EDM include(s):
+#include "xAODCore/AddDVProxy.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthParticleContainer_v1.h"
+#include "xAODTruth/versions/TruthVertexContainer_v1.h"
+#include "xAODTruth/versions/TruthEventContainer_v1.h"
+#include "xAODTruth/versions/TruthPileupEventContainer_v1.h"
+#include "xAODTruth/versions/TruthMetaDataContainer_v1.h"
+
+// Set up the collection proxies:
+ADD_NS_DV_PROXY( xAOD, TruthMetaDataContainer_v1 );
+ADD_NS_DV_PROXY( xAOD, TruthParticleContainer_v1 );
+ADD_NS_DV_PROXY( xAOD, TruthVertexContainer_v1 );
+ADD_NS_DV_PROXY( xAOD, TruthEventContainer_v1 );
+ADD_NS_DV_PROXY( xAOD, TruthPileupEventContainer_v1 );
diff --git a/xAOD/xAODTruth/Root/xAODTruthCLIDs.cxx b/xAOD/xAODTruth/Root/xAODTruthCLIDs.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..491a18cd3d169a9884a69cf7adb802278886dab4
--- /dev/null
+++ b/xAOD/xAODTruth/Root/xAODTruthCLIDs.cxx
@@ -0,0 +1,17 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+//simple includes to force the CLASS_DEF to be encountered during compile
+
+#include "xAODTruth/TruthVertexContainer.h"
+#include "xAODTruth/TruthVertexAuxContainer.h"
+#include "xAODTruth/TruthEventContainer.h"
+#include "xAODTruth/TruthEventAuxContainer.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthParticleAuxContainer.h"
+#include "xAODTruth/TruthPileupEventContainer.h"
+#include "xAODTruth/TruthPileupEventAuxContainer.h"
+#include "xAODTruth/TruthEventBaseContainer.h"
+
diff --git a/xAOD/xAODTruth/Root/xAODTruthHelpers.cxx b/xAOD/xAODTruth/Root/xAODTruthHelpers.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3d00de95e602944a5a772eff2a659cb1f4afe9cf
--- /dev/null
+++ b/xAOD/xAODTruth/Root/xAODTruthHelpers.cxx
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: xAODTruthHelpers.cxx 668406 2015-05-19 15:32:15Z krasznaa $
+
+// Core EDM include(s):
+#include "AthLinks/ElementLink.h"
+#include "AthContainers/AuxElement.h"
+
+// xAOD include(s):
+#include "xAODBase/IParticle.h"
+
+// Local include(s):
+#include "xAODTruth/xAODTruthHelpers.h"
+#include "xAODTruth/TruthParticle.h"
+#include "xAODTruth/TruthParticleContainer.h"
+
+namespace xAOD {
+
+   namespace TruthHelpers {
+
+      /// @param p The particle that we find the associated truth particle for
+      /// @returns A pointer to the associated truth particle if available,
+      ///          or a null pointer if not
+      ///
+      const xAOD::TruthParticle* getTruthParticle( const xAOD::IParticle& p ) {
+
+         /// A convenience type declaration
+         typedef ElementLink< xAOD::TruthParticleContainer > Link_t;
+
+         /// A static accessor for the information
+         static SG::AuxElement::ConstAccessor< Link_t > acc( "truthParticleLink" );
+
+         // Check if such a link exists on the object:
+         if( ! acc.isAvailable( p ) ) {
+            return 0;
+         }
+
+         // Get the link:
+         const Link_t& link = acc( p );
+
+         // Check if the link is valid:
+         if( ! link.isValid() ) {
+            return 0;
+         }
+
+         // Everything has passed, let's return the pointer:
+         return *link;
+      }
+
+      /// @param p The particle that we want to find the truth type of
+      /// @returns 0 if the truth type is not available, or the truth type
+      ///          determined by MCTruthClassifier, if it is
+      ///
+      int getParticleTruthType( const xAOD::IParticle& p ) {
+
+         /// A static accessor for the information
+         static SG::AuxElement::ConstAccessor< int > acc( "truthType" );
+
+         // Check if such a variable exists on the object:
+         if( ! acc.isAvailable( p ) ) {
+            return 0;
+         }
+
+         // Let's return the value:
+         return acc( p );
+      }
+
+      /// @param p The particle that we want to find the truth origin of
+      /// @returns 0 if the truth origin is not available, or the truth origin
+      ///          determined by MCTruthClassifier, if it is
+      ///
+      int getParticleTruthOrigin( const xAOD::IParticle& p ) {
+
+         /// A static accessor for the information
+         static SG::AuxElement::ConstAccessor< int > acc( "truthOrigin" );
+
+         // Check if such a variable exists on the object:
+         if( ! acc.isAvailable( p ) ) {
+            return 0;
+         }
+
+         // Let's return the value:
+         return acc( p );
+      }
+
+   } // namespace TruthHelpers
+
+} // namespace xAOD
diff --git a/xAOD/xAODTruth/TODO b/xAOD/xAODTruth/TODO
new file mode 100644
index 0000000000000000000000000000000000000000..65552242600f222c6c7417e5bd35dd24d2af6b29
--- /dev/null
+++ b/xAOD/xAODTruth/TODO
@@ -0,0 +1,8 @@
+xAOD truth TODOs
+================
+
+* Tidy TruthEvent attrs, add named weight vector
+
+* Handling run-level info like cross-sections?
+
+* Add a vector of separate TruthPileupEvent objects, which store no event-level info
diff --git a/xAOD/xAODTruth/cmt/Makefile.RootCore b/xAOD/xAODTruth/cmt/Makefile.RootCore
new file mode 100644
index 0000000000000000000000000000000000000000..e44442caa389d2963ed687991bbed33a412b1654
--- /dev/null
+++ b/xAOD/xAODTruth/cmt/Makefile.RootCore
@@ -0,0 +1,24 @@
+# this makefile also gets parsed by shell scripts
+# therefore it does not support full make syntax and features
+# edit with care
+
+# for full documentation check:
+# https://twiki.cern.ch/twiki/bin/viewauth/Atlas/RootCore#Package_Makefile
+
+PACKAGE          = xAODTruth
+PACKAGE_PRELOAD  =
+PACKAGE_CXXFLAGS =
+PACKAGE_OBJFLAGS =
+PACKAGE_LDFLAGS  =
+PACKAGE_BINFLAGS =
+PACKAGE_LIBFLAGS =
+PACKAGE_DEP      = AthContainers AthLinks xAODBase xAODCore TruthUtils
+PACKAGE_TRYDEP   =
+PACKAGE_CLEAN    =
+PACKAGE_NOGRID   =
+PACKAGE_PEDANTIC = 1
+PACKAGE_NOOPT    = 0
+PACKAGE_NOCC     = 0
+PACKAGE_REFLEX   = 1
+
+include $(ROOTCOREDIR)/Makefile-common
diff --git a/xAOD/xAODTruth/cmt/requirements b/xAOD/xAODTruth/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..44f457ab07aacdadc7b5440f8ba1ab3fcd1062ec
--- /dev/null
+++ b/xAOD/xAODTruth/cmt/requirements
@@ -0,0 +1,42 @@
+package xAODTruth
+# $Id: requirements 761796 2016-07-14 08:06:02Z krasznaa $
+
+author Andy Buckley <andy.buckley@cern.ch>
+author James Catmore <james.catmore@cern.ch>
+author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+author Jovan Mitrevski <Jovan.Mitrevski@cern.ch>
+
+public
+
+# Central packages:
+use AtlasPolicy     AtlasPolicy-*
+use AthContainers   AthContainers-*    Control
+use AthLinks        AthLinks-*         Control
+
+# EDM packages:
+use xAODBase        xAODBase-*         Event/xAOD
+use xAODCore        xAODCore-*         Event/xAOD
+use AtlasROOT       AtlasROOT-*        External
+
+# Specify the ROOT components that are necessary for cmake. Transparent to CMT
+apply_pattern cmake_add_command command="find_package(ROOT COMPONENTS Physics)"
+
+library xAODTruth ../Root/*.cxx
+apply_pattern installed_library
+
+private
+
+use TruthUtils      TruthUtils-*       Generators
+use AtlasReflex     AtlasReflex-*      External
+
+# Generate a dictionary for the package:
+apply_pattern lcgdict dict=xAODTruth selectionfile=selection.xml \
+                      headerfiles="../xAODTruth/xAODTruthDict.h" \
+                      extralibfiles=../Root/dict/*.cxx
+
+apply_pattern do_genCLIDDB library=xAODTruth
+
+# Specify the unit test(s) of the package:
+use TestTools       TestTools-*        AtlasTest
+apply_pattern UnitTest_run unit_test=ut_xaodtruth_particle
+
diff --git a/xAOD/xAODTruth/share/ut_xaodtruth_particle_test.ref b/xAOD/xAODTruth/share/ut_xaodtruth_particle_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..fdaff706b58a58b373166733cd7d08319568a231
--- /dev/null
+++ b/xAOD/xAODTruth/share/ut_xaodtruth_particle_test.ref
@@ -0,0 +1 @@
+All tests succeeded
diff --git a/xAOD/xAODTruth/test/ut_xaodtruth_helpers_test.py b/xAOD/xAODTruth/test/ut_xaodtruth_helpers_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..4147126363f0779555b4663a4acca857d0c98252
--- /dev/null
+++ b/xAOD/xAODTruth/test/ut_xaodtruth_helpers_test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+#
+# $Id: ut_xaodtruth_helpers_test.py 761304 2016-07-12 12:03:36Z krasznaa $
+#
+# This is a simple unit test for checking the health of the truth helper
+# functions in the standalone analysis environment.
+#
+
+## C/C++ style main function
+def main():
+
+    # Initialise the environment:
+    import ROOT
+    ROOT.gROOT.Macro( "$ROOTCOREDIR/scripts/load_packages.C" )
+
+    # Open an input xAOD file:
+    import os
+    FNAME = os.getenv( "ROOTCORE_TEST_FILE", "FileNotSpecifiedInEnvironment" )
+    f = ROOT.TFile.Open( FNAME, "READ" )
+    if not f:
+        print( "Couldn't open \"%s\"" % FNAME )
+        return 1
+    print( "Opened: %s" % FNAME )
+
+    # Make a transient tree from it:
+    treeMgr = ROOT.xAOD.TTreeMgr( ROOT.xAOD.TEvent.kAthenaAccess )
+    if not treeMgr.readFrom( f ).isSuccess():
+        print( "Couldn't make a transient tree from the input file!" )
+        return 1
+    import xAODRootAccess.GenerateDVIterators
+    t = treeMgr.eventTree()
+
+    # Loop on the first few events:
+    for entry in xrange( 10 ):
+        # Load the event:
+        if t.GetEntry( entry ) < 0:
+            print( "Couldn't load entry %i from the input!" % entry )
+            return 1
+        # Print some header info:
+        print( "Processing run #%i event #%i (%i events processed so far)" % \
+               ( t.EventInfo.runNumber(), t.EventInfo.eventNumber(), entry ) )
+        # Exercise the functions on electrons:
+        for el in t.Electrons:
+            print( " - Electron: eta = %g, phi = %g, pt = %g" % \
+                   ( el.eta(), el.phi(), el.pt() ) )
+            print( "             truthType = %i, truthOrigin = %i" % \
+                   ( ROOT.xAOD.TruthHelpers.getParticleTruthType( el ),
+                     ROOT.xAOD.TruthHelpers.getParticleTruthOrigin( el ) ) )
+            tp = ROOT.xAOD.TruthHelpers.getTruthParticle( el )
+            if tp:
+                print( "   - TruthParticle: eta = %g, phi = %g, pt = %g" % \
+                       ( tp.eta(), tp.phi(), tp.pt() ) )
+                pass
+            pass
+        pass
+
+    return 0;
+
+# Execute the main function:
+if __name__ == "__main__":
+    import sys
+    sys.exit( main() )
diff --git a/xAOD/xAODTruth/test/ut_xaodtruth_particle_test.cxx b/xAOD/xAODTruth/test/ut_xaodtruth_particle_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..363f3b15cb5bc712f1111babdea7cde394b23718
--- /dev/null
+++ b/xAOD/xAODTruth/test/ut_xaodtruth_particle_test.cxx
@@ -0,0 +1,73 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ut_xaodtruth_particle_test.cxx 687313 2015-08-04 12:07:38Z krasznaa $
+
+// System include(s):
+#include <iostream>
+#include <cmath>
+
+// Local include(s):
+#include "xAODTruth/TruthParticle.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthParticleAuxContainer.h"
+
+/// Helper macro to test assertions
+#define SIMPLE_ASSERT( EXP )                                                \
+   do {                                                                     \
+      if( ! ( EXP ) ) {                                                     \
+         std::cout << "Error evaluating: " << #EXP << std::endl;            \
+         return 1;                                                          \
+      }                                                                     \
+   } while( 0 )
+
+int main() {
+
+   // Create a container to test:
+   xAOD::TruthParticleContainer c;
+   xAOD::TruthParticleAuxContainer aux;
+   c.setStore( &aux );
+
+   // Construct a particle that we can test. The values are chosen on purpose
+   // to not be possible to represent in exactly the same way at single and
+   // double precision.
+   static const double PX = std::sqrt( ( double ) 1.2345 );
+   static const double PY = std::sqrt( ( double ) 2.3456 );
+   static const double PZ = std::sqrt( ( double ) 3.4567 );
+   static const double E  = std::sqrt( ( double ) 4.5678 );
+   static const double M  = std::sqrt( ( double ) 5.6789 );
+   xAOD::TruthParticle* p = new xAOD::TruthParticle();
+   c.push_back( p );
+   p->setPx( PX );
+   p->setPy( PY );
+   p->setPz( PZ );
+   p->setE( E );
+   p->setM( M );
+
+   // The precisions that we want:
+   static const double FLOAT_PRECISION  = 1e-5;
+   static const double DOUBLE_PRECISION = 1e-10;
+
+   // Start with the most basic checks:
+   SIMPLE_ASSERT( std::abs( p->px() - PX ) < FLOAT_PRECISION );
+   SIMPLE_ASSERT( std::abs( p->py() - PY ) < FLOAT_PRECISION );
+   SIMPLE_ASSERT( std::abs( p->pz() - PZ ) < FLOAT_PRECISION );
+   SIMPLE_ASSERT( std::abs( p->e() - E ) < FLOAT_PRECISION );
+   SIMPLE_ASSERT( std::abs( p->m() - M ) < FLOAT_PRECISION );
+
+   // Now something more tricky:
+   SIMPLE_ASSERT( std::abs( p->pt() - p->p4().Pt() ) < DOUBLE_PRECISION );
+   SIMPLE_ASSERT( std::abs( p->eta() - p->p4().Eta() ) < DOUBLE_PRECISION );
+   SIMPLE_ASSERT( std::abs( p->phi() - p->p4().Phi() ) < DOUBLE_PRECISION );
+   SIMPLE_ASSERT( std::abs( p->e() - p->p4().E() ) < DOUBLE_PRECISION );
+
+   // And finally something not completely obvious:
+   SIMPLE_ASSERT( std::abs( p->m() - p->p4().M() ) > 0.1 );
+
+   // Let the user know what happened:
+   std::cout << "All tests succeeded" << std::endl;
+
+   // Return gracefully:
+   return 0;
+}
diff --git a/xAOD/xAODTruth/xAODTruth/TruthEvent.h b/xAOD/xAODTruth/xAODTruth/TruthEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd363fc7e06275742288ebc23db750e85f986ea0
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthEvent.h
@@ -0,0 +1,201 @@
+#ifndef XAODTRUTH_TRUTHEVENT_H
+#define XAODTRUTH_TRUTHEVENT_H
+
+// System include(s):
+#include <utility>
+#include <vector>
+
+// EDM include(s):
+#include "AthContainers/AuxElement.h"
+#include "AthLinks/ElementLink.h"
+#include "xAODBase/ObjectType.h"
+
+// Local include(s):
+#include "xAODTruth/TruthEventBase.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthVertexContainer.h"
+
+namespace xAOD {
+
+   /// Class describing a signal truth event in the MC record
+   ///
+   class TruthEvent : public SG::AuxElement {
+
+   public:
+      /// Default constructor
+      TruthEvent();
+      /// Virtual destructor, to make vtable happy
+      virtual ~TruthEvent() {}
+
+      /// @name Access to all the particles associated with the event
+      /// @{
+
+      /// Type of a single truth particle link
+      typedef ElementLink< TruthParticleContainer > TruthParticleLink_t;
+      /// Type of the truth particle links vector
+      typedef std::vector< TruthParticleLink_t > TruthParticleLinks_t;
+
+      /// Get all the truth particles
+      const TruthParticleLinks_t& truthParticleLinks() const;
+      /// Set all the truth particles
+      void setTruthParticleLinks( const TruthParticleLinks_t& plinks );
+      /// Get the number of truth particles
+      size_t nTruthParticles() const;
+      /// Get the link to one of the truth particles
+      const TruthParticleLink_t& truthParticleLink( size_t index ) const;
+      /// Get a pointer to one of the truth particles
+      const TruthParticle* truthParticle( size_t index ) const;
+      /// Add one truth particle
+      void addTruthParticleLink( const TruthParticleLink_t& plink );
+      /// Remove all truth particles
+      void clearTruthParticleLinks();
+
+      /// @}
+      
+      /// @name Access to all the vertices associated with the event
+      /// @{
+
+      /// Type of a single truth vertex link
+      typedef ElementLink< TruthVertexContainer > TruthVertexLink_t;
+      /// Type of the truth particle links vector
+      typedef std::vector< TruthVertexLink_t > TruthVertexLinks_t;
+
+      /// Get all the truth vertices
+      const TruthVertexLinks_t& truthVertexLinks() const;
+      /// Set all the truth vertices
+      void setTruthVertexLinks( const TruthVertexLinks_t& links );
+      /// Get the number of truth vertices
+      size_t nTruthVertices() const;
+      /// Get the link to one of the truth vertices
+      const TruthVertexLink_t& truthVertexLink( size_t index ) const;
+      /// Get a pointer to one of the truth vertices
+      const TruthVertex* truthVertex( size_t index ) const;
+      /// Add one truth vertex
+      void addTruthVertexLink( const TruthVertexLink_t& vlink );
+      /// Remove all truth vertices
+      void clearTruthVertexLinks();
+
+      /// @}
+      
+      /// @name Simple event properties
+      /// @{
+
+      /// Const access to the weights vector
+      /// @todo Need to add the map-like interface for the weights: very important!
+      const std::vector< float >& weights() const;
+      /// Set the event weights
+      /// @todo Need to add named weight access: vector<string>
+      void setWeights( const std::vector< float >& weights );
+
+      /// Get the cross section
+      float crossSection() const;
+      /// Set the cross-section
+      void setCrossSection( float value );
+
+      /// Get the cross section error
+      float crossSectionError() const;
+      /// Set the cross-section error
+      void setCrossSectionError( float value );
+
+      /// Set the cross-section and its error
+      void setCrossSection( float value, float error );
+
+      /// @}
+
+      /// @name Parton density info
+      ///
+      /// Optional due to particle gun & NLO events where a single PDF info
+      /// doesn't work.
+      ///
+      /// @{
+
+      /// Accessor enums for PDF info parameter lookup
+      enum PdfParam {
+         PDGID1 = 0, ///< [int]
+         PDGID2 = 1, ///< [int]
+         PDFID1 = 2, ///< [int]
+         PDFID2 = 3, ///< [int]
+         X1 = 4,     ///< [float]
+         X2 = 5,     ///< [float]
+         SCALE = 6,  ///< Not implemented!!!
+         Q = 6,      ///< [float]
+         PDF1 = 7,   ///< Not implemented!!!
+         PDF2 = 8,   ///< Not implemented!!!
+         XF1 = 7,    ///< [float]
+         XF2 = 8     ///< [float]
+      }; // enum PdfParam
+
+      /// Read an integer PDF info parameter
+      bool pdfInfoParameter( int& value, PdfParam parameter ) const;
+      /// Read a floating point PDF info parameter
+      bool pdfInfoParameter( float& value, PdfParam parameter ) const;
+
+      /// Set an integer PDF info parameter
+      bool setPdfInfoParameter( int value, PdfParam parameter );
+      /// Set a floating point PDF info parameter
+      bool setPdfInfoParameter( float value, PdfParam parameter );
+
+      /// Helper struct holding a full set of PDF info values
+      struct PdfInfo {
+
+         /// Constructor to set (invalid) defaults
+         PdfInfo();
+
+         /// Check if all the variables in the object are valid
+         bool valid() const;
+
+         int pdgId1;
+         int pdgId2;
+         int pdfId1;
+         int pdfId2;
+         float x1;
+         float x2;
+         float Q;
+         float xf1;
+         float xf2;
+
+      }; // struct PdfInfo
+
+      /// Retrieve a full PdfInfo with a single call
+      /// @note May have invalid values -- use valid() to check.
+      PdfInfo pdfInfo() const;
+
+      /// @}
+
+      /// @name Links to particles and vertices in the event
+      /// @{
+
+      /// Pointer to a vertex representing the primary interaction point
+      ///
+      /// The naming of the function is a bit misleading. The returned vertex
+      /// can only be interpreted as an interaction *position*.
+      ///
+      const TruthVertex* signalProcessVertex() const;
+      /// Link to the vertex representing the primary interaction point
+      const TruthVertexLink_t& signalProcessVertexLink() const;
+      /// Set pointer to a vertex representing the primary interaction point
+      void setSignalProcessVertexLink( const TruthVertexLink_t& link );
+
+      /// Pointer to the incoming primary particle
+      const TruthParticle* primaryParticle() const;
+
+      /// Set incoming primary particle
+      void setPrimaryParticleLink( const TruthParticleLink_t& pcl);
+
+      /// @}
+
+      /// The type of the object as a simple enumeration
+      virtual Type::ObjectType type() const;
+
+      /// Function making sure that the object is ready for persistification
+      void toPersistent();
+
+   }; // class TruthEvent
+
+} // namespace xAOD
+
+// Declare the base class of TruthEvent to StoreGate:
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthEvent, SG::AuxElement );
+
+#endif // XAODTRUTH_TRUTHEVENT_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthEventAuxContainer.h b/xAOD/xAODTruth/xAODTruth/TruthEventAuxContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..44cb0bbf4f59eb36526906f32649f377ca18710e
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthEventAuxContainer.h
@@ -0,0 +1,57 @@
+#ifndef XAODTRUTH_TRUTHEVENTAUXCONTAINER_H
+#define XAODTRUTH_TRUTHEVENTAUXCONTAINER_H
+
+// System include(s):
+#include <vector>
+
+// EDM include(s):
+#include "AthLinks/ElementLink.h"
+#include "xAODCore/AuxContainerBase.h"
+
+// Local include(s):
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthVertexContainer.h"
+
+namespace xAOD {
+
+   /// Auxiliary store for the truth vertices
+   ///
+   class TruthEventAuxContainer : public AuxContainerBase {
+
+   public:
+      /// Default constructor
+      TruthEventAuxContainer();
+
+   private:
+      /// @name Links to the interaction particles/vertices
+      /// @{
+      std::vector< ElementLink< TruthVertexContainer > >
+      signalProcessVertexLink;
+      /// @}
+
+      /// @todo Needs to be a map or similar (perhaps two linked vectors?)
+      std::vector< std::vector< float > > weights;
+
+      /// @name Cross sections and errors coming from the generator
+      /// @{
+      std::vector< float > crossSection;
+      std::vector< float > crossSectionError;
+      /// @}
+
+      /// @name Links to the generated/simulated particles/vertices
+      /// @{
+      std::vector< std::vector< ElementLink< TruthParticleContainer > > >
+      truthParticleLinks;
+      std::vector< std::vector< ElementLink< TruthVertexContainer > > >
+      truthVertexLinks;
+      /// @}
+
+   }; // class TruthEventAuxContainer
+
+} // namespace xAOD
+
+// Declare the class's inheritance to StoreGate:
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthEventAuxContainer, xAOD::AuxContainerBase ); 
+
+#endif // XAODTRUTH_TRUTHEVENTAUXCONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthEventBase.h b/xAOD/xAODTruth/xAODTruth/TruthEventBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..f84e151a3879d212d0e0acbe8884507db25738b8
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthEventBase.h
@@ -0,0 +1,19 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRUTH_TRUTHEVENTBASE_H
+#define XAODTRUTH_TRUTHEVENTBASE_H
+
+#include "xAODTruth/versions/TruthEventBase_v1.h"
+
+namespace xAOD {
+
+  /// Typedef to implementation
+  typedef TruthEventBase_v1 TruthEventBase;
+
+}
+
+#endif
diff --git a/xAOD/xAODTruth/xAODTruth/TruthEventBaseContainer.h b/xAOD/xAODTruth/xAODTruth/TruthEventBaseContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..cbdee8b08c1d5152e5d21b8ff72d1098d5b1ea93
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthEventBaseContainer.h
@@ -0,0 +1,24 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthEventBaseContainer.h 622193 2014-10-16 16:08:34Z krasznaa $
+#ifndef XAODTRUTH_TRUTHEVENTBASECONTAINER_H
+#define XAODTRUTH_TRUTHEVENTBASECONTAINER_H
+
+// Local include(s):
+#include "xAODTruth/TruthEventBase.h"
+#include "xAODTruth/versions/TruthEventBaseContainer_v1.h"
+
+namespace xAOD {
+   /// Declare the latest version of the truth event container
+   typedef TruthEventBaseContainer_v1 TruthEventBaseContainer;
+}
+
+// Declare a CLID for the class for Athena:
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TruthEventBaseContainer, 1280408222, 1 )
+
+#endif // XAODTRUTH_TRUTHEVENTBASECONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthEventContainer.h b/xAOD/xAODTruth/xAODTruth/TruthEventContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..eb99877bae90dab0f76ace26b4fff0b3f7371d2b
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthEventContainer.h
@@ -0,0 +1,22 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthEventContainer_v1.h 622193 2014-10-16 16:08:34Z krasznaa $
+#ifndef XAODTRUTH_TRUTHEVENTCONTAINER_H
+#define XAODTRUTH_TRUTHEVENTCONTAINER_H
+
+// EDM include(s):
+#include "AthContainers/DataVector.h"
+
+// Local include(s):
+#include "xAODTruth/TruthEvent.h"
+
+namespace xAOD {
+   /// Alias
+   typedef DataVector< TruthEvent > TruthEventContainer;
+}
+
+#endif // XAODTRUTH_TRUTHEVENTCONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthMetaData.h b/xAOD/xAODTruth/xAODTruth/TruthMetaData.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc53752da50664234d105cc29d101d807ac79e12
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthMetaData.h
@@ -0,0 +1,19 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRUTH_TRUTHMETADATA_H
+#define XAODTRUTH_TRUTHMETADATA_H
+
+#include "xAODTruth/versions/TruthMetaData_v1.h"
+
+namespace xAOD {
+
+  /// Typedef to implementation
+  typedef TruthMetaData_v1 TruthMetaData;
+
+}
+
+#endif
diff --git a/xAOD/xAODTruth/xAODTruth/TruthMetaDataAuxContainer.h b/xAOD/xAODTruth/xAODTruth/TruthMetaDataAuxContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..8974a7c4ca848331e5d0d95471a4058501e6dbba
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthMetaDataAuxContainer.h
@@ -0,0 +1,23 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+#ifndef XAODTRUTH_TRUTHMETADATAAUXCONTAINER_H
+#define XAODTRUTH_TRUTHMETADATAAUXCONTAINER_H
+
+// Local include(s):
+#include "xAODTruth/versions/TruthMetaDataAuxContainer_v1.h"
+
+namespace xAOD {
+   /// Declare the latest version of the truth vertex auxiliary container
+   typedef TruthMetaDataAuxContainer_v1 TruthMetaDataAuxContainer;
+}
+
+// Declare a CLID for the class
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TruthMetaDataAuxContainer, 1094306618, 1 )
+
+#endif // XAODTRUTH_TRUTHMETADATAAUXCONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthMetaDataContainer.h b/xAOD/xAODTruth/xAODTruth/TruthMetaDataContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..248918cd223da5f9a9e1b7bdd6a6e976bbf5a431
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthMetaDataContainer.h
@@ -0,0 +1,24 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+#ifndef XAODTRUTH_TRUTHMETADATACONTAINER_H
+#define XAODTRUTH_TRUTHMETADATACONTAINER_H
+
+// Local include(s):
+#include "xAODTruth/TruthMetaData.h"
+#include "xAODTruth/versions/TruthMetaDataContainer_v1.h"
+
+namespace xAOD {
+   /// Declare the latest version of the truth vertex container
+   typedef TruthMetaDataContainer_v1 TruthMetaDataContainer;
+}
+
+// Declare a CLID for the class for Athena:
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TruthMetaDataContainer, 1188015687, 1 )
+
+#endif // XAODTRUTH_TRUTHMETADATACONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthParticle.h b/xAOD/xAODTruth/xAODTruth/TruthParticle.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4d77f2c331896b55eb72d109bf1beeb2eed6fbe
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthParticle.h
@@ -0,0 +1,19 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRUTH_TRUTHPARTICLE_H
+#define XAODTRUTH_TRUTHPARTICLE_H
+
+#include "xAODTruth/versions/TruthParticle_v1.h"
+
+namespace xAOD {
+
+  /// Typedef to implementation
+  typedef TruthParticle_v1 TruthParticle;
+
+}
+
+#endif
diff --git a/xAOD/xAODTruth/xAODTruth/TruthParticleAuxContainer.h b/xAOD/xAODTruth/xAODTruth/TruthParticleAuxContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b652492327411aef6ddd4951a5ce997c44360b1
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthParticleAuxContainer.h
@@ -0,0 +1,23 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthParticleAuxContainer.h 622193 2014-10-16 16:08:34Z krasznaa $
+#ifndef XAODTRUTH_TRUTHPARTICLEAUXCONTAINER_H
+#define XAODTRUTH_TRUTHPARTICLEAUXCONTAINER_H
+
+// Local include(s):
+#include "xAODTruth/versions/TruthParticleAuxContainer_v1.h"
+
+namespace xAOD {
+   /// Declare the latest version of the truth particle auxiliary container
+   typedef TruthParticleAuxContainer_v1 TruthParticleAuxContainer;
+}
+
+// Declare a CLID for the class
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TruthParticleAuxContainer, 1107340896, 1 )
+
+#endif // XAODTRUTH_TRUTHPARTICLEAUXCONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthParticleContainer.h b/xAOD/xAODTruth/xAODTruth/TruthParticleContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea98e5bea32a550b9e65a913ab35e2261a7eb2d1
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthParticleContainer.h
@@ -0,0 +1,24 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthParticleContainer.h 622193 2014-10-16 16:08:34Z krasznaa $
+#ifndef XAODTRUTH_TRUTHPARTICLECONTAINER_H
+#define XAODTRUTH_TRUTHPARTICLECONTAINER_H
+
+// Local include(s):
+#include "xAODTruth/TruthParticle.h"
+#include "xAODTruth/versions/TruthParticleContainer_v1.h"
+
+namespace xAOD {
+   /// Declare the latest version of the truth particle container
+   typedef TruthParticleContainer_v1 TruthParticleContainer;
+}
+
+// Declare a CLID for the class for Athena:
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TruthParticleContainer, 1237340765, 1 )
+
+#endif // XAODTRUTH_TRUTHPARTICLECONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthVertex.h b/xAOD/xAODTruth/xAODTruth/TruthVertex.h
new file mode 100644
index 0000000000000000000000000000000000000000..183d7f8e5b36f1ec414558a31fb18247c947c2ec
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthVertex.h
@@ -0,0 +1,19 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRUTH_TRUTHVERTEX_H
+#define XAODTRUTH_TRUTHVERTEX_H
+
+#include "xAODTruth/versions/TruthVertex_v1.h"
+
+namespace xAOD {
+
+  /// Typedef to implementation
+  typedef TruthVertex_v1 TruthVertex;
+
+}
+
+#endif
diff --git a/xAOD/xAODTruth/xAODTruth/TruthVertexAuxContainer.h b/xAOD/xAODTruth/xAODTruth/TruthVertexAuxContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..014b3a6342de3a4a55bceb9f27f189b48279a248
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthVertexAuxContainer.h
@@ -0,0 +1,23 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthVertexAuxContainer.h 622081 2014-10-16 00:55:18Z abuckley $
+#ifndef XAODTRUTH_TRUTHVERTEXAUXCONTAINER_H
+#define XAODTRUTH_TRUTHVERTEXAUXCONTAINER_H
+
+// Local include(s):
+#include "xAODTruth/versions/TruthVertexAuxContainer_v1.h"
+
+namespace xAOD {
+   /// Declare the latest version of the truth vertex auxiliary container
+   typedef TruthVertexAuxContainer_v1 TruthVertexAuxContainer;
+}
+
+// Declare a CLID for the class
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TruthVertexAuxContainer, 1254939514, 1 )
+
+#endif // XAODTRUTH_TRUTHVERTEXAUXCONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/TruthVertexContainer.h b/xAOD/xAODTruth/xAODTruth/TruthVertexContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a7a99c8eaca0d3a962e45ba378dc496e116f763
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/TruthVertexContainer.h
@@ -0,0 +1,24 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthVertexContainer.h 622193 2014-10-16 16:08:34Z krasznaa $
+#ifndef XAODTRUTH_TRUTHVERTEXCONTAINER_H
+#define XAODTRUTH_TRUTHVERTEXCONTAINER_H
+
+// Local include(s):
+#include "xAODTruth/TruthVertex.h"
+#include "xAODTruth/versions/TruthVertexContainer_v1.h"
+
+namespace xAOD {
+   /// Declare the latest version of the truth vertex container
+   typedef TruthVertexContainer_v1 TruthVertexContainer;
+}
+
+// Declare a CLID for the class for Athena:
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TruthVertexContainer, 1239726567, 1 )
+
+#endif // XAODTRUTH_TRUTHVERTEXCONTAINER_H
diff --git a/xAOD/xAODTruth/xAODTruth/selection.xml b/xAOD/xAODTruth/xAODTruth/selection.xml
new file mode 100644
index 0000000000000000000000000000000000000000..abd3914cc9dc22eb499e32663223671bd17455b1
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/selection.xml
@@ -0,0 +1,77 @@
+<!-- $Id: selection.xml 670153 2015-05-27 11:42:29Z tbisanz $ -->
+<lcgdict>
+
+  <!-- The TruthParticle_v1 class(es): -->
+  <class name="xAOD::TruthParticle_v1" >
+    <field name="m_p4" transient="true" />
+    <field name="m_p4Cached" transient="true" />
+  </class>
+  <read sourceClass="xAOD::TruthParticle_v1" version="[1-]"
+        targetClass="xAOD::TruthParticle_v1" source="" target="m_p4Cached" >
+    <![CDATA[
+       m_p4Cached = false;
+    ]]>
+  </read>
+  <class name="xAOD::TruthParticle_v1::Polarization" />
+
+  <!-- The TruthVertex_v1 class: -->
+  <class name="xAOD::TruthVertex_v1" >
+    <field name="m_v4" transient="true" />
+    <field name="m_v4Cached" transient="true" />
+  </class>
+  <read sourceClass="xAOD::TruthVertex_v1" version="[1-]"
+        targetClass="xAOD::TruthVertex_v1" source="" target="m_v4Cached" >
+    <![CDATA[
+       m_v4Cached = false;
+    ]]>
+  </read>
+
+  <!-- The TruthEvent_v1 class(es): -->
+  <class name="xAOD::TruthEventBase_v1" />
+  <class name="xAOD::TruthEventBaseContainer_v1" />
+  <class name="xAOD::TruthEvent_v1" />
+  <class name="xAOD::TruthPileupEvent_v1" />
+  <class name="xAOD::TruthEvent_v1::PdfInfo" />
+  <class name="xAOD::TruthMetaData_v1" />
+
+  <!-- The persistent classes: -->
+  <class name="xAOD::TruthParticleContainer_v1"
+         id="58F98A16-E465-4CA5-A099-73033206D8E3" />
+  <class name="xAOD::TruthVertexContainer_v1"
+         id="5FBAE0AB-09F7-4B6C-B066-0A003FC38ECF" />
+  <class name="xAOD::TruthEventContainer_v1"
+         id="6290F297-F529-40EE-9FE5-1C577678306D" />
+  <class name="xAOD::TruthPileupEventContainer_v1"
+         id="05ECB16C-A36F-4853-8BB7-C9E7A84B4677" />
+  <class name="xAOD::TruthMetaDataContainer_v1"
+         id="754BDA89-C0D9-43BF-B468-32E10C1690FE" />
+
+  <class name="xAOD::TruthParticleAuxContainer_v1"
+         id="BA8FA08F-8DD6-420D-97D5-8B54EABECD65" />
+  <class name="xAOD::TruthVertexAuxContainer_v1"
+         id="B6BD3B02-C411-4EB9-903F-5B099D3B1A3E" />
+  <class name="xAOD::TruthEventAuxContainer_v1"
+         id="1B945EFD-4F7D-4BDD-9FB1-6FB975315961" />
+  <class name="xAOD::TruthPileupEventAuxContainer_v1"
+         id="9E9DD653-247C-4D5E-B14C-538EADEA6CD2" />
+  <class name="xAOD::TruthMetaDataAuxContainer_v1"
+         id="E2EF5F89-DFFA-4225-823E-29E40130A7B2" />
+
+  <!-- Smart pointers for TruthParticle_v1: -->
+  <class name="DataLink<xAOD::TruthParticleContainer_v1>" />
+  <class name="std::vector<DataLink<xAOD::TruthParticleContainer_v1> >" />
+  <class name="ElementLink<xAOD::TruthParticleContainer_v1>" />
+  <class name="std::vector<ElementLink<xAOD::TruthParticleContainer_v1> >" />
+  <class name="std::vector<std::vector<ElementLink<xAOD::TruthParticleContainer_v1> > >" />
+
+  <!-- Smart pointers for TruthVertex_v1: -->
+  <class name="DataLink<xAOD::TruthVertexContainer_v1>" />
+  <class name="std::vector<DataLink<xAOD::TruthVertexContainer_v1> >" />
+  <class name="ElementLink<xAOD::TruthVertexContainer_v1>" />
+  <class name="std::vector<ElementLink<xAOD::TruthVertexContainer_v1> >" />
+  <class name="std::vector<std::vector<ElementLink<xAOD::TruthVertexContainer_v1> > >" />
+
+  <!-- The helper functions: -->
+  <function pattern="xAOD::TruthHelpers::*" />
+
+</lcgdict>
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthEvent.h b/xAOD/xAODTruth/xAODTruth/versions/TruthEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..38f90cbf48026b76e8c3482c389ece970d46b582
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthEvent.h
@@ -0,0 +1,200 @@
+#ifndef XAODTRUTH_TRUTHEVENT_H
+#define XAODTRUTH_TRUTHEVENT_H
+
+// System include(s):
+#include <utility>
+#include <vector>
+
+// EDM include(s):
+#include "AthContainers/AuxElement.h"
+#include "AthLinks/ElementLink.h"
+#include "xAODBase/ObjectType.h"
+
+// Local include(s):
+#include "xAODTruth/TruthEventBase.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthVertexContainer.h"
+
+namespace xAOD {
+
+   /// Class describing a signal truth event in the MC record
+   ///
+   class TruthEvent : public SG::AuxElement {
+
+   public:
+      /// Default constructor
+      TruthEvent();
+      /// Virtual destructor, to make vtable happy
+      virtual ~TruthEvent() {}
+
+      /// @name Access to all the particles associated with the event
+      /// @{
+
+      /// Type of a single truth particle link
+      typedef ElementLink< TruthParticleContainer > TruthParticleLink_t;
+      /// Type of the truth particle links vector
+      typedef std::vector< TruthParticleLink_t > TruthParticleLinks_t;
+
+      /// Get all the truth particles
+      const TruthParticleLinks_t& truthParticleLinks() const;
+      /// Set all the truth particles
+      void setTruthParticleLinks( const TruthParticleLinks_t& plinks );
+      /// Get the number of truth particles
+      size_t nTruthParticles() const;
+      /// Get the link to one of the truth particles
+      const TruthParticleLink_t& truthParticleLink( size_t index ) const;
+      /// Get a pointer to one of the truth particles
+      const TruthParticle* truthParticle( size_t index ) const;
+      /// Add one truth particle
+      void addTruthParticleLink( const TruthParticleLink_t& plink );
+      /// Remove all truth particles
+      void clearTruthParticleLinks();
+
+      /// @}
+      
+      /// @name Access to all the vertices associated with the event
+      /// @{
+
+      /// Type of a single truth vertex link
+      typedef ElementLink< TruthVertexContainer > TruthVertexLink_t;
+      /// Type of the truth particle links vector
+      typedef std::vector< TruthVertexLink_t > TruthVertexLinks_t;
+
+      /// Get all the truth vertices
+      const TruthVertexLinks_t& truthVertexLinks() const;
+      /// Set all the truth vertices
+      void setTruthVertexLinks( const TruthVertexLinks_t& links );
+      /// Get the number of truth vertices
+      size_t nTruthVertices() const;
+      /// Get the link to one of the truth vertices
+      const TruthVertexLink_t& truthVertexLink( size_t index ) const;
+      /// Get a pointer to one of the truth vertices
+      const TruthVertex* truthVertex( size_t index ) const;
+      /// Add one truth vertex
+      void addTruthVertexLink( const TruthVertexLink_t& vlink );
+      /// Remove all truth vertices
+      void clearTruthVertexLinks();
+
+      /// @}
+      
+      /// @name Simple event properties
+      /// @{
+
+      /// Const access to the weights vector
+      /// @todo Need to add the map-like interface for the weights: very important!
+      const std::vector< float >& weights() const;
+      /// Set the event weights
+      /// @todo Need to add named weight access: vector<string>
+      void setWeights( const std::vector< float >& weights );
+
+      /// Get the cross section
+      float crossSection() const;
+      /// Set the cross-section
+      void setCrossSection( float value );
+
+      /// Get the cross section error
+      float crossSectionError() const;
+      /// Set the cross-section error
+      void setCrossSectionError( float value );
+
+      /// Set the cross-section and its error
+      void setCrossSection( float value, float error );
+
+      /// @}
+
+      /// @name Parton density info
+      ///
+      /// Optional due to particle gun & NLO events where a single PDF info
+      /// doesn't work.
+      ///
+      /// @{
+
+      /// Accessor enums for PDF info parameter lookup
+      enum PdfParam {
+         PDGID1 = 0, ///< [int]
+         PDGID2 = 1, ///< [int]
+         PDFID1 = 2, ///< [int]
+         PDFID2 = 3, ///< [int]
+         X1 = 4,     ///< [float]
+         X2 = 5,     ///< [float]
+         SCALE = 6,  ///< Not implemented!!!
+         Q = 6,      ///< [float]
+         PDF1 = 7,   ///< Not implemented!!!
+         PDF2 = 8,   ///< Not implemented!!!
+         XF1 = 7,    ///< [float]
+         XF2 = 8     ///< [float]
+      }; // enum PdfParam
+
+      /// Read an integer PDF info parameter
+      bool pdfInfoParameter( int& value, PdfParam parameter ) const;
+      /// Read a floating point PDF info parameter
+      bool pdfInfoParameter( float& value, PdfParam parameter ) const;
+
+      /// Set an integer PDF info parameter
+      bool setPdfInfoParameter( int value, PdfParam parameter );
+      /// Set a floating point PDF info parameter
+      bool setPdfInfoParameter( float value, PdfParam parameter );
+
+      /// Helper struct holding a full set of PDF info values
+      struct PdfInfo {
+
+         /// Constructor to set (invalid) defaults
+         PdfInfo();
+
+         /// Check if all the variables in the object are valid
+         bool valid() const;
+
+         int pdgId1;
+         int pdgId2;
+         int pdfId1;
+         int pdfId2;
+         float x1;
+         float x2;
+         float Q;
+         float xf1;
+         float xf2;
+
+      }; // struct PdfInfo
+
+      /// Retrieve a full PdfInfo with a single call
+      /// @note May have invalid values -- use valid() to check.
+      PdfInfo pdfInfo() const;
+
+      /// @}
+
+      /// @name Links to particles and vertices in the event
+      /// @{
+
+      /// Pointer to a vertex representing the primary interaction point
+      ///
+      /// The naming of the function is a bit misleading. The returned vertex
+      /// can only be interpreted as an interaction *position*.
+      ///
+      const TruthVertex* signalProcessVertex() const;
+      /// Link to the vertex representing the primary interaction point
+      const TruthVertexLink_t& signalProcessVertexLink() const;
+      /// Set pointer to a vertex representing the primary interaction point
+      void setSignalProcessVertexLink( const TruthVertexLink_t& link );
+
+      /// Get the link to the first incoming primary particle
+      const TruthParticleLink_t& primaryParticleLink() const;
+      /// Set one incoming primary particle
+      void setPrimaryParticleLink( const TruthParticleLink_t& pcl );
+
+      /// @}
+
+      /// The type of the object as a simple enumeration
+      virtual Type::ObjectType type() const;
+
+      /// Function making sure that the object is ready for persistification
+      void toPersistent();
+
+   }; // class TruthEvent
+
+} // namespace xAOD
+
+// Declare the base class of TruthEvent to StoreGate:
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthEvent, SG::AuxElement );
+
+#endif // XAODTRUTH_TRUTHEVENT_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthMetaDataAuxContainer_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthMetaDataAuxContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..aec914664b52160c49992d4b0ad2ddc5a3d8dce6
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthMetaDataAuxContainer_v1.h
@@ -0,0 +1,51 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+#ifndef XAODTRUTH_VERSIONS_TRUTHMETADATAAUXCONTAINER_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHMETADATAAUXCONTAINER_V1_H
+
+// System include(s):
+#include <vector>
+
+// EDM include(s):
+#include "AthLinks/ElementLink.h"
+#include "xAODCore/AuxContainerBase.h"
+
+// Local include(s):
+#include "xAODTruth/TruthParticleContainer.h"
+
+namespace xAOD {
+
+  /// Auxiliary store for the truth meta data
+  ///
+  /// @author Tobias Bisanz <tobias.bisanz@cern.ch>
+  ///
+  /// $Revision$
+  /// $Date$
+  ///
+  class TruthMetaDataAuxContainer_v1 : public AuxContainerBase {
+
+  public:
+    /// Default constructor
+    TruthMetaDataAuxContainer_v1();
+
+  private:
+    //Two vectors (of vectors) to store association between weight name and weight
+    //index. No std::map is used for increased read-back speed in ROOT
+    std::vector < std::vector < std::string > > weightNames;
+    std::vector < uint32_t > mcChannelNumber;
+
+  }; // class TruthMetaDataAuxContainer_v1
+
+} // namespace xAOD
+
+
+// StoreGate registration
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthMetaDataAuxContainer_v1, xAOD::AuxContainerBase );
+
+#endif // XAODTRUTH_VERSIONS_TRUTHMETADATAAUXCONTAINER_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthMetaDataContainer_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthMetaDataContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..93a6633a86d2d604cb54b962afdbf842e0c3a677
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthMetaDataContainer_v1.h
@@ -0,0 +1,22 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+#ifndef XAODTRUTH_VERSIONS_TRUTHMETADATACONTAINER_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHMETADATACONTAINER_V1_H
+
+// EDM include(s):
+#include "AthContainers/DataVector.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthMetaData_v1.h"
+
+namespace xAOD {
+   // Alias
+   typedef DataVector< TruthMetaData_v1 > TruthMetaDataContainer_v1;
+}
+
+#endif // XAODTRUTH_VERSIONS_TRUTHMETADATACONTAINER_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthMetaData_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthMetaData_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd48d625979ab35333d96b32ac8fa0fc85356db1
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthMetaData_v1.h
@@ -0,0 +1,55 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+#ifndef XAODTRUTH_VERSIONS_TRUTHMETADATA_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHMETADATA_V1_H
+
+// EDM include(s):
+#include "AthContainers/AuxElement.h"
+#include "AthLinks/ElementLink.h"
+
+// xAOD include(s):
+#include "xAODBase/ObjectType.h"
+
+namespace xAOD {
+
+   /// Class describing meta data for truth records
+   ///
+   ///
+   /// @author Tobias Bisanz <tobias.bisanz@cern.ch>
+   ///
+   /// $Revision$
+   /// $Date$
+   ///
+   class TruthMetaData_v1 : public SG::AuxElement {
+
+   public:
+      /// Default constructor
+      TruthMetaData_v1();
+
+      /// @name Simple truth meta data properties 
+      /// @{
+
+      uint32_t mcChannelNumber() const;
+      void setMcChannelNumber( uint32_t value );
+
+      const std::vector< std::string >& weightNames() const;
+      void setWeightNames( const std::vector< std::string >& value );
+
+      /// @}
+
+   private:
+   
+   }; // class TruthMetaData_v1
+
+} // namespace xAOD
+
+// Declare the inheritance of the type to StoreGate:
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthMetaData_v1, SG::AuxElement );
+
+#endif // XAODTRUTH_VERSIONS_TRUTHMETADATA_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthParticleAuxContainer_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthParticleAuxContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..5670ccc61b869bdc9b4e4e49b7231e259baae908
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthParticleAuxContainer_v1.h
@@ -0,0 +1,55 @@
+// -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef XAODTRUTH_VERSIONS_TRUTHPARTICLEAUXCONTAINER_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHPARTICLEAUXCONTAINER_V1_H
+
+#include <vector>
+
+#include "AthLinks/ElementLink.h"
+#include "xAODCore/AuxContainerBase.h"
+
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthVertexContainer.h"
+
+namespace xAOD {
+
+
+  /// Auxiliary store for the truth vertices
+  ///
+  /// @author Andy Buckley <Andy.Buckey@cern.ch>
+  /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+  /// @author Jovan Mitrevski <Jovan.Mitrevski@cern.h>
+  ///
+  class TruthParticleAuxContainer_v1 : public AuxContainerBase {
+
+  public:
+    /// Default constructor
+    TruthParticleAuxContainer_v1();
+
+  private:
+    std::vector< int > pdgId;
+    std::vector< int > barcode;
+    std::vector< int > status;
+    std::vector< ElementLink< TruthVertexContainer > > prodVtxLink;
+    std::vector< ElementLink< TruthVertexContainer > > decayVtxLink;
+    std::vector< float > px;
+    std::vector< float > py;
+    std::vector< float > pz;
+    std::vector< float > e;
+    std::vector< float > m; // needed since not necessarily on shell
+
+  }; // class TruthParticleAuxContainer_v1
+
+} // namespace xAOD
+
+
+// StoreGate registration
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthParticleAuxContainer_v1, xAOD::AuxContainerBase );
+
+
+#endif // XAODTRUTH_VERSIONS_TRUTHPARTICLEAUXCONTAINER_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthParticleContainer_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthParticleContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..4bee9879f63ca4729110c988001e81d539a82e1d
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthParticleContainer_v1.h
@@ -0,0 +1,24 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthParticleContainer_v1.h 622193 2014-10-16 16:08:34Z krasznaa $
+#ifndef XAODTRUTH_VERSIONS_TRUTHPARTICLECONTAINER_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHPARTICLECONTAINER_V1_H
+
+// EDM include(s):
+#include "AthContainers/DataVector.h"
+#include "xAODBase/IParticleContainer.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthParticle_v1.h"
+#include "xAODTruth/TruthParticleContainerFwd.h" // Only as long as this is the most recent version...
+
+namespace xAOD {
+   // Alias
+   typedef DataVector< TruthParticle_v1 > TruthParticleContainer_v1;
+}
+
+#endif // XAODTRUTH_VERSIONS_TRUTHPARTICLECONTAINER_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthParticle_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthParticle_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6f65a248f015e9784c684df8965ae82b1f51299
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthParticle_v1.h
@@ -0,0 +1,381 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthParticle_v1.h 624338 2014-10-27 15:08:55Z krasznaa $
+#ifndef XAODTRUTH_VERSIONS_TRUTHPARTICLE_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHPARTICLE_V1_H
+
+// EDM include(s):
+#include "AthLinks/ElementLink.h"
+
+// xAOD include(s):
+#include "xAODBase/IParticle.h"
+#include "xAODBase/ObjectType.h"
+
+// Local include(s):
+#include "xAODTruth/TruthVertexContainerFwd.h"
+
+namespace xAOD {
+
+   /// Class describing a truth particle in the MC record
+   ///
+   /// The xAOD truth record mimicks the structure of HepMC. Truth particles
+   /// and truth vertices form a decay tree. Where each truth particle is
+   /// connected to a single production and decay vertex. And each vertex is
+   /// connected to one or more incoming, and one or more outgoing particles.
+   ///
+   /// @author Andy Buckley <Andy.Buckley@cern.ch>
+   /// @author Jovan Mitrevski <Jovan.Mitrevski@cern.ch>
+   ///
+   /// $Revision: 624338 $
+   /// $Date: 2014-10-27 16:08:55 +0100 (Mon, 27 Oct 2014) $
+   ///
+   class TruthParticle_v1 : public IParticle {
+
+   public:
+      /// Default constructor
+      TruthParticle_v1();
+
+      /// @name Functions identifying the particle in the MC record
+      /// @{
+
+      /// Set PDG ID code
+      void setPdgId( int pid );
+      /// PDG ID code
+      int pdgId() const;
+      /// Absolute PDG ID code (often useful)
+      int absPdgId() const;
+
+      /// Barcode
+      /// @note Meaning of barcode may change -- be careful!
+      int barcode() const;
+      /// Set barcode
+      void setBarcode( int value );
+
+      /// Status code
+      int status() const;
+      /// Set status code
+      void setStatus( int value );
+
+      /// @}
+
+      /// @name Links to the production and decay vertices
+      /// @{
+
+      /// Check for a production vertex on this particle
+      bool hasProdVtx() const;
+      /// The production vertex of this particle
+      const TruthVertex_v1* prodVtx() const;
+      /// The production vertex link of this particle
+      const ElementLink< TruthVertexContainer >& prodVtxLink() const;
+      /// Set the production vertex of the particle
+      void setProdVtxLink( const ElementLink< TruthVertexContainer >& link );
+
+      /// Check for a decay vertex on this particle
+      bool hasDecayVtx() const;
+      /// The decay vertex of this particle
+      const TruthVertex_v1* decayVtx() const;
+      /// The decay vertex link of this particle
+      const ElementLink< TruthVertexContainer >& decayVtxLink() const;
+      /// Set the decay vertex of the particle
+      void setDecayVtxLink( const ElementLink< TruthVertexContainer >& link );
+
+      /// @}
+
+      /// @name Particle connection / origin / decay information
+      /// @{
+
+      /// Number of parents of this particle
+      size_t nParents() const;
+
+      /// Retrieve the i-th mother (TruthParticle) of this TruthParticle
+      const TruthParticle_v1* parent( size_t i = 0 ) const;
+
+      /// Number of children of this particle
+      size_t nChildren() const;
+
+      /// Retrieve the i-th mother (TruthParticle) of this TruthParticle
+      const TruthParticle_v1* child( size_t i = 0 ) const;
+
+      /// @todo Add mappings of e.g. isPrimary, isDecayed, isPrompt,
+      /// isFromDecay, hasHadronicDecay, hasLeptonicDecay,
+      /// isHadronic/LeptonicTau ...
+
+      /// @todo Add isFirstWith, isLastWith
+
+      /// @}
+
+      /// @name Functions implementing the xAOD::IParticle interface
+      /// @{
+
+      /// The transverse momentum (\f$p_T\f$) of the particle
+      virtual double pt() const;
+      /// The pseudorapidity (\f$\eta\f$) of the particle
+      virtual double eta() const;
+      /// The azimuthal angle (\f$\phi\f$) of the particle
+      virtual double phi() const;
+      /// The mass of the particle
+      ///
+      /// Note, not necessarily = \f$E^2-p^2\f$ if not on mass shell.
+      ///
+      virtual double m() const;
+      /// The total energy of the particle
+      virtual double e() const;
+      /// The true rapidity (\f$y\f$) of the particle
+      virtual double rapidity() const;
+
+      /// Definition of the 4-momentum type
+      typedef IParticle::FourMom_t FourMom_t;
+
+      /// The full 4-momentum of the particle
+      ///
+      /// Note that m may not be right, though, if not on mass shell. In which
+      /// case <code>p4().M()</code> will be different from <code>m()</code>.
+      ///
+      virtual const FourMom_t& p4() const;
+
+      /// The type of the object as a simple enumeration
+      virtual Type::ObjectType type() const;
+
+      /// @}
+
+      /// @name 4-momentum accessors specific to truth particles
+      /// @{
+
+      /// The absolute pseudorapidity (\f$|\eta|\f$) of the particle
+      /// @todo Remove this when/if supported in xAOD::IParticle
+      double abseta() const;
+      /// The true absolute rapidity (\f$|y|\f$) of the particle
+      /// @todo Remove this when/if supported in xAOD::IParticle
+      double absrapidity() const;
+
+      /// The x component of the particle's momentum
+      float px() const;
+      /// Set the x component of the particle's momentum
+      void setPx( float value );
+
+      /// The y component of the particle's momentum
+      float py() const;
+      /// Set the y component of the particle's momentum
+      void setPy( float value );
+
+      /// The z component of the particle's momentum
+      float pz() const;
+      /// Set the z component of the particle's momentum
+      void setPz( float value );
+
+      /// Set the energy of the particle
+      void setE( float value );
+
+      /// Also store the mass
+      void setM( float value );
+
+      /// @}
+
+      /// @name Particle species information
+      ///
+      /// Just convenience methods here, since they all just forward to the
+      /// utility functions operating on the PDG particle ID code.
+      ///
+      /// @{
+
+      /// Physical charge
+      double charge() const;
+      /// 3 x the physical charge (so it can be an int for quarks)
+      int threeCharge() const;
+
+      /// Whether the particle is electrically charged
+      bool isCharged() const;
+      /// Whether the particle is electrically neutral
+      bool isNeutral() const;
+
+      /// Whether the particle is a photon
+      bool isPhoton() const;
+      /// Whether the particle is a lepton
+      bool isLepton() const;
+      /// Whether the particle is a charged lepton
+      bool isChLepton() const;
+      /// Whether the particle is an electron (or positron)
+      bool isElectron() const;
+      /// Whether the particle is a muon (or antimuon)
+      bool isMuon() const;
+      /// Whether the particle is a tau (or antitau)
+      bool isTau() const;
+      /// Whether the particle is a neutrino (or antineutrino)
+      bool isNeutrino() const;
+
+      /// Whether the particle is a hadron
+      bool isHadron() const;
+      /// Whether the particle is a meson
+      bool isMeson() const;
+      /// Whether the particle is a baryon
+      bool isBaryon() const;
+
+      /// Whether the particle contains a strange quark (or antiquark)
+      bool hasStrange() const;
+      /// Whether the particle contains a charm quark (or antiquark)
+      bool hasCharm() const;
+      /// Whether the particle contains a bottom quark (or antiquark)
+      bool hasBottom() const;
+
+      /// Determine if the PID is that of a light flavour (not b or c) meson
+      bool isLightMeson() const;
+      /// Determine if the PID is that of a light flavour (not b or c) baryon
+      bool isLightBaryon() const;
+      /// Determine if the PID is that of a light flavour (not b or c) hadron
+      bool isLightHadron() const;
+
+      /// Determine if the PID is that of a heavy flavour (b or c) meson
+      bool isHeavyMeson() const;
+      /// Determine if the PID is that of a heavy flavour (b or c) baryon
+      bool isHeavyBaryon() const;
+      /// Determine if the PID is that of a heavy flavour (b or c) hadron
+      bool isHeavyHadron() const;
+
+      /// Determine if the PID is that of a b-meson.
+      bool isBottomMeson() const;
+      /// Determine if the PID is that of a b-baryon.
+      bool isBottomBaryon() const;
+      /// Determine if the PID is that of a b-hadron.
+      bool isBottomHadron() const;
+
+      /// @brief Determine if the PID is that of a c-meson.
+      ///
+      /// Specifically, the _heaviest_ quark is a c: a B_c is a b-meson and NOT
+      /// a c-meson. Charmonia (closed charm) are counted as c-mesons here.
+      ///
+      bool isCharmMeson() const;
+      /// @brief Determine if the PID is that of a c-baryon.
+      ///
+      /// Specifically, the _heaviest_ quark is a c: a baryon containing a b & c
+      /// is a b-baryon and NOT a c-baryon. To test for the simpler case, just
+      /// use a combination of hasCharm() and isBaryon().
+      ///
+      bool isCharmBaryon() const;
+      /// Determine if the PID is that of a c-hadron.
+      bool isCharmHadron() const;
+
+      /// Determine if the PID is that of a strange meson
+      bool isStrangeMeson() const;
+      /// Determine if the PID is that of a strange baryon
+      bool isStrangeBaryon() const;
+      /// Determine if the PID is that of a strange hadron
+      bool isStrangeHadron() const;
+
+      /// Check if this particle is a quark
+      bool isQuark() const;
+      /// Check if this particle is a parton
+      bool isParton() const;
+      /// Check if this particle is a top quark
+      bool isTop() const;
+      /// Check if this particle is a W boson
+      bool isW() const;
+      /// Check if this particle is a Z boson
+      bool isZ() const;
+      /// Check if this particle is a Higgs boson
+      bool isHiggs() const;
+      /// Check if this particle is a resonant state
+      bool isResonance() const;
+      /// Check if this is a generator specific (non-physical) particle
+      bool isGenSpecific() const;
+
+      /// @}
+
+      /// @name Polarization properties (optional)
+      /// @{
+
+      /// Polarization parameter types
+      enum PolParam {
+         polarizationPhi   = 0, ///< Polarization in (\f$\phi\f$)
+         polarizationTheta = 1  ///< Polarization in (\f$\theta\f$)
+      };
+
+      /// Accessor for polarization parameters
+      ///
+      /// Generic C++ code should use this function to retrieve the polarization
+      /// parameters of a truth particle. Since these parameters are optional,
+      /// the function is designed to tell the user whether the requested
+      /// parameter could be retrieved or not.
+      ///
+      /// @param value The polarization parameter value read from the object
+      /// @param parameter The polarization parameter that we are interested in
+      /// @return <code>true</code> if the retrieval was successful,
+      ///         <code>false</code> if it wasn't
+      ///
+      bool polarizationParameter( float& value, PolParam parameter ) const;
+
+      /// Set method for polarization parameter values
+      ///
+      /// In order to keep the symmetry with the getter function, this setter
+      /// communicates a possible failure in its operation through a return
+      /// value. Setting a polariozation parameter is much less likely to fail
+      /// than retrieving one, but in some situations it may still happen...
+      ///
+      /// @param value The polarization parameter value to set on the object
+      /// @param parameter The polarization parameter type that we want to set
+      /// @return <code>true</code> if the operation was successful, or
+      ///         <code>false</code> if it wasn't
+      ///
+      bool setPolarizationParameter( float value, PolParam parameter );
+
+      /// Convenience accessor for a polariozation parameter.
+      ///
+      /// Throws an exception if the request can't be completed. It should
+      /// mostly be used in PyROOT, as the other form of this function is very
+      /// hard to use there. But one needs to know for sure that the requested
+      /// parameter will exist.
+      ///
+      /// @param parameter The polarion parameter that we are interested in
+      /// @return The value of the polarization parameter requested
+      ///
+      float polarizationPatameter( PolParam parameter ) const;
+
+      /// Single container for full polarization information
+      ///
+      /// It can be used as a convenient way for accessing the polarization of
+      /// the particle with a single call.
+      ///
+      struct Polarization {
+
+         /// Constructor to set (invalid) defaults
+         /// @todo Use C++11 inline member init when allowed
+         Polarization()
+         : phi( -1.0 ), theta( -1.0 ) {}
+
+         /// Check if the stored values are valid
+         bool valid() const {
+            return ( ( phi > 0.0 ) && ( theta > 0.0 ) );
+         }
+
+         float phi;   ///< Polarization in (\f$\phi\f$)
+         float theta; ///< Polarization in (\f$\theta\f$)
+
+      }; // struct Polarization
+
+      /// Retrieve a full Polarization with a single call
+      ///
+      /// @note May have invalid values -- use valid() to check.
+      ///
+      /// @return An object holding the full polarization information
+      ///
+      Polarization polarization() const;
+
+      /// @}
+
+      /// Function making sure that the object is ready for persistification
+      void toPersistent();
+
+   private:
+      /// Cached four momentum
+      mutable FourMom_t m_p4;
+      /// Flag specifying if the four-momentum is cached
+      mutable bool m_p4Cached;
+
+   }; // class TruthParticle_v1
+
+} // namespace xAOD
+
+#endif // XAODTRUTH_VERSIONS_TRUTHPARTICLE_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthVertexAuxContainer_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthVertexAuxContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc988e1337e4463dddb99d47b900553b3cb89533
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthVertexAuxContainer_v1.h
@@ -0,0 +1,58 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthVertexAuxContainer_v1.h 624338 2014-10-27 15:08:55Z krasznaa $
+#ifndef XAODTRUTH_VERSIONS_TRUTHVERTEXAUXCONTAINER_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHVERTEXAUXCONTAINER_V1_H
+
+// System include(s):
+#include <vector>
+
+// EDM include(s):
+#include "AthLinks/ElementLink.h"
+#include "xAODCore/AuxContainerBase.h"
+
+// Local include(s):
+#include "xAODTruth/TruthParticleContainer.h"
+
+namespace xAOD {
+
+  /// Auxiliary store for the truth vertices
+  ///
+  /// @author Andy Buckley <Andy.Buckey@cern.ch>
+  /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+  ///
+  /// $Revision: 624338 $
+  /// $Date: 2014-10-27 16:08:55 +0100 (Mon, 27 Oct 2014) $
+  ///
+  class TruthVertexAuxContainer_v1 : public AuxContainerBase {
+
+  public:
+    /// Default constructor
+    TruthVertexAuxContainer_v1();
+
+  private:
+    std::vector< int > id;
+    std::vector< int > barcode;
+    std::vector< std::vector< ElementLink< TruthParticleContainer > > >
+    incomingParticleLinks;
+    std::vector< std::vector< ElementLink< TruthParticleContainer > > >
+    outgoingParticleLinks;
+    std::vector< float > x;
+    std::vector< float > y;
+    std::vector< float > z;
+    std::vector< float > t;
+
+  }; // class TruthVertexAuxContainer_v1
+
+} // namespace xAOD
+
+
+// StoreGate registration
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthVertexAuxContainer_v1, xAOD::AuxContainerBase );
+
+#endif // XAODTRUTH_VERSIONS_TRUTHVERTEXAUXCONTAINER_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthVertexContainer_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthVertexContainer_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..3851af60d1d46d2bb901cf17f39ebc76a82903e5
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthVertexContainer_v1.h
@@ -0,0 +1,23 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthVertexContainer_v1.h 622193 2014-10-16 16:08:34Z krasznaa $
+#ifndef XAODTRUTH_VERSIONS_TRUTHVERTEXCONTAINER_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHVERTEXCONTAINER_V1_H
+
+// EDM include(s):
+#include "AthContainers/DataVector.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthVertex_v1.h"
+#include "xAODTruth/TruthVertexContainerFwd.h" // Only as long as this is the most recent version...
+
+namespace xAOD {
+   // Alias
+   typedef DataVector< TruthVertex_v1 > TruthVertexContainer_v1;
+}
+
+#endif // XAODTRUTH_VERSIONS_TRUTHVERTEXCONTAINER_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/versions/TruthVertex_v1.h b/xAOD/xAODTruth/xAODTruth/versions/TruthVertex_v1.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce94b368d48d92efebe67e0d4ca10101b626effe
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/versions/TruthVertex_v1.h
@@ -0,0 +1,153 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TruthVertex_v1.h 624338 2014-10-27 15:08:55Z krasznaa $
+#ifndef XAODTRUTH_VERSIONS_TRUTHVERTEX_V1_H
+#define XAODTRUTH_VERSIONS_TRUTHVERTEX_V1_H
+
+// ROOT include(s):
+#include <TLorentzVector.h>
+
+// EDM include(s):
+#include "AthContainers/AuxElement.h"
+#include "AthLinks/ElementLink.h"
+
+// xAOD include(s):
+#include "xAODBase/ObjectType.h"
+
+// Local include(s):
+#include "xAODTruth/TruthParticleContainerFwd.h"
+
+namespace xAOD {
+
+   /// Class describing a truth vertex in the MC record
+   ///
+   /// The xAOD truth record mimicks the structure of HepMC. Truth particles
+   /// and truth vertices form a decay tree. Where each truth particle is
+   /// connected to a single production and decay vertex. And each vertex is
+   /// connected to one or more incoming, and one or more outgoing particles.
+   ///
+   /// @author Andy Buckley <Andy.Buckley@cern.ch>
+   ///
+   /// $Revision: 624338 $
+   /// $Date: 2014-10-27 16:08:55 +0100 (Mon, 27 Oct 2014) $
+   ///
+   class TruthVertex_v1 : public SG::AuxElement {
+
+   public:
+      /// Default constructor
+      TruthVertex_v1();
+
+      /// @name Functions identifying the vertex in the MC record
+      /// @{
+
+      /// Set vertex ID code
+      void setId( int value );
+      /// Vertex ID code
+      int id() const;
+
+      /// Set barcode
+      void setBarcode( int value );
+      /// Barcode
+      int barcode() const;
+
+      /// @}
+
+      /// @name Links to the particles associated with this vertex
+      /// @{
+
+      /// Type of one truth particle link
+      typedef ElementLink< TruthParticleContainer > TPLink_t;
+      /// Type used to save the links to incoming and outgoing particles
+      typedef std::vector< TPLink_t > TPLinks_t;
+
+      /// Get all the incoming particles
+      const TPLinks_t& incomingParticleLinks() const;
+      /// Set all the incoming particles
+      void setIncomingParticleLinks( const TPLinks_t& links );
+      /// Get the number of incoming particles
+      size_t nIncomingParticles() const;
+      /// Get one of the incoming particles
+      const TruthParticle_v1* incomingParticle( size_t index ) const;
+      /// Add one incoming particle
+      void addIncomingParticleLink( const TPLink_t& link );
+      /// Remove all incoming particles
+      void clearIncomingParticleLinks();
+
+      /// Get all the outgoing particles
+      const TPLinks_t& outgoingParticleLinks() const;
+      /// Set all the outgoing particles
+      void setOutgoingParticleLinks( const TPLinks_t& links );
+      /// Get the number of outgoing particles
+      size_t nOutgoingParticles() const;
+      /// Get one of the outgoing particles
+      const TruthParticle_v1* outgoingParticle( size_t index ) const;
+      /// Add one outgoing particle
+      void addOutgoingParticleLink( const TPLink_t& link );
+      /// Remove all outgoing particles
+      void clearOutgoingParticleLinks();
+
+      /// @}
+
+      /// @name Vertex position functions
+      /// @{
+
+      /// Vertex x displacement
+      float x() const;
+      /// Set the x displacement of the vertex
+      void setX( float value );
+
+      /// Vertex y displacement
+      float y() const;
+      /// Set the y displacement of the vertex
+      void setY( float value );
+
+      /// Vertex longitudinal distance along the beam line form the origin
+      float z() const;
+      /// Set the vertex's longitudinal distance from the origin
+      void setZ( float value );
+
+      /// Vertex transverse distance from the beam line
+      float perp() const;
+      /// Vertex pseudorapidity
+      float eta() const;
+      /// Vertex azimuthal angle
+      float phi() const;
+
+      /// Vertex time
+      float t() const;
+      /// Set the vertex time
+      void setT( float value );
+
+      /// The 4-vector type
+      typedef TLorentzVector FourVec_t;
+
+      /// The full 4-vector of the vertex
+      const FourVec_t& v4() const;
+
+      /// @}
+
+      /// The type of the object as a simple enumeration
+      Type::ObjectType type() const;
+
+      /// Function making sure that the object is ready for persistification
+      void toPersistent();
+
+   private:
+      /// Cached four vector
+      mutable FourVec_t m_v4;
+      /// Flag showing whether the four-vector is cached
+      mutable bool m_v4Cached;
+
+   }; // class TruthVertex_v1
+
+} // namespace xAOD
+
+// Declare the inheritance of the type to StoreGate:
+#include "xAODCore/BaseInfo.h"
+SG_BASE( xAOD::TruthVertex_v1, SG::AuxElement );
+
+#endif // XAODTRUTH_VERSIONS_TRUTHVERTEX_V1_H
diff --git a/xAOD/xAODTruth/xAODTruth/xAODTruthDict.h b/xAOD/xAODTruth/xAODTruth/xAODTruthDict.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed88b03a434bccbd99b5a889654c9757b28fbd50
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/xAODTruthDict.h
@@ -0,0 +1,56 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: xAODTruthDict.h 670153 2015-05-27 11:42:29Z tbisanz $
+#ifndef XAODTRUTH_XAODTRUTHDICT_H
+#define XAODTRUTH_XAODTRUTHDICT_H
+
+// System include(s):
+#include <vector>
+
+// EDM include(s):
+#include "AthLinks/DataLink.h"
+#include "AthLinks/ElementLink.h"
+
+// Local include(s):
+#include "xAODTruth/versions/TruthParticleContainer_v1.h"
+#include "xAODTruth/versions/TruthParticleAuxContainer_v1.h"
+#include "xAODTruth/versions/TruthVertexContainer_v1.h"
+#include "xAODTruth/versions/TruthVertexAuxContainer_v1.h"
+#include "xAODTruth/versions/TruthEventBaseContainer_v1.h"
+#include "xAODTruth/versions/TruthEventContainer_v1.h"
+#include "xAODTruth/versions/TruthEventAuxContainer_v1.h"
+#include "xAODTruth/versions/TruthPileupEventContainer_v1.h"
+#include "xAODTruth/versions/TruthPileupEventAuxContainer_v1.h"
+#include "xAODTruth/versions/TruthMetaDataContainer_v1.h"
+#include "xAODTruth/versions/TruthMetaDataAuxContainer_v1.h"
+#include "xAODTruth/xAODTruthHelpers.h"
+
+namespace {
+   struct GCCXML_DUMMY_INSTANTIATION_XAODTRUTH {
+      // The DataVector types:
+      xAOD::TruthParticleContainer_v1    c1;
+      xAOD::TruthVertexContainer_v1      c2;
+      xAOD::TruthEventBaseContainer_v1   c3;
+      xAOD::TruthEventContainer_v1       c4;
+      xAOD::TruthPileupEventContainer_v1 c5;
+      xAOD::TruthMetaDataContainer_v1    c6;
+
+      // The smart pointer types:
+      DataLink< xAOD::TruthParticleContainer_v1 > dl1;
+      std::vector< DataLink< xAOD::TruthParticleContainer_v1 > > dl2;
+      DataLink< xAOD::TruthVertexContainer_v1 > dl3;
+      std::vector< DataLink< xAOD::TruthVertexContainer_v1 > > dl4;
+      ElementLink< xAOD::TruthParticleContainer_v1 > el1;
+      std::vector< ElementLink< xAOD::TruthParticleContainer_v1 > > el2;
+      std::vector< std::vector< ElementLink< xAOD::TruthParticleContainer_v1 > > > el3;
+      ElementLink< xAOD::TruthVertexContainer_v1 > el4;
+      std::vector< ElementLink< xAOD::TruthVertexContainer_v1 > > el5;
+      std::vector< std::vector< ElementLink< xAOD::TruthVertexContainer_v1 > > > el6;
+   };
+}
+
+#endif // XAODTRUTH_XAODTRUTHDICT_H
diff --git a/xAOD/xAODTruth/xAODTruth/xAODTruthHelpers.h b/xAOD/xAODTruth/xAODTruth/xAODTruthHelpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..ccd679a7877ff115fca9090acc80c82ab99a36ab
--- /dev/null
+++ b/xAOD/xAODTruth/xAODTruth/xAODTruthHelpers.h
@@ -0,0 +1,37 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: xAODTruthHelpers.h 668406 2015-05-19 15:32:15Z krasznaa $
+#ifndef XAODTRUTH_XAODTRUTHHELPERS_H
+#define XAODTRUTH_XAODTRUTHHELPERS_H
+
+// Local include(s):
+#include "xAODTruth/TruthParticleFwd.h"
+
+namespace xAOD {
+
+   // Forward declaration(s):
+   class IParticle;
+
+   /// Dedicated namespace for the helper functions
+   namespace TruthHelpers {
+
+      /// Return the truthParticle associated to the given IParticle (if any)
+      const TruthParticle* getTruthParticle( const xAOD::IParticle& p );
+
+      /// Return the particle's truth type (as defined by the MC Truth
+      /// Classifier)
+      int getParticleTruthType( const xAOD::IParticle& p );
+
+      /// Return the particle's truth origin (as defined by the MC Truth
+      /// Classifier)
+      int getParticleTruthOrigin( const xAOD::IParticle& p );
+
+   } // namespace TruthHelpers
+
+} // namespace xAOD
+
+#endif // XAODTRUTH_XAODTRUTHHELPERS_H