diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 165d96d02263a8634525d3349977b154c3a5e235..0000000000000000000000000000000000000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-cmake_minimum_required(VERSION 3.6)
-
-set( ATLAS_PROJECT Athena
-   CACHE STRING	   "The name of the project to build against" )
-
-set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-
-find_package( Athena )
-
-atlas_ctest_setup()
-
-atlas_project( Faser 1.0.0
-  USE ${ATLAS_PROJECT} ${${ATLAS_PROJECT}_VERSION} )
-
-lcg_generate_env( SH_FILE ${CMAKE_BINARY_DIR}/${ATLAS_PLATFORM}/env_setup.sh )
-install( FILES ${CMAKE_BINARY_DIR}/${ATLAS_PLATFORM}/env_setup.sh
- DESTINATION . )
diff --git a/Projects/Calypso/package_filters.txt b/Projects/Calypso/package_filters.txt
index fe17656847d3ddec5d678d70f1ed496a2106c100..1eaecdb54f06cd6c309f009f84ae1e0bffa5ddb1 100644
--- a/Projects/Calypso/package_filters.txt
+++ b/Projects/Calypso/package_filters.txt
@@ -5,3 +5,8 @@
 # Don't pick up anything from the Projects directory:
 + xAOD/.*
 - Projects/.*
+- Calorimeter/.*
+- Database/.*
+- DetectorDescription/.*
+- Scintillator/.*
+- Tracker/TrackerDetDescr/.*
\ No newline at end of file
diff --git a/Tracker/TrkDetAlgs/TrkDetStripClusterFormation/TrkDetStripClusterFormation/StripClusterization.h b/Tracker/TrkDetAlgs/TrkDetStripClusterFormation/TrkDetStripClusterFormation/StripClusterization.h
new file mode 100644
index 0000000000000000000000000000000000000000..103737a0f836b5f0413544ac4a4d3ef0f29ebf79
--- /dev/null
+++ b/Tracker/TrkDetAlgs/TrkDetStripClusterFormation/TrkDetStripClusterFormation/StripClusterization.h
@@ -0,0 +1,94 @@
+#ifndef TRKDETSTRIPCLUSTERFORMATION_STRIPCLUSTERIZATION_H
+#define TRKDETSTRIPCLUSTERFORMATION_STRIPCLUSTERIZATION_H
+//STL
+#include <string>
+#include <map>
+#include <set>
+
+//Gaudi
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+// Base class
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+//InDet includes
+//Stored by value, cannot be fwd declared
+#include "Identifier/IdentifierHash.h"
+//template parameter, so should not be possible to just fwd declare
+#include "Identifier/Identifier.h"
+//Next contains a typedef so cannot be fwd declared
+#include "InDetPrepRawData/SCT_ClusterContainer.h"
+#include "InDetRawData/SCT_RDO_Container.h"
+//tool/service handle template parameters
+
+
+class SCT_ID;
+class SCT_ChannelStatusAlg;
+class SiDetectorManager;
+class ISvcLocator;
+class StatusCode;
+class ISCT_FlaggedConditionSvc;
+
+class IInDetConditionsSvc;
+namespace InDetDD{
+  class SiDetectorManager;
+}
+
+
+namespace InDet {
+  class ISCT_ClusteringTool;
+/**
+ *    @class SCT_Clusterization
+ *    @brief Form clusters from SCT Raw Data Objects
+ *    The class loops over an RDO grouping strips and creating collections of clusters, subsequently recorded in StoreGate
+ *    Uses SCT_ConditionsServices to determine which strips to include.
+ */
+class SCT_Clusterization : public AthAlgorithm {
+public:
+  /// Constructor with parameters:
+  SCT_Clusterization(const std::string &name,ISvcLocator *pSvcLocator);
+  
+  /**    @name Usual algorithm methods */
+  //@{
+  ///Retrieve the tools used and initialize variables
+  virtual StatusCode initialize();
+  ///Form clusters and record them in StoreGate (detector store)
+  virtual StatusCode execute();
+  ///Clean up and release the collection containers
+  virtual StatusCode finalize();
+  //@}
+
+
+private:
+  /**    @name Disallow default instantiation, copy, assignment */
+  //@{
+  SCT_Clusterization() = delete;
+  SCT_Clusterization(const SCT_Clusterization&) = delete;
+  SCT_Clusterization &operator=(const SCT_Clusterization&) = delete;
+  //@}
+
+  ToolHandle< ISCT_ClusteringTool >        m_clusteringTool;       //!< Clustering algorithm
+//  std::string                              m_dataObjectName;       //!< RDO container name in StoreGate
+  std::string                              m_managerName;   //REMOVE LATER       //!< Detector manager name in StoreGate
+//  std::string                              m_clustersName; //REMOVE LATER           
+//  int                                      m_page; //REMOVE LATER            //!< Page number for hash function
+  const SCT_ID*                            m_idHelper;
+//  typedef std::map<Identifier, int>        IdMap_t;//REMOVE LATER
+//  IdMap_t                                  m_status;//REMOVE LATER
+//  IdentifierHash                           m_maxKey;//REMOVE LATER
+
+
+  SG::ReadHandle<SCT_RDO_Container> m_rdoContainer; //(m_dataObjectName);
+  SG::WriteHandle<SCT_ClusterContainer>    m_clusterContainer;
+  const InDetDD::SiDetectorManager*        m_manager;
+  unsigned int                             m_maxRDOs;
+  ServiceHandle<IInDetConditionsSvc>       m_pSummarySvc;
+  ServiceHandle<ISCT_FlaggedConditionSvc>   m_flaggedConditionSvc;
+  bool                                     m_checkBadModules;
+  std::set<IdentifierHash>                 m_flaggedModules;
+  unsigned int                             m_maxTotalOccupancyPercent;
+};
+
+}
+
+#endif // TRKDETSTRIPCLUSTERFORMATION_STRIPCLUSTERIZATION_H
\ No newline at end of file
diff --git a/Tracker/TrkDetAlgs/TrkDetStripClusterFormation/src/StripClusterization.cxx b/Tracker/TrkDetAlgs/TrkDetStripClusterFormation/src/StripClusterization.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..93aef8adfc315cd3c7df0640d9fa2b06265ac469
--- /dev/null
+++ b/Tracker/TrkDetAlgs/TrkDetStripClusterFormation/src/StripClusterization.cxx
@@ -0,0 +1,218 @@
+#include "InDetPrepRawDataFormation/SCT_Clusterization.h"
+#include "InDetPrepRawData/SiClusterContainer.h"
+#include "InDetPrepRawData/SCT_ClusterCollection.h"
+#include "InDetConditionsSummaryService/IInDetConditionsSvc.h"
+#include "InDetRawData/SCT_RDORawData.h"
+#include "InDetRawData/SCT_RDO_Container.h"
+#include "InDetReadoutGeometry/SiDetectorManager.h"
+#include "AtlasDetDescr/AtlasDetectorID.h"    
+#include "InDetIdentifier/SCT_ID.h"
+#include "SCT_ConditionsServices/ISCT_FlaggedConditionSvc.h"
+#include "SiClusterizationTool/ISCT_ClusteringTool.h"
+
+#include "StoreGate/StoreClearedIncident.h"
+
+#include "GaudiKernel/PropertyMgr.h"
+#include "GaudiKernel/IIncidentSvc.h"
+#include "StoreGate/DataHandle.h"
+#include "CxxUtils/make_unique.h"
+
+namespace InDet{
+  using namespace InDet;
+  static const std::string moduleFailureReason("SCT_Clusterization: Exceeds max RDOs");
+
+// Constructor with parameters:
+  SCT_Clusterization::SCT_Clusterization(const std::string &name, ISvcLocator *pSvcLocator) :
+  AthAlgorithm(name,pSvcLocator),
+    m_clusteringTool("InDet::SCT_ClusteringTool", this),       //Changed to private  // public - does this need to be changed for athenaMT
+//    m_dataObjectName("SCT_RDOs"),                    // RDO container
+    m_managerName("SCT"),
+//    m_clustersName("NOTTHISNOTHIS"),
+//    m_page(0),                     
+    m_idHelper(nullptr),
+//    m_maxKey(0),
+    m_rdoContainer(),
+    m_clusterContainer(),
+    m_manager(nullptr),
+    m_maxRDOs(384), //(77),
+    m_pSummarySvc("SCT_ConditionsSummarySvc", name),
+    m_flaggedConditionSvc("SCT_FlaggedConditionSvc",name),
+    m_checkBadModules(true),
+    m_flaggedModules(),
+    m_maxTotalOccupancyPercent(10)
+  {  
+  // Get parameter values from jobOptions file    
+    declareProperty("DataObjectName", m_rdoContainer = SG::ReadHandle<SCT_RDO_Container> ("SCT_RDOs"), "SCT RDOs" );
+    declareProperty("DetectorManagerName",m_managerName);
+    declareProperty("clusteringTool",m_clusteringTool);    //inconsistent nomenclature!
+//    declareProperty("ClustersName",m_clustersName);
+//    declareProperty("PageNumber",m_page);
+    declareProperty("conditionsService" , m_pSummarySvc);
+    declareProperty("maxRDOs", m_maxRDOs);
+    declareProperty("checkBadModules",m_checkBadModules);
+    declareProperty("FlaggedConditionService", m_flaggedConditionSvc);
+    declareProperty("maxTotalOccupancyInPercent",m_maxTotalOccupancyPercent);
+    declareProperty("ClustersName", 
+                  m_clusterContainer = SG::WriteHandle<SCT_ClusterContainer>("SCT_Clusters"),
+                  "SCT cluster container");    
+    
+  }
+
+
+// Initialize method:
+  StatusCode SCT_Clusterization::initialize(){
+    ATH_MSG_INFO( "SCT_Clusterization::initialize()!");
+
+    // Get the conditions summary service (continue anyway, just check the pointer 
+    // later and declare everything to be 'good' if it is NULL)
+    if (m_checkBadModules){
+      ATH_MSG_INFO( "Clusterization has been asked to look at bad module info" );
+      ATH_CHECK(m_pSummarySvc.retrieve());
+    }
+
+    // Get the flagged conditions service
+    ATH_CHECK(m_flaggedConditionSvc.retrieve());
+
+    // Get the clustering tool
+    ATH_CHECK (m_clusteringTool.retrieve());
+
+    // Get the SCT manager
+    ATH_CHECK (detStore()->retrieve(m_manager,"SCT"));
+
+    // Get the SCT ID helper
+    ATH_CHECK (detStore()->retrieve(m_idHelper,"SCT_ID"));
+
+    ATH_MSG_INFO( "Container m_clusterContainer '" << m_clusterContainer.name() << "' set");
+
+    return StatusCode::SUCCESS;
+  }
+
+  
+// Execute method:
+  StatusCode SCT_Clusterization::execute(){
+  // Register the IdentifiableContainer into StoreGate
+//      ATH_MSG_INFO( "Container m_clusterContainer '" << m_clusterContainer.name() << "' set");
+   m_clusterContainer = CxxUtils::make_unique<SCT_ClusterContainer>(m_idHelper->wafer_hash_max());   
+   // declare the container:
+//   m_clusterContainer->addRef();
+   
+    SiClusterContainer* symSiContainer = nullptr;
+    StatusCode sc = evtStore()->symLink(m_clusterContainer.cptr(), symSiContainer);
+    if (sc.isFailure()) {
+      ATH_MSG_FATAL("Pixel clusters could not be symlinked in StoreGate !");
+      return StatusCode::FAILURE;
+    } else {
+      ATH_MSG_DEBUG( "Pixel clusters '" << m_clusterContainer.name() << "' symlinked in StoreGate");
+    }   
+   if (! m_clusterContainer.isValid() ){
+      msg(MSG:: FATAL) << "Container of type SCT_ClusterContainer could not be initialised !"<< endreq;
+      return StatusCode::FAILURE;
+   }else{
+    ATH_MSG_DEBUG( "Container '" << m_clusterContainer.name() << "' initialised" );
+   }
+   
+
+  // First, we have to retrieve and access the container, not because we want to 
+  // use it, but in order to generate the proxies for the collections, if they 
+  // are being provided by a container converter.
+//    const SG::ReadHandle<SCT_RDO_Container> p_rdoContainer(m_dataObjectName);
+    if (!m_rdoContainer.isValid()){
+      msg(MSG:: FATAL) << "Could not find the data object "<< m_rdoContainer.name() << " !" << endreq;
+     return StatusCode::FAILURE;
+    }
+  // Anything to dereference the DataHandle will trigger the converter
+    m_rdoContainer->clID();   
+    SCT_RDO_Container::const_iterator rdoCollections    = m_rdoContainer->begin();
+    SCT_RDO_Container::const_iterator rdoCollectionsEnd = m_rdoContainer->end();
+    bool dontDoClusterization(false);
+    //new code to remove large numbers of hits (what is large?)
+    if (m_maxTotalOccupancyPercent != 100){
+      constexpr int totalNumberOfChannels(6279168);
+      const int maxAllowableHits(totalNumberOfChannels*m_maxTotalOccupancyPercent/100);//integer arithmetic, should be ok
+      int totalHits(0);
+      for(; rdoCollections != rdoCollectionsEnd; ++rdoCollections){
+          const InDetRawDataCollection<SCT_RDORawData>* rd(*rdoCollections);
+          totalHits+=rd->size();
+      }//iterator is now at the end
+      //reset the iterator
+      rdoCollections    = m_rdoContainer->begin();
+      if (totalHits >  maxAllowableHits) {
+          ATH_MSG_INFO("This event has too many hits in the SCT");
+          dontDoClusterization=true;
+      }
+    }
+    
+    
+    //detType doesn't seem to do anything, does it need to be here?
+//    AtlasDetectorID detType;
+    if (not dontDoClusterization){
+        for(; rdoCollections != rdoCollectionsEnd; ++rdoCollections){
+          const InDetRawDataCollection<SCT_RDORawData>* rd(*rdoCollections);
+    #ifndef NDEBUG
+          ATH_MSG_DEBUG("RDO collection size=" << rd->size() << ", Hash=" << rd->identifyHash());
+    #endif
+          bool goodModule = (m_checkBadModules and m_pSummarySvc) ? m_pSummarySvc->isGood(rd->identifyHash()) : true;
+          // Check the RDO is not empty and that the wafer is good according to the conditions
+          if ((not rd->empty()) and goodModule){
+            // If more than a certain number of RDOs set module to bad
+            if (m_maxRDOs and (rd->size() > m_maxRDOs)) {
+              m_flaggedConditionSvc->flagAsBad(rd->identifyHash(), moduleFailureReason);
+              m_flaggedModules.insert(rd->identifyHash());
+              continue;
+            }
+            // Use one of the specific clustering AlgTools to make clusters    
+            std::unique_ptr<SCT_ClusterCollection> clusterCollection ( m_clusteringTool->clusterize(*rd,*m_manager,*m_idHelper));
+            if (clusterCollection) { 
+//              ATH_MSG_DEBUG("SCT_ClusterCollection" << clusterCollection->size() <<  "\n");
+              if (not clusterCollection->empty()) {
+                //Using get because I'm unsure of move semantec status
+                if (m_clusterContainer->addCollection(clusterCollection.get(), clusterCollection->identifyHash()).isFailure()){
+                  msg(MSG:: FATAL) << "Clusters could not be added to container !"<< endreq;
+//                  delete clusterCollection;   // Graceful exit?
+                  return StatusCode::FAILURE;
+                } else {
+    #ifndef NDEBUG
+                  ATH_MSG_DEBUG("Clusters with key '" << clusterCollection->identifyHash() << "' added to Container\n");
+    #endif
+                 clusterCollection.release();//Release ownership if sucessfully added to collection
+                } 
+              } else { 
+    #ifndef NDEBUG
+                ATH_MSG_DEBUG("Don't write empty collections\n");
+    #endif    
+//                delete clusterCollection;
+              }
+            } else { 
+                ATH_MSG_DEBUG("Clustering algorithm found no clusters\n");
+            }
+          }
+        }
+    }
+  // Set container to const
+    if (m_clusterContainer.setConst().isFailure()){
+      ATH_MSG_FATAL("FAILED TO SET CONST");
+      return StatusCode::FAILURE;
+    }
+    return StatusCode::SUCCESS;
+  }
+
+// Finalize method:
+  StatusCode SCT_Clusterization::finalize() 
+  {
+    msg(MSG::INFO) << "SCT_Clusterization::finalize() " << PACKAGE_VERSION << endreq;
+    if (m_maxRDOs) {
+      msg(MSG::INFO) 
+        << "Number of noisy modules killed by maximum RDO limit of " 
+        << m_maxRDOs << " = " << m_flaggedModules.size() << endreq;
+      msg(MSG::INFO) << "Printing info on up to 10 modules:" << endreq;
+      std::set<IdentifierHash>::const_iterator itr(m_flaggedModules.begin());
+      std::set<IdentifierHash>::const_iterator end(m_flaggedModules.end());
+      for (int num(0); (itr != end) && (num < 10) ; ++itr, ++num) {
+        msg(MSG::INFO) << "Noisy: " << m_idHelper->print_to_string(m_idHelper->wafer_id(*itr)) << endreq;
+      }
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+}
\ No newline at end of file
diff --git a/xAOD/xAODTracking/CMakeLists.txt b/xAOD/xAODTracking/CMakeLists.txt
index 4a647f871c4aa39736fc8c9fef3fc50aa2560476..0af665fab93b84a0a687755682cc8fcf9e55f71e 100755
--- a/xAOD/xAODTracking/CMakeLists.txt
+++ b/xAOD/xAODTracking/CMakeLists.txt
@@ -1,8 +1,3 @@
-# $Id: CMakeLists.txt 782296 2016-11-04 09:12:22Z krasznaa $
-################################################################################
-# Package: xAODTracking
-################################################################################
-
 # Declare the package name:
 atlas_subdir( xAODTracking )
 
@@ -40,3 +35,8 @@ atlas_add_test( xAODTracking_StripCluster_test
 atlas_add_test( xAODTracking_StripRawData_test
    SOURCES test/xAODTracking_StripRawData_test.cxx
    LINK_LIBRARIES xAODTracking )
+    
+atlas_add_test( xAODTracking_TrackParticlexAODHelpers_test
+   SOURCES test/xAODTracking_TrackParticlexAODHelpers_test.cxx
+   LINK_LIBRARIES xAODTracking
+   EXTRA_PATTERNS "^DEBUG" )
\ No newline at end of file
diff --git a/xAOD/xAODTracking/Root/Track.cxx b/xAOD/xAODTracking/Root/Track.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bd2c2c8d376fb563353246f4941043c7789acf68
--- /dev/null
+++ b/xAOD/xAODTracking/Root/Track.cxx
@@ -0,0 +1,496 @@
+// Misc includes
+#include <bitset>
+#include <vector>
+
+// EDM include(s):
+#include "xAODCore/AuxStoreAccessorMacros.h"
+
+// Local include(s):
+#include "xAODTracking/Track.h"
+#include "xAODTracking/TrackSummaryAccessors_v1.h"
+#include "EventPrimitives/EventPrimitivesHelpers.h"
+
+// Amg include
+//#include "EventPrimitives/EventPrimitives.h"
+
+namespace xAOD {
+
+  Track::Track()
+  : IParticle(), m_p4(), m_p4Cached( false ) {
+      
+  }
+  
+  Track::Track(const Track& tp ) 
+  : IParticle( tp ), m_p4(tp.m_p4), m_p4Cached( tp.m_p4Cached ) {
+    makePrivateStore( tp );
+  }
+  
+  Track& Track::operator=(const Track& tp ){
+    if(this == &tp) return *this;
+    
+    if( ( ! hasStore() ) && ( ! container() ) ) {
+       makePrivateStore();
+    }
+    this->IParticle::operator=( tp );
+    return *this;
+  }
+  
+  Track::~Track(){
+  }
+  
+  double Track::p() const {
+    return p4().P();
+  }
+
+  double Track::m() const {
+    return p4().M();
+  }
+
+  double Track::e() const {
+    return p4().E(); 
+  }
+
+  const Track::FourMom_t& Track::p4() const {
+    using namespace std;
+  // Check if we need to reset the cached object:
+    if( ! m_p4Cached ) {
+      float p = 10.e6; // 10 TeV (default value for very high pt muons, with qOverP==0)
+      if (fabs(qOverP())>0.) p = 1/fabs(qOverP());
+      float thetaT = theta();
+      float phiT = phi();
+      float sinTheta= sin(thetaT);
+      float px = p*sinTheta*cos(phiT);
+      float py = p*sinTheta*sin(phiT);
+      float pz = p*cos(thetaT);
+      float e  =  pow (139.570,2) + pow( px,2) + pow( py,2) + pow( pz,2);
+      m_p4.SetPxPyPzE( px, py, pz, sqrt(e) ); 
+      m_p4Cached = true;
+    }
+  // Return the cached object:
+    return m_p4;
+  }
+
+  Type::ObjectType Track::type() const {
+     return Type::TrackParticle;
+  }
+
+  float Track::charge() const {
+    return (qOverP() > 0) ? 1 : ((qOverP() < 0) ? -1 : 0);
+  }
+
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, x0)
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, y0)
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, theta)
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, qOverP)
+
+  const DefiningParameters_t Track::definingParameters() const{
+    DefiningParameters_t tmp;
+    tmp << d0() , z0() , phi0() , theta() , qOverP();
+    return tmp;
+  }
+
+  void Track::setDefiningParameters(float d0, float z0, float phi0, float theta, float qOverP) {
+    m_perigeeCached=false;
+#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) )
+    delete m_perigeeParameters;
+    m_perigeeParameters=0;
+#endif // not XAOD_STANDALONE and not XAOD_MANACORE
+    static Accessor< float > acc1( "d0" );
+    acc1( *this ) = d0;
+
+    static Accessor< float > acc2( "z0" );
+    acc2( *this ) = z0;
+
+    static Accessor< float > acc3( "phi" );
+    acc3( *this ) = phi0;
+
+    static Accessor< float > acc4( "theta" );
+    acc4( *this ) = theta;
+
+    static Accessor< float > acc5( "qOverP" );
+    acc5( *this ) = qOverP;
+
+    m_p4Cached = false;
+    return;
+  }
+
+  void Track::setDefiningParametersCovMatrix(const xAOD::ParametersCovMatrix_t& cov){
+    m_perigeeCached=false;
+#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) )
+    delete m_perigeeParameters;
+    m_perigeeParameters=0;
+#endif // not XAOD_STANDALONE and not XAOD_MANACORE
+
+    static Accessor< std::vector<float> > acc( "definingParametersCovMatrix" );
+    Amg::compress(cov,acc(*this));
+  }
+
+  const xAOD::ParametersCovMatrix_t Track::definingParametersCovMatrix() const {
+    xAOD::ParametersCovMatrix_t cov; 
+    const std::vector<float>& covVec = definingParametersCovMatrixVec();
+    if( !covVec.empty() ) Amg::expand( covVec.begin(), covVec.end(),cov );
+    else cov.setIdentity();
+    return cov;
+  }
+
+  const std::vector<float>& Track::definingParametersCovMatrixVec() const {
+  // Can't use AUXSTORE_PRIMITIVE_SETTER_AND_GETTER since I have to add Vec to the end of setDefiningParametersCovMatrix to avoid clash.
+    static Accessor< std::vector<float> > acc( "definingParametersCovMatrix" );
+    return acc(*this);
+  }
+
+  void Track::setDefiningParametersCovMatrixVec(const std::vector<float>& cov){
+  // Can't use AUXSTORE_PRIMITIVE_SETTER_AND_GETTER since I have to add Vec to the end of setDefiningParametersCovMatrix to avoid clash.
+    static Accessor< std::vector<float> > acc( "definingParametersCovMatrix" );
+    acc(*this)=cov;
+  }
+
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, vx)
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, vy)
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, vz)
+
+  void Track::setParametersOrigin(float x, float y, float z){
+    static Accessor< float > acc1( "vx" );
+    acc1( *this ) = x;
+
+    static Accessor< float > acc2( "vy" );
+    acc2( *this ) = y;
+
+    static Accessor< float > acc3( "vz" );
+    acc3( *this ) = z;
+  }
+
+#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) )
+  const Trk::Perigee& Track::perigeeParameters() const {
+    if (m_perigeeCached)
+      return *m_perigeeParameters;
+    m_perigeeCached=true;
+
+    static Accessor< float > acc1( "d0" );
+    static Accessor< float > acc2( "z0" );
+    static Accessor< float > acc3( "phi" );
+    static Accessor< float > acc4( "theta" );
+    static Accessor< float > acc5( "qOverP" );
+    static Accessor< std::vector<float> > acc6( "definingParametersCovMatrix" );
+    ParametersCovMatrix_t* cov = new ParametersCovMatrix_t(definingParametersCovMatrix());
+    // cov->setZero();
+    // auto it= acc6(*this).begin();
+    // for (size_t irow = 0; irow<5; ++irow)
+    //   for (size_t icol =0; icol<=irow; ++icol)
+    //       cov->fillSymmetric(irow,icol,*it++) ;
+    static Accessor< float > acc7( "beamlineTiltX" );
+    static Accessor< float > acc8( "beamlineTiltY" );
+    
+    if(!acc7.isAvailable( *this ) || !acc8.isAvailable( *this )){
+      m_perigeeParameters = new Trk::Perigee(acc1(*this),acc2(*this),acc3(*this),acc4(*this),acc5(*this),Trk::PerigeeSurface(Amg::Vector3D(vx(),vy(),vz())),cov);
+       return *m_perigeeParameters;
+    }
+    
+    Amg::Transform3D * amgTransf = new Amg::Transform3D();  
+    Amg::Translation3D amgtranslation(vx(),vy(),vz());
+    *amgTransf = amgtranslation * Amg::RotationMatrix3D::Identity();
+    *amgTransf *= Amg::AngleAxis3D(acc8(*this), Amg::Vector3D(0.,1.,0.));
+    *amgTransf *= Amg::AngleAxis3D(acc7(*this), Amg::Vector3D(1.,0.,0.));
+    m_perigeeParameters = new Trk::Perigee(acc1(*this),acc2(*this),acc3(*this),acc4(*this),acc5(*this),Trk::PerigeeSurface(amgTransf),cov);
+    
+    return *m_perigeeParameters;
+  }
+#endif // not XAOD_STANDALONE and not XAOD_MANACORE
+
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, chiSquared)
+  AUXSTORE_PRIMITIVE_GETTER(Track, float, numberDoF)
+
+  void Track::setFitQuality(float chiSquared, float numberDoF){
+    static Accessor< float > acc1( "chiSquared" );
+    acc1( *this ) = chiSquared;  
+    static Accessor< float > acc2( "numberDoF" );
+    acc2( *this ) = numberDoF;   
+  }
+
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, float, radiusOfFirstHit, setRadiusOfFirstHit)
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint64_t, identifierOfFirstHit, setIdentifierOfFirstHit)
+
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, float, beamlineTiltX, setBeamlineTiltX)
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, float, beamlineTiltY, setBeamlineTiltY)
+  
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint32_t, hitPattern, setHitPattern)
+
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint8_t,numberOfUsedHitsdEdx ,setNumberOfUsedHitsdEdx )
+
+   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint8_t,numberOfIBLOverflowsdEdx , setNumberOfIBLOverflowsdEdx)
+
+  size_t Track::numberOfParameters() const{
+    ///@todo - Can we do this in a better way? Not great to force retrieval of one specific parameter - any would do.
+    static Accessor< std::vector<float>  > acc( "parameterX" );
+    if(! acc.isAvailable( *this )) return 0;
+    return acc(*this).size();
+  }
+
+  const CurvilinearParameters_t Track::trackParameters(unsigned int index) const{
+    CurvilinearParameters_t tmp;
+    tmp << parameterX(index),parameterY(index),parameterZ(index),
+      parameterPX(index),parameterPY(index),parameterPZ(index);
+    return tmp;
+  }
+
+  void Track::setTrackParameters(std::vector<std::vector<float> >& parameters){
+    static Accessor< std::vector < float > > acc1( "parameterX" );
+    static Accessor< std::vector < float > > acc2( "parameterY" );
+    static Accessor< std::vector < float > > acc3( "parameterZ" );
+    static Accessor< std::vector < float > > acc4( "parameterPX" );
+    static Accessor< std::vector < float > > acc5( "parameterPY" );
+    static Accessor< std::vector < float > > acc6( "parameterPZ" );
+
+    static Accessor< std::vector<uint8_t>  > acc7( "parameterPosition" );
+
+    acc1(*this).resize(parameters.size());
+    acc2(*this).resize(parameters.size());
+    acc3(*this).resize(parameters.size());
+    acc4(*this).resize(parameters.size());
+    acc5(*this).resize(parameters.size());
+    acc6(*this).resize(parameters.size());
+
+    acc7(*this).resize(parameters.size());
+
+    unsigned int index=0;
+    // std::cout<<"Adding this many parameters: "<<parameters.size()<<std::endl;
+    std::vector<std::vector<float> >::const_iterator it=parameters.begin(), itEnd=parameters.end();
+    for (;it!=itEnd;++it,++index){
+      assert((*it).size()==6);
+      acc1(*this).at(index)=(*it).at(0);
+      acc2(*this).at(index)=(*it).at(1);
+      acc3(*this).at(index)=(*it).at(2);
+      acc4(*this).at(index)=(*it).at(3);
+      acc5(*this).at(index)=(*it).at(4);
+      acc6(*this).at(index)=(*it).at(5);
+      // std::cout<<"param=("<<(*it).at(0)<<", "<<(*it).at(0)<<", "<<(*it).at(1)<<", "<<(*it).at(2)<<", "<<(*it).at(3)<<", "<<(*it).at(4)<<", "<<(*it).at(5)<<")"<<std::endl;
+    }
+  }
+
+  float Track::parameterX(unsigned int index) const  {
+    static Accessor< std::vector<float>  > acc( "parameterX" );
+    return acc(*this).at(index);
+  }
+
+  float Track::parameterY(unsigned int index) const  {
+    static Accessor< std::vector<float>  > acc( "parameterY" );
+    return acc(*this).at(index);
+  }
+
+  float Track::parameterZ(unsigned int index) const  {
+    static Accessor< std::vector<float>  > acc( "parameterZ" );
+    return acc(*this).at(index);
+  }
+
+  float Track::parameterPX(unsigned int index) const {
+    static Accessor< std::vector<float>  > acc( "parameterPX" );
+    return acc(*this).at(index);
+  }
+
+  float Track::parameterPY(unsigned int index) const {
+    static Accessor< std::vector<float>  > acc( "parameterPY" );
+    return acc(*this).at(index);
+  }
+
+  float Track::parameterPZ(unsigned int index) const {
+    static Accessor< std::vector<float>  > acc( "parameterPZ" );    
+    return acc(*this).at(index);
+  }
+
+  xAOD::ParametersCovMatrix_t Track::trackParameterCovarianceMatrix(unsigned int index) const
+  {
+    static Accessor< std::vector<float>  > acc( "trackParameterCovarianceMatrices" );
+    unsigned int offset = index*15;
+    // copy the correct values into the temp matrix
+    xAOD::ParametersCovMatrix_t tmp;
+    std::vector<float>::const_iterator it = acc(*this).begin()+offset;
+    Amg::expand(it,it+15,tmp);
+    return tmp;
+  }
+
+  void Track::setTrackParameterCovarianceMatrix(unsigned int index, std::vector<float>& cov){
+    assert(cov.size()==15);
+    unsigned int offset = index*15;
+    static Accessor< std::vector < float > > acc( "trackParameterCovarianceMatrices" );
+    std::vector<float>& v = acc(*this);
+    v.resize(offset+15);
+    std::copy(cov.begin(),cov.end(),v.begin()+offset );
+  }
+
+  xAOD::ParameterPosition Track::parameterPosition(unsigned int index) const
+  {
+    static Accessor< std::vector<uint8_t>  > acc( "parameterPosition" );
+    return static_cast<xAOD::ParameterPosition>(acc(*this).at(index));
+  }
+
+  bool Track::indexOfParameterAtPosition(unsigned int& index, ParameterPosition position) const 
+  {
+    size_t maxParameters = numberOfParameters();
+    bool foundParameters=false;
+    for (size_t i=0; i<maxParameters; ++i){
+      if (parameterPosition(i)==position){
+        foundParameters=true;
+        index=i;
+        break;
+      }
+    }
+    return foundParameters;
+  }
+
+  void  Track::setParameterPosition(unsigned int index, xAOD::ParameterPosition pos){
+    static Accessor< std::vector<uint8_t>  > acc( "parameterPosition" );
+    acc( *this ).at(index) = static_cast<uint8_t>(pos);
+  }
+
+#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) )
+  const Trk::CurvilinearParameters Track::curvilinearParameters(unsigned int index) const {    
+
+    static Accessor< std::vector<float>  > acc( "trackParameterCovarianceMatrices" );
+    unsigned int offset = index*15;
+    // copy the correct values into the temp matrix
+    ParametersCovMatrix_t* cov = new ParametersCovMatrix_t(); 
+    auto it = acc(*this).begin()+offset;
+    Amg::expand(it,it+15,*cov);
+    // retrieve the parameters to build the curvilinear frame
+    Amg::Vector3D pos(parameterX(index),parameterY(index),parameterZ(index));
+    Amg::Vector3D mom(parameterPX(index),parameterPY(index),parameterPZ(index));
+    Trk::CurvilinearParameters param(pos,mom,charge(),cov);
+
+    return param;
+  }
+#endif // not XAOD_STANDALONE and not XAOD_MANACORE
+
+  AUXSTORE_PRIMITIVE_GETTER_WITH_CAST(Track, uint8_t, xAOD::TrackProperties,trackProperties)
+  AUXSTORE_PRIMITIVE_SETTER_WITH_CAST(Track, uint8_t, xAOD::TrackProperties,trackProperties, setTrackProperties)
+
+  AUXSTORE_PRIMITIVE_GETTER_WITH_CAST(Track, uint8_t, xAOD::TrackFitter,trackFitter)
+  AUXSTORE_PRIMITIVE_SETTER_WITH_CAST(Track, uint8_t, xAOD::TrackFitter,trackFitter, setTrackFitter)
+
+  std::bitset<xAOD::NumberOfTrackRecoInfo>   Track::patternRecoInfo() const {
+    static Accessor< uint64_t > acc( "patternRecoInfo" );
+    std::bitset<xAOD::NumberOfTrackRecoInfo> tmp(acc(*this));
+    return tmp;
+  }
+
+  void Track::setPatternRecognitionInfo(uint64_t patternReco)  {
+    static Accessor< uint64_t > acc( "patternRecoInfo" );
+    acc( *this ) = patternReco;
+  }
+
+  void Track::setPatternRecognitionInfo(const std::bitset<xAOD::NumberOfTrackRecoInfo>& patternReco)  {
+    static Accessor< uint64_t > acc( "patternRecoInfo" );
+  #if __cplusplus < 201100
+    uint64_t value = 0;
+    unsigned int i = 0;
+    unsigned int size=patternReco.size();
+    for (;i<32;++i)       value   |= ((patternReco[i]) << i);
+    for (i=32;i<size;++i) value   |= ((patternReco[i]) << (i-32));
+    acc( *this ) = value;
+
+  #else
+    acc( *this ) = patternReco.to_ullong();
+  #endif
+  }
+
+  AUXSTORE_PRIMITIVE_SETTER_WITH_CAST(Track, uint8_t, xAOD::ParticleHypothesis, particleHypothesis, setParticleHypothesis)
+  AUXSTORE_PRIMITIVE_GETTER_WITH_CAST(Track, uint8_t, xAOD::ParticleHypothesis, particleHypothesis)
+
+  bool Track::summaryValue(uint8_t& value, const SummaryType &information)  const {
+    xAOD::Track::Accessor< uint8_t >* acc = trackSummaryAccessorV1<uint8_t>( information );
+    if( ( ! acc ) || ( ! acc->isAvailable( *this ) ) ) return false;
+  // Retrieve the value:
+    value = ( *acc )( *this );
+    return true;
+  }
+  
+  bool Track::summaryValue(float& value, const SummaryType &information)  const {
+    xAOD::Track::Accessor< float >* acc = trackSummaryAccessorV1<float>( information );
+    if( ( ! acc ) || ( ! acc->isAvailable( *this ) ) ) return false;
+  // Retrieve the value:
+    value = ( *acc )( *this );
+    return true;
+  }
+  
+  void Track::setSummaryValue(uint8_t& value, const SummaryType &information){
+    xAOD::Track::Accessor< uint8_t >* acc = trackSummaryAccessorV1<uint8_t>( information );
+  // Set the value:
+    ( *acc )( *this ) = value;
+  }
+
+  void Track::setSummaryValue(float& value, const SummaryType &information){
+    xAOD::Track::Accessor< float >* acc = trackSummaryAccessorV1<float>( information );
+  // Set the value:
+    ( *acc )( *this ) = value;
+  }
+ 
+
+#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) )
+   /// The function will return an invalid ElementLink in case nothing was set
+   /// for it yet. This is to avoid users having to always check both for
+   /// the decoration being available, and the link being valid.
+   ///
+   /// @returns An element link to the parent Trk::Track of this track particle
+   ///
+   const ElementLink< TrackCollection >& Track::trackLink() const {
+
+      // The accessor:
+      static ConstAccessor< ElementLink< TrackCollection > > acc( "trackLink" );
+
+      // Check if one of them is available:
+      if( acc.isAvailable( *this ) ) {
+         return acc( *this );
+      }
+
+      // If no Trk::Track link was not set (yet), return a dummy object:
+      static const ElementLink< TrackCollection > dummy;
+      return dummy;
+   }
+
+   void Track::
+   setTrackLink( const ElementLink< TrackCollection >& el ) {
+
+      // The accessor:
+      static Accessor< ElementLink< TrackCollection > > acc( "trackLink" );
+
+      // Do the deed:
+      acc( *this ) = el;
+      return;
+   }
+
+   const Trk::Track* Track::track() const{
+
+      // The accessor:
+      static ConstAccessor< ElementLink< TrackCollection > > acc( "trackLink" );
+
+      if( ! acc.isAvailable( *this ) ) {
+         return 0;
+      }
+      if( ! acc( *this ).isValid() ) {
+         return 0;
+      }
+
+      return *( acc( *this ) );
+   }
+   
+#endif // not XAOD_STANDALONE and not XAOD_MANACORE
+
+   AUXSTORE_OBJECT_SETTER_AND_GETTER( Track,
+                                      ElementLink< VertexContainer >,
+                                      vertexLink, setVertexLink )
+
+   const Vertex* Track::vertex() const {
+
+      // The accessor:
+      static SG::AuxElement::Accessor< ElementLink< VertexContainer > >
+         acc( "vertexLink" );
+
+      if( ! acc.isAvailable( *this ) ) {
+         return 0;
+      }
+      if( ! acc( *this ).isValid() ) {
+         return 0;
+      }
+      return *( acc( *this ) );
+   }
+
+} // namespace xAOD
\ No newline at end of file
diff --git a/xAOD/xAODTracking/Root/dict/ContainerProxies.cxx b/xAOD/xAODTracking/Root/dict/ContainerProxies.cxx
index a12798748c68f6ba85468f238936daeb542638a7..40858146df7d3f3dedc892dbb065ac8cf5dd555d 100644
--- a/xAOD/xAODTracking/Root/dict/ContainerProxies.cxx
+++ b/xAOD/xAODTracking/Root/dict/ContainerProxies.cxx
@@ -2,9 +2,11 @@
 #include "xAODCore/AddDVProxy.h"
 
 // Local include(s):
+#include "xAODTracking/TrackContainer.h"
 #include "xAODTracking/StripClusterContainer.h"
 #include "xAODTracking/StripRawDataContainer.h"
 
 // Set up the collection proxies:
+ADD_NS_DV_PROXY( xAOD, TrackContainer );
 ADD_NS_DV_PROXY( xAOD, StripClusterContainer );
 ADD_NS_DV_PROXY( xAOD, StripRawDataContainer );
\ No newline at end of file
diff --git a/xAOD/xAODTracking/test/xAODTracking_Track_test.cxx b/xAOD/xAODTracking/test/xAODTracking_Track_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9395da84ef19fa958b7ae896d557545021cd6934
--- /dev/null
+++ b/xAOD/xAODTracking/test/xAODTracking_Track_test.cxx
@@ -0,0 +1,114 @@
+// System include(s):
+#include <iostream>
+
+// Local include(s):
+#include "xAODTracking/TrackContainer.h"
+#include "xAODTracking/TrackAuxContainer.h"
+
+template< typename T >
+std::ostream& operator<< ( std::ostream& out,
+                           const std::vector< T >& vec ) {
+
+   out << "[";
+   for( size_t i = 0; i < vec.size(); ++i ) {
+      out << vec[ i ];
+      if( i < vec.size() - 1 ) {
+         out << ", ";
+      }
+   }
+   out << "]";
+   return out;
+}
+
+/// Function filling one Track with information
+void fill( xAOD::Track& tp ) {
+
+   tp.setDefiningParameters( 1.0, 2.0, 1.23, 0.5, 0.25 );
+
+   static const float covMatrix[ 15 ] = {
+      1.0, 1.0, 1.0, 1.0, 1.0,
+      2.0, 2.0, 2.0, 2.0, 2.0,
+      3.0, 3.0, 3.0, 3.0, 3.0
+   };
+   static const std::vector< float >
+      covMatrixVec( covMatrix, covMatrix + 15 );
+   tp.setDefiningParametersCovMatrixVec( covMatrixVec );
+
+   tp.setParametersOrigin( 0.0, 1.0, 2.0 );
+
+   static const float parameters[ 2 ][ 6 ] = {
+      { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 },
+      { 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 }
+   };
+   static std::vector< std::vector< float > > parametersVec;
+   if( ! parametersVec.size() ) {
+      for( int i = 0; i < 2; ++i ) {
+         std::vector< float > temp( parameters[ i ],
+                                    parameters[ i ] + 6 );
+         parametersVec.push_back( temp );
+      }
+   }
+   tp.setTrackParameters( parametersVec );
+
+   tp.setParameterPosition( 0, xAOD::FirstMeasurement );
+   tp.setParameterPosition( 1, xAOD::CalorimeterEntrance );
+
+   return;
+}
+
+/// Function printing the properties of a Track
+void print( const xAOD::Track& tp ) {
+
+   std::cout << "x0 = " << tp.x0() << ", y0 = " << tp.y0()
+             << ", phi = " << tp.phi() << ", theta = " << tp.theta()
+             << ", qOverP = " << tp.qOverP() << std::endl;
+   std::cout << "definingParametersCovMatrixVec = "
+             << tp.definingParametersCovMatrixVec() << std::endl;
+   std::cout << "vx = " << tp.vx() << ", vy = " << tp.vy()
+             << ", vz = " << tp.vz() << std::endl;
+   std::cout << "numberOfParameters = " << tp.numberOfParameters() << std::endl;
+   for( size_t i = 0; i < tp.numberOfParameters(); ++i ) {
+      std::cout << "  - x = " << tp.parameterX( i )
+                << ", y = " << tp.parameterY( i )
+                << ", z = " << tp.parameterZ( i )
+                << ", px = " << tp.parameterPX( i )
+                << ", py = " << tp.parameterPY( i )
+                << ", pz = " << tp.parameterPZ( i ) << std::endl;
+   }
+   std::cout << "parameterPosition( 0 ) = "
+             << tp.parameterPosition( 0 ) << std::endl;
+   std::cout << "parameterPosition( 1 ) = "
+             << tp.parameterPosition( 1 ) << std::endl;
+
+   return;
+}
+
+int main() {
+
+   // Create the main containers to test:
+   xAOD::TrackAuxContainer aux;
+   xAOD::TrackContainer tpc;
+   tpc.setStore( &aux );
+
+   // Add one track particle to the container:
+   xAOD::Track* p = new xAOD::Track();
+   tpc.push_back( p );
+
+   // Fill it with information:
+   fill( *p );
+
+   // Print the information:
+   print( *p );
+
+   // Print the contents of the auxiliary store:
+   aux.dump();
+   
+   // Copy the track particle.
+   xAOD::Track* p2 = new xAOD::Track(*p);
+   
+   // Print the information:
+   print( *p2 );
+
+   // Return gracefully:
+   return 0;
+}
\ No newline at end of file
diff --git a/xAOD/xAODTracking/xAODTracking/Track.h b/xAOD/xAODTracking/xAODTracking/Track.h
new file mode 100644
index 0000000000000000000000000000000000000000..123257ebc0c2bddc084e680899b88ff3781ef665
--- /dev/null
+++ b/xAOD/xAODTracking/xAODTracking/Track.h
@@ -0,0 +1,226 @@
+#ifndef XAODTRACKING_TRACK_H
+#define XAODTRACKING_TRACK_H
+
+// System include(s):
+#include <bitset>
+extern "C" {
+#   include <stdint.h>
+}
+
+// Core include(s):
+#include "AthLinks/ElementLink.h"
+#include "AthContainers/DataVector.h"
+
+// xAOD include(s):
+#include "xAODBase/IParticle.h"
+#include "xAODTracking/TrackingPrimitives.h" 
+
+namespace xAOD {
+    
+    class Track : public IParticle {
+    
+    public:
+    
+        /// Default constructor
+        Track();
+        /// Destructor
+        ~Track();
+        /// Copy ctor. This involves copying the entire Auxilary store, and is a slow operation which should be used sparingly.
+        Track(const Track& o );
+        /// Assignment operator. This can involve creating and copying an Auxilary store, and so should be used sparingly.
+        Track& operator=(const Track& tp );
+        
+        /// @name IParticle functions
+        /// @{
+            /// 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 (has range \f$-\pi\f$ to \f$+\pi\f$.)
+            virtual double           phi() const;
+            /// The invariant mass of the particle..
+            virtual double           m() const;
+            /// The total energy of the particle.
+            virtual double           e() const;
+            /// The true rapidity (y) 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.
+            virtual const FourMom_t& p4() const;
+    
+            /// The type of the object as a simple enumeration
+            virtual Type::ObjectType type() const;
+        /// @}
+    
+        /// @name Defining parameters functions
+        /// The 'defining parameters' are key to the concept of a Track, and give the values for the IParticle interface
+        /// ( pt(), phi(), eta() etc.).
+        /// They use the Trk::Perigee coordinate system, and are defined as:
+        ///  \f$( d_0, z_0, \phi, \theta, q/p )\f$.
+        /// The parameters are expressed with respect to an origin (returned by vx(), vy() and vy() ), currently intended to be the 'beamspot'.
+        /// This origin is expected to be the same for all track particles in a collection (and this may be be enforced).
+        /// The \f$\phi\f$ parameter is returned by either the phi() or the phi0() methods, the difference just being whether it is returned as a float or a double (it is stored as a float)
+        /// @{
+            /// Returns the charge.
+            float charge() const;
+            /// Returns the \f$x_0\f$ parameter
+            float x0() const;
+            /// Returns the \f$y_0\f$ parameter
+            float y0() const;
+            /// Returns the \f$\phi\f$ parameter, which has range \f$-\pi\f$ to \f$+\pi\f$.
+            float phi() const;
+            /// Returns the \f$\theta\f$  parameter, which has range 0 to \f$\pi\f$.
+            float theta() const;
+            /// Returns the \f$q/p\f$  parameter
+            float qOverP() const;
+            /// @brief Returns a SVector of the Perigee track parameters. 
+            /// i.e. a vector of
+            ///  \f$\left(\begin{array}{c}x_0\\y_0\\\phi\\\theta\\q/p\end{array}\right)\f$
+            const DefiningParameters_t definingParameters() const;
+            /// Returns the 5x5 symmetric matrix containing the defining parameters covariance matrix.
+            const ParametersCovMatrix_t definingParametersCovMatrix() const;  
+            /// Returns the length 6 vector containing the elements of defining parameters covariance matrix.
+            const std::vector<float>& definingParametersCovMatrixVec() const;   
+            /// Set the defining parameters.     
+            void setDefiningParameters(float x0, float y0, float phi, float theta, float qOverP);
+            /// Set the defining parameters covariance matrix.
+            void setDefiningParametersCovMatrix(const ParametersCovMatrix_t& cov);
+            /// Set the defining parameters covariance matrix using a length 15 vector.
+            void setDefiningParametersCovMatrixVec(const std::vector<float>& cov);
+            /// The x origin for the parameters.
+            float vx() const;
+            /// The y origin for the parameters.
+            float vy() const;
+            /// The z origin for the parameters.
+            float vz() const;
+            /// Set the origin for the parameters.
+            void setParametersOrigin(float x, float y, float z);
+   
+    
+        /// @name Curvilinear functions
+        /// The set of functions which return other track parameters.
+        /// The remaining track parameters (i.e. not the 'defining parameters') use the 'curvilinear' coordinate system, 
+        /// and are represented by the parameters @f$(x,y,z,p_x,p_y,p_z)@f$.
+        /// The parameters can have an associated local 5x5 error/covariance matrix. They are expressed at various points through the
+        /// detector, which can be determined by the parameterPosition() method.      
+        /// @code
+        /// // Example code to use parameters
+        /// unsigned int index=0;
+        /// if (myTP.indexOfParameterAtPosition(index, xAOD::FirstMeasurement)){
+        ///   CurvilinearParameters_t parameters = myTP.trackParameters(index);
+        /// }
+        /// @endcode
+        /// @{
+            /// Returns the number of additional parameters stored in the TrackParticle. 
+            size_t numberOfParameters() const; 
+            /// Returns the track parameter vector at 'index'.
+            const CurvilinearParameters_t trackParameters(unsigned int index) const;
+            /// Returns the parameter x position, for 'index'.
+            float parameterX(unsigned int index) const;
+            /// Returns the parameter y position, for 'index'.
+            float parameterY(unsigned int index) const;
+            /// Returns the parameter z position, for 'index'.
+            float parameterZ(unsigned int index) const;
+            /// Returns the parameter x momentum component, for 'index'.
+            float parameterPX(unsigned int index) const;
+            /// Returns the parameter y momentum component, for 'index'.
+            float parameterPY(unsigned int index) const;
+            /// Returns the parameter z momentum component, for 'index'.
+            float parameterPZ(unsigned int index) const; 
+            /// Set the parameters via the passed vector of vectors. 
+            /// The vector<float> should be of size 6: x,y,z,px,py,pz (charge is stored elsewhere)
+            void setTrackParameters(std::vector<std::vector<float> >& parameters);
+            /// @brief Returns the TrackParticleCovMatrix_t (covariance matrix) at 'index', 
+            /// which corresponds to the parameters at the same index.
+            ParametersCovMatrix_t trackParameterCovarianceMatrix(unsigned int index) const;
+            /// Set the cov matrix of the parameter at 'index', using a vector of floats.
+            /// The vector @f$\mathrm{v}(a1,a2,a3 ... a_{15})@f$ represents the lower diagonal, i.e. it gives a matrix of 
+            /// \f$\left(\begin{array}{ccccc} a_1  & a_2  & a_4  & a_7  & a_{11} \\ a_2  & a_3  & a_5  & a_8  & a_{12} \\ a_4  & a_5  & a_6  & a_9  & a_{13} \\ a_7  & a_8  & a_9  & a_{10}  & a_{14} \\ a_{11} & a_{12} & a_{13} & a_{14} & a_{15} \end{array}\right)\f$
+            void setTrackParameterCovarianceMatrix(unsigned int index, std::vector<float>& cov);  
+            /// @brief Return the ParameterPosition of the parameters at 'index'.
+            xAOD::ParameterPosition parameterPosition(unsigned int index) const;
+            /// @brief Function to determine if this TrackParticle contains track parameters at a certain position, and if so, what the 'index' is.
+            /// @param[in] index Filled with the index of the track parameters at 'position' - untouched otherwise.
+            /// @param[out] position The location in the detector of the required track parameters.
+            /// @return Returns 'true' if the TrackParticle parameters at 'position', returns False otherwise.
+            bool indexOfParameterAtPosition(unsigned int& index, ParameterPosition position) const;
+            /// Set the 'position' (i.e. where it is in ATLAS) of the parameter at 'index', using the ParameterPosition enum. 
+            void setParameterPosition(unsigned int index, ParameterPosition pos);
+
+        
+        uint32_t hitPattern() const;
+        void setHitPattern(uint32_t hitpattern);
+    
+        /// @}
+    
+        /// @name Fit quality functions
+        /// Returns some information about quality of the track fit.
+        /// @{
+            /// Returns the @f$ \chi^2 @f$ of the overall track fit.
+            float chiSquared() const;
+            /// Returns the number of degrees of freedom of the overall track or vertex fit as float.
+            float  numberDoF() const;   
+            /// Set the 'Fit Quality' information.
+            void setFitQuality(float chiSquared, float numberDoF);   
+        /// @}
+    
+        /// @name TrackInfo functions
+        /// Contains information about the 'fitter' of this Trk::Track / TrackParticle.
+        /// Additionally there is some information about how the e.g. fit was configured. 
+        /// Also the information on the properties of the  track fit is stored.
+        /// @{
+            /// Method for setting the fitter, using the TrackFitter enum.
+            void setTrackFitter(const TrackFitter fitter)  ;
+            /// Method for setting the particle type, using the ParticleHypothesis enum.
+            void setParticleHypothesis(const ParticleHypothesis hypo);
+        /// Returns the particle hypothesis used for Track fitting.
+            ParticleHypothesis particleHypothesis() const
+            /// Returns the fitter.
+            TrackFitter trackFitter() const;
+        /// @}
+    
+    
+            /// Accessor for TrackSummary values.
+            /// If 'information' is stored in this TrackParticle and is of the correct templated type T, 
+            /// then the function fills 'value' and returns 'true', otherwise it returns 'false', and does not touch 'value'. 
+            /// See below for an example of how this is intended to be used.
+            /// @code
+            /// int numberOfBLayerHits=0;
+            /// if( myParticle.summaryValue(numberOfBLayerHits,xAOD::numberOfBLayerHits) ){
+            ///   ATH_MSG_INFO("Successfully retrieved the integer value, numberOfBLayerHits"); 
+            /// }
+            /// float numberOfCscPhiHits=0.0; //Wrong! This is actually an int too.
+            /// if( !myParticle.summaryValue(numberOfCscPhiHits,xAOD::numberOfCscPhiHits) ){
+            ///   ATH_MSG_INFO("Types must match!"); 
+            /// }
+            /// @endcode
+            /// @param[in] information The information being requested. This is not guaranteed to be stored in all TrackParticles.
+            /// @param[out] value  Only filled if this TrackParticle contains 'information', and the types match.
+            /// @return Returns 'true' if the TrackParticle contains 'information', and its concrete type matches 'value' (templated type T).
+            bool summaryValue(uint8_t& value, const SummaryType &information) const;
+            ///  @copydoc Track::summaryValue(uint8_t& value, const SummaryType &information) const
+            bool summaryValue(float& value, const SummaryType &information) const;
+            /// Set method for TrackSummary values.
+            void setSummaryValue(uint8_t& value, const SummaryType &information);
+            ///  @copydoc Track::setSummaryValue(uint8_t& value, const SummaryType &information)
+            void setSummaryValue(float& value, const SummaryType &information);
+        /// @}
+
+        /// @}
+        private:
+        /// Cached 4-momentum object.
+        mutable FourMom_t m_p4;
+        /// Cache state of the internal 4-momentum (reset from the streamer).
+        mutable bool m_p4Cached;
+
+        }; // class Track Particle
+}
+
+// Set up a CLID for the class:
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::Track, 159016719, 1 )
+
+#endif // XAODTRACKING_TRACK_H
\ No newline at end of file
diff --git a/xAOD/xAODTracking/xAODTracking/TrackAuxContainer.h b/xAOD/xAODTracking/xAODTracking/TrackAuxContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..97f7ffc9785d1ab532602d841dbefbc0bb164b21
--- /dev/null
+++ b/xAOD/xAODTracking/xAODTracking/TrackAuxContainer.h
@@ -0,0 +1,96 @@
+#ifndef XAODTRACKING_TRACKAUXCONTAINER_H
+#define XAODTRACKING_TRACKAUXCONTAINER_H
+ 
+// System include(s):
+extern "C" {
+#   include <stdint.h>
+}
+#include <vector>
+
+// EDM include(s):
+#include "xAODCore/AuxContainerBase.h"
+#include "AthLinks/ElementLink.h"
+
+// Local include(s):
+#include "xAODTracking/TrackAuxContainer.h"
+ 
+namespace xAOD {
+    class TrackAuxContainer : public AuxContainerBase {
+    
+    public:
+    /// Default constructor
+    TrackAuxContainer();
+    /// Dumps contents (for debugging)
+    void dump() const;
+    
+    private:
+    
+    /// @name Defining parameters (perigee)
+    /// @{
+    std::vector< float >                x0;
+    std::vector< float >                y0;
+    std::vector< float >                phi;
+    std::vector< float >                theta;
+    std::vector< float >                qOverP;
+    
+    std::vector< std::vector<float> >   definingParametersCovMatrix;
+    
+    std::vector< float >                vx;
+    std::vector< float >                vy;
+    std::vector< float >                vz;
+    /// @}
+    
+    // /// @name Parameters
+        /// We store the 3-pos, 3-mom and charge, and on the transient side these will be transformed into curvilinear parameters.
+        /// Also stored are the cov matrix (still expressed in local coordinate frame) and parameter position.
+        /// @{
+        std::vector< std::vector<float> >   parameterX;
+        std::vector< std::vector<float> >   parameterY;
+        std::vector< std::vector<float> >   parameterZ;
+        std::vector< std::vector<float> >   parameterPX;
+        std::vector< std::vector<float> >   parameterPY;
+        std::vector< std::vector<float> >   parameterPZ;
+
+        std::vector< std::vector<float> >   trackParameterCovarianceMatrices;
+        std::vector< std::vector<uint8_t> > parameterPosition;
+    
+    std::vector< uint32_t > hitPattern;
+    
+    /// @name Fit quality functions
+    /// @{
+    std::vector< float >                chiSquared;
+    std::vector< float >                numberDoF;
+    /// @}
+    
+    /// @name TrackInfo functions
+    /// @{
+    std::vector< uint8_t >              trackFitter;
+    std::vector< uint8_t >              particleHypothesis;
+    /// @}
+    
+    #ifndef XAODTRACKING_SUMMARYDYNAMIC
+    /// @name TrackSummary information
+    /// @{
+    std::vector< uint8_t >         numberOfContribStripLayers       ;
+    std::vector< uint8_t >         numberOfStripHits                  ;
+    std::vector< uint8_t >         numberOfStripOutliers              ;
+    std::vector< uint8_t >         numberOfStripHoles                 ;
+    std::vector< uint8_t >         numberOfStripDoubleHoles           ;
+    std::vector< uint8_t >         numberOfStripSharedHits            ;
+    std::vector< uint8_t >         numberOfStripDeadSensors           ;
+    std::vector< uint8_t >         numberOfStripSpoiltHits            ;
+    
+    std::vector< uint8_t >         numberOfOutliersOnTrack          ;
+    std::vector< uint8_t >         standardDeviationOfChi2OS        ;
+    
+    /// @}
+    #endif
+    }; // class TrackAuxContainer
+}
+
+// Set up a CLID and StoreGate inheritance for the class:
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TrackAuxContainer, 1209269198, 1 )
+
+
+#endif // XAODTRACKING_TRACKAUXCONTAINER_H
\ No newline at end of file
diff --git a/xAOD/xAODTracking/xAODTracking/TrackContainer.h b/xAOD/xAODTracking/xAODTracking/TrackContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..12a6f8c0e2e841e0c1b0edd64a259145c216a558
--- /dev/null
+++ b/xAOD/xAODTracking/xAODTracking/TrackContainer.h
@@ -0,0 +1,21 @@
+#ifndef XAODTRACKING_TRACKCONTAINER_H
+#define XAODTRACKING_TRACKCONTAINER_H
+
+// Core include(s):
+#include "AthContainers/DataVector.h"
+#include <stdint.h>
+ 
+// Local include(s):
+#include "xAODTracking/Track.h"
+
+//template struct DataVector_detail::DVLEltBaseInit< xAOD::Track >;
+ 
+namespace xAOD {
+   typedef DataVector< xAOD::Track > TrackContainer;
+}
+
+// Set up a CLID for the container:
+#include "xAODCore/CLASS_DEF.h"
+CLASS_DEF( xAOD::TrackContainer, 1287425431, 1 )
+
+#endif // XAODTRACKING_TRACKCONTAINER_H
\ No newline at end of file
diff --git a/xAOD/xAODTracking/xAODTracking/TrackingPrimitives.h b/xAOD/xAODTracking/xAODTracking/TrackingPrimitives.h
new file mode 100644
index 0000000000000000000000000000000000000000..d75bce1058668d57fc7e242e654827efdf4aaed5
--- /dev/null
+++ b/xAOD/xAODTracking/xAODTracking/TrackingPrimitives.h
@@ -0,0 +1,72 @@
+#ifndef XAODTRACKING_XAODPRIMITIVES_H
+#define XAODTRACKING_XAODPRIMITIVES_H
+
+#include <unistd.h>
+#include <Eigen/Core>
+#include <Eigen/Dense>
+
+namespace xAOD {
+    
+  using DefiningParameters_t  Eigen::Matrix<double, 5, 1>;
+  using ParametersCovMatrix_t Eigen::Matrix<double, 5, 5>;
+    /// Enums to identify who created this track and which properties does it have.
+  enum TrackFitter
+  {
+      ///Track fitter not defined.
+      Unknown        = 0,
+      ///tracks produced by the Kalman Fitter
+      KalmanFitter       = 1,
+      ///maximum number of enums
+      NumberOfTrackFitters     = 2
+  };
+
+  enum ParticleHypothesis { nonInteracting  = 0,
+    geantino        = 0,
+    electron        = 1,
+    muon            = 2,
+    pion            = 3,
+    kaon            = 4,
+    proton          = 5,
+    noHypothesis    = 99,
+    undefined       = 99
+  };
+
+  /// Enum allowing us to know where in FASER the parameters are defined.
+  enum ParameterPosition {
+    /// Parameter defined at the first plane.
+    FirstPlane,
+    /// Parameter defined at the position of the 1st measurement.
+    FirstMeasurement,
+    /// Parameter defined at the position of the last measurement.
+    LastMeasurement,
+    /// Parameter defined at the entrance to the calorimeter.
+    CalorimeterEntrance,
+    /// Parameter defined at the exit of the calorimeter.
+    CalorimeterExit
+  };
+
+
+  /// Enumerates the different types of information stored in Summary. 
+  /// Please note that the values have specific types - i.e. some are float, whilst most are uint8_t.
+  /// When adding a new transient information type, please make sure to increase numberOfTrackSummaryTypes.*/
+  enum SummaryType {
+    // --- Inner Detector
+    numberOfContribSCTLayers          = 1,  //!< number of contributing layers of the pixel detector [unit8_t].
+    numberOfStripHits                 = 2,  //!< number of hits in Strip [unit8_t].
+    numberOfStripOutliers             = 3,  //!< number of Strip outliers [unit8_t].
+    numberOfStripHoles                = 4,  //!< number of Strip holes [unit8_t].
+    numberOfStripDoubleHoles          = 5,  //!< number of Holes in both sides of a Strip module [unit8_t].
+    numberOfStripSharedHits           = 6,  //!< number of Strip hits shared by several tracks [unit8_t].
+    numberOfStripDeadSensors          = 7,  //!< number of dead Strip sensors crossed [unit8_t].
+    numberOfStripSpoiltHits           = 8,  //!< number of Strip hits with broad errors (width/sqrt(12)) [unit8_t].
+
+    // --- all
+    numberOfOutliersOnTrack           = 9,  //!< number of measurements flaged as outliers in TSOS [unit8_t].
+    standardDeviationOfChi2OS         = 10, //!< 100 times the standard deviation of the chi2 from the surfaces [unit8_t].
+    // -- numbers...
+    numberOfTrackSummaryTypes         = 11
+  };
+  
+} //  namespace xAOD 
+
+#endif // XAODTRACKING_XAODPRIMITIVES_H
\ No newline at end of file
diff --git a/xAOD/xAODTracking/xAODTracking/selection.xml b/xAOD/xAODTracking/xAODTracking/selection.xml
index 585d32b46a7ea7ee4bf23e581d66eafafda46016..e84b24622af33c98839c0b9c0417da7e840c0624 100644
--- a/xAOD/xAODTracking/xAODTracking/selection.xml
+++ b/xAOD/xAODTracking/xAODTracking/selection.xml
@@ -1,4 +1,25 @@
 <lcgdict>
+
+  <!-- TRACK DICTIONARIES -->
+  
+  <!-- Track dictionaries: -->
+  <class name="xAOD::Track">
+      <field name="m_p4" transient="true"/>
+      <field name="m_p4Cached" transient="true"/>
+  </class>
+  
+  <class name="xAOD::TrackAuxContainer"
+      id="C3B01EA0-CA87-4C96-967F-E0F9A75BD370"/>
+  <class name="xAOD::TrackContainer"
+      id="F7564EE8-3BD2-11E3-A42F-6C3BE51AB9F1"/>
+  
+  <!-- All smart pointer dictionaries for xAOD::IParticle -->
+  <class name="DataLink<xAOD::TrackContainer>" />
+  <class name="std::vector<DataLink<xAOD::TrackContainer> >" />
+  <class name="ElementLink<xAOD::TrackContainer>" />
+  <class name="std::vector<ElementLink<xAOD::TrackContainer> >" />
+  <class name="std::vector<std::vector<ElementLink<xAOD::TrackContainer> > >" />
+  
   <!-- StripRawData dictionaries: -->
   <class name="xAOD::StripRawDataAuxContainer"                                           
          id="788781DA-FE8A-414A-A72B-6E846094FCF8" />                                              
diff --git a/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h b/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h
index 00d1f615050e3b2c3817c4e977a369b112ccf3fe..cb4bb673e608ac61b110e1a4c66dbbc5f5e3d7bf 100644
--- a/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h
+++ b/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h
@@ -20,14 +20,29 @@
 #include "AthLinks/ElementLink.h"
  
 // Local include(s):
+#include "xAODTracking/TrackContainer.h"
+#include "xAODTracking/TrackContainer.h"
+#include "xAODTracking/TrackAuxContainer.h"
+
 #include "xAODTracking/StripClusterContainer.h"
 #include "xAODTracking/StripClusterAuxContainer.h"
 
 #include "xAODTracking/StripRawDataContainer.h"
 #include "xAODTracking/StripRawDataAuxContainer.h"
 
+#include "xAODTracking/TrackingPrimitives.h"
+
 namespace {
   struct GCCXML_DUMMY_INSTANTIATION_XAODTRACKING {
+      
+      xAOD::TrackContainer                                              c1;
+      DataLink< xAOD::TrackContainer >                                  l1;
+      ElementLink< xAOD::TrackContainer >                               l2;
+      ElementLinkVector< xAOD::TrackContainer >                         l3;
+      std::vector< DataLink< xAOD::TrackContainer > >                   l4;
+      std::vector< ElementLink< xAOD::TrackContainer > >                l5;
+      std::vector< ElementLinkVector< xAOD::TrackContainer > >          l6;
+      std::vector< std::vector< ElementLink< xAOD::TrackContainer > > > l7;
 
       // Container(s):
       xAOD::StripClusterContainer                                                    c4;