diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/BaseTrackVertexAssociationTool.cxx b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/BaseTrackVertexAssociationTool.cxx
index 68306d83f9ee4a63bdab91077013441c29323991..d1ca4978451e011825ac81b42f1a9e4c46e6f63e 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/BaseTrackVertexAssociationTool.cxx
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/BaseTrackVertexAssociationTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h"
@@ -30,6 +30,8 @@ StatusCode BaseTrackVertexAssociationTool::initialize()
   ATH_MSG_INFO("Cut on d0 significance: " << m_d0sig_cut << "\t(d0sig_cut)");
   ATH_MSG_INFO("Cut on Δz * sin θ: " << m_dzSinTheta_cut << "\t(dzSinTheta_cut)");
 
+  ATH_MSG_WARNING("BaseTrackVertexAssociationTool is being depricated. Please use the new TrackVertexAssociationTool instead.");
+
   return StatusCode::SUCCESS;
 }
 
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LinkDef.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LinkDef.h
index f9fa452558b6689ef1035f603096f64ab7ab8510..368eab5d2c469f905a3fab4534fbcdd6e88c3c62 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LinkDef.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LinkDef.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifdef __CINT__
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LooseTrackVertexAssociationTool.cxx b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LooseTrackVertexAssociationTool.cxx
index ee6da8f6ab16d35845502794cb589a3c0f01e63c..cd7ffb2d274464bdea160fb7f3ca7ec1c608458a 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LooseTrackVertexAssociationTool.cxx
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/LooseTrackVertexAssociationTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #define LOOSETRACKVERTEXASSOCIATIONTOOL_CXX
@@ -27,6 +27,9 @@ namespace CP
   StatusCode LooseTrackVertexAssociationTool::initialize()
   {
     //    dz_cut=2;
+
+    ATH_MSG_WARNING("LooseTrackVertexAssociationTool is being depricated. Please use the new TrackVertexAssociationTool instead.");
+
     return StatusCode::SUCCESS;
   }
 
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/TightTrackVertexAssociationTool.cxx b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/TightTrackVertexAssociationTool.cxx
index 60f6af0da4a0510c46b59787db8c6e8719818a10..88ffbc0f18711a0102ae778bc62e1dc4482f7a28 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/TightTrackVertexAssociationTool.cxx
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/TightTrackVertexAssociationTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #define TIGHTTRACKVERTEXASSOCIATIONTOOL_CXX
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/TrackVertexAssociationTool.cxx b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/TrackVertexAssociationTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c43bba155b9306bcdc609c83596cd61f1daf9491
--- /dev/null
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/Root/TrackVertexAssociationTool.cxx
@@ -0,0 +1,339 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrackVertexAssociationTool/TrackVertexAssociationTool.h"
+
+#include "xAODEventInfo/EventInfo.h"
+#include "xAODTracking/TrackParticle.h"
+#include "xAODTracking/TrackParticleContainer.h"
+#include "xAODTracking/TrackParticlexAODHelpers.h"
+#include "xAODTracking/TrackingPrimitives.h"
+
+using namespace std;
+
+namespace CP {
+
+TrackVertexAssociationTool::TrackVertexAssociationTool(const std::string& name) :
+  AsgTool(name),
+  m_wp("Nominal"),
+  m_d0_cut(-1),
+  m_use_d0sig(false),
+  m_d0sig_cut(-1),
+  m_dzSinTheta_cut(-1),
+  m_doUsedInFit(false),
+  m_requirePriVtx(false)
+{
+  declareProperty("WorkingPoint", m_wp);
+  declareProperty("d0_cut", m_d0_cut);
+  declareProperty("use_d0sig", m_use_d0sig);
+  declareProperty("d0sig_cut", m_d0sig_cut);
+  declareProperty("dzSinTheta_cut", m_dzSinTheta_cut);
+  declareProperty("doUsedInFit", m_doUsedInFit);
+  declareProperty("requirePriVtx", m_requirePriVtx);
+}
+
+StatusCode TrackVertexAssociationTool::initialize()
+{
+  ATH_MSG_INFO(" Initializing TrackVertexAssociationTool");
+
+  if ( m_wp == "Electron" ) {
+    m_d0_cut = -1;
+    m_use_d0sig = true;
+    m_d0sig_cut = 5.0;
+    m_dzSinTheta_cut = 0.5;
+    m_doUsedInFit = false;
+    m_requirePriVtx = false;
+  } else if ( m_wp == "Muon" ) {
+    m_d0_cut = -1;
+    m_use_d0sig = true;
+    m_d0sig_cut = 3.0;
+    m_dzSinTheta_cut = 0.5;
+    m_doUsedInFit = false;
+    m_requirePriVtx = false;
+  } else if ( m_wp == "Loose" ) {
+    m_d0_cut = -1;
+    m_use_d0sig = false;
+    m_d0sig_cut = -1;
+    m_dzSinTheta_cut = 3.;
+    m_doUsedInFit = true;
+    m_requirePriVtx = true;
+  } else if ( m_wp == "Nominal" ) {
+    m_d0_cut = 2.;
+    m_use_d0sig = false;
+    m_d0sig_cut = -1;
+    m_dzSinTheta_cut = 3.;
+    m_doUsedInFit = false;
+    m_requirePriVtx = false;
+  } else if ( m_wp == "Tight" ) {
+    m_d0_cut = 0.5;
+    m_use_d0sig = false;
+    m_d0sig_cut = -1;
+    m_dzSinTheta_cut = 0.5;
+    m_doUsedInFit = false;
+    m_requirePriVtx = false;
+  } else if ( m_wp == "Custom" ) {
+    // nothing to do here
+  } else {
+    ATH_MSG_ERROR("Invalid TVA working point '" << m_wp << "' - for a custom configuration, please provide 'Custom' for the 'WorkingPoint' property");
+    return StatusCode::FAILURE;
+  }
+
+  if ( m_wp == "Custom" ) {
+    ATH_MSG_INFO("TVA working point 'Custom' provided - tool properties are initialized to default values unless explicitly set by the user");
+  } else {
+    ATH_MSG_INFO("TVA working point '" << m_wp << "' provided - tool properties have been configured accordingly");
+  }
+
+  if(m_use_d0sig){
+    ATH_MSG_INFO("Cut on d0 significance: " << m_d0sig_cut << "\t(d0sig_cut)");
+  } else {
+    ATH_MSG_INFO("Cut on d0: " << m_d0_cut << "\t(d0_cut)");
+  }
+  ATH_MSG_INFO("Cut on Δz * sin θ: " << m_dzSinTheta_cut << "\t(dzSinTheta_cut)");
+
+  ATH_MSG_INFO("Allow UsedInFit MatchStatus: " << m_doUsedInFit << "\t(doUsedInFit)");
+  ATH_MSG_INFO("Require VxType::PriVtx for unique match: " << m_requirePriVtx << "\t(requirePriVtx)");
+
+  return StatusCode::SUCCESS;
+}
+
+bool TrackVertexAssociationTool::isCompatible(
+    const xAOD::TrackParticle &trk, const xAOD::Vertex &vx) const
+{
+  float dzSinTheta = 0.;
+  bool status = false;
+
+  MatchStatus matchstatus = isMatch(trk, vx, dzSinTheta);
+
+  if(matchstatus == TrackVertexAssociationTool::UsedInFit || matchstatus == TrackVertexAssociationTool::Matched ) {
+    status = true;
+  }
+  else {
+    status = false;
+  }
+  return status;
+}
+
+xAOD::TrackVertexAssociationMap TrackVertexAssociationTool::getMatchMap(
+    std::vector<const xAOD::TrackParticle *> &trk_list,
+    std::vector<const xAOD::Vertex *> &vx_list) const
+{
+  return getMatchMapInternal(trk_list, vx_list);
+}
+
+xAOD::TrackVertexAssociationMap TrackVertexAssociationTool::getMatchMap(
+    const xAOD::TrackParticleContainer &trkCont,
+    const xAOD::VertexContainer &vxCont) const
+{
+  return getMatchMapInternal(trkCont, vxCont);
+}
+
+const xAOD::Vertex *TrackVertexAssociationTool::getUniqueMatchVertex(
+    const xAOD::TrackParticle &trk,
+    std::vector<const xAOD::Vertex *> &vx_list) const
+{
+  return getUniqueMatchVertexInternal(trk, vx_list);
+}
+
+ElementLink<xAOD::VertexContainer>
+TrackVertexAssociationTool::getUniqueMatchVertexLink(
+    const xAOD::TrackParticle &trk, const xAOD::VertexContainer &vxCont) const
+{
+  ElementLink<xAOD::VertexContainer> vx_link_tmp;
+
+  const xAOD::Vertex *vx_tmp = getUniqueMatchVertexInternal(trk, vxCont);
+  if (vx_tmp) {
+    vx_link_tmp.toContainedElement(vxCont, vx_tmp);
+  }
+  return vx_link_tmp;
+}
+
+xAOD::TrackVertexAssociationMap
+TrackVertexAssociationTool::getUniqueMatchMap(
+    std::vector<const xAOD::TrackParticle *> &trk_list,
+    std::vector<const xAOD::Vertex *> &vx_list) const
+{
+  return getUniqueMatchMapInternal(trk_list, vx_list);
+}
+
+xAOD::TrackVertexAssociationMap
+TrackVertexAssociationTool::getUniqueMatchMap(
+    const xAOD::TrackParticleContainer &trkCont,
+    const xAOD::VertexContainer &vxCont) const
+{
+  return getUniqueMatchMapInternal(trkCont, vxCont);
+}
+
+// private methods
+
+TrackVertexAssociationTool::MatchStatus TrackVertexAssociationTool::isMatch(const xAOD::TrackParticle &trk,
+                                                                            const xAOD::Vertex &vx,
+                                                                            float &dzSinTheta) const
+{
+  // ATH_MSG_DEBUG("<###### Enter: isMatch() function ######>");
+
+  if (vx.vertexType() == xAOD::VxType::NoVtx) {
+    // ATH_MSG_DEBUG(
+    //     "The Vertex is a fake one, will not do track-vertex association");
+    return UnMatch;
+  }
+
+  float vx_z0 = vx.z();
+  float trk_z0 = trk.z0();
+  float beamspot_z0 = trk.vz();
+  float theta = trk.theta();
+  // calculate Δz * sin θ
+  dzSinTheta = fabs((trk_z0 - vx_z0 + beamspot_z0) * sin(theta));
+
+  // If vertex fit information is flagged to be used,
+  if(m_doUsedInFit) {
+    bool usedInFit = trackParticleUsedInVertexFit( trk, vx );
+    if( usedInFit ) { // check whether the track is used for the given vertex fit.
+      ATH_MSG_DEBUG("This track is used to fit the vertex");
+      return UsedInFit;
+    } else {
+      bool usedInAnyFit = trackParticleUsedInVertexFit( trk );
+      if( usedInAnyFit ) { // otherwise, automatically return UnMatch if it was used in another vertex fit
+        return UnMatch;
+      }
+    }
+  }
+
+  // Now use cuts to determine a match
+  // Only arrive here if:
+  // 1. vertex fit info was flagged to be used but track wasn't used in any vertex fit
+  // 2. vertex fit info wasn't flagged to be used
+
+  const xAOD::EventInfo *evt{0};
+  if (evtStore()->retrieve(evt, "EventInfo").isFailure()) {
+    throw std::runtime_error("Could not retrieve EventInfo");
+  }
+
+  if (m_use_d0sig) {
+
+    double d0sig = xAOD::TrackingHelpers::d0significance(
+        &trk, evt->beamPosSigmaX(), evt->beamPosSigmaY(), evt->beamPosSigmaXY());
+    // d0 significance cut
+    if (m_d0sig_cut >= 0 && fabs(d0sig) > m_d0sig_cut)
+      return UnMatch;
+
+  } else {
+
+    float trk_d0=trk.d0();
+    // d0 cut
+    if (m_d0_cut >= 0 && fabs(trk_d0) > m_d0_cut)
+      return UnMatch;
+
+  }
+
+  if (m_dzSinTheta_cut >= 0 && dzSinTheta > m_dzSinTheta_cut)
+    return UnMatch;
+
+  return Matched;
+}
+
+template <typename U, typename V>
+xAOD::TrackVertexAssociationMap
+TrackVertexAssociationTool::getMatchMapInternal(U &trk_list, V &vx_list) const
+{
+  xAOD::TrackVertexAssociationMap trktovxmap;
+
+  for (auto *vertex : vx_list) {
+    xAOD::TrackVertexAssociationList trktovxlist;
+    trktovxlist.clear();
+    for (auto *track : trk_list) {
+      if (isCompatible(*track, *vertex)) {
+        trktovxlist.push_back(track);
+      }
+    }
+    trktovxmap[vertex] = trktovxlist;
+  }
+
+  return trktovxmap;
+}
+
+template <typename T>
+const xAOD::Vertex *TrackVertexAssociationTool::getUniqueMatchVertexInternal(
+    const xAOD::TrackParticle &trk, T &vx_list) const
+{
+  float min_dz = m_dzSinTheta_cut;
+  const xAOD::Vertex *bestMatchVertex{0};
+
+  for (auto *vertex : vx_list) {
+    float dzSinTheta = 0.;
+    MatchStatus matchstatus = isMatch(trk, *vertex, dzSinTheta);
+    if(matchstatus == TrackVertexAssociationTool::UsedInFit) {
+      return vertex;
+    }
+    else {
+      if ((m_requirePriVtx && vertex->vertexType()==xAOD::VxType::PriVtx) || (!m_requirePriVtx)) {
+        if (matchstatus == TrackVertexAssociationTool::Matched) {
+          if (dzSinTheta < min_dz) {
+            min_dz = dzSinTheta;
+            bestMatchVertex = vertex;
+          }
+        }
+      }
+    }
+  }
+
+  // check if get the matched Vertex, for the tracks not used in vertex fit
+  if (!bestMatchVertex) {
+    ATH_MSG_DEBUG("Could not find any matched vertex for this track");
+  }
+
+  return bestMatchVertex;
+}
+
+template <typename T, typename U>
+xAOD::TrackVertexAssociationMap
+TrackVertexAssociationTool::getUniqueMatchMapInternal(T &trk_list,
+                                                  U &vx_list) const
+{
+  xAOD::TrackVertexAssociationMap trktovxmap;
+
+  // initialize map
+  for (auto *vertex : vx_list) {
+    xAOD::TrackVertexAssociationList trktovxlist;
+    trktovxlist.clear();
+
+    trktovxmap[vertex] = trktovxlist;
+  }
+
+  for (auto *track : trk_list) {
+    const xAOD::Vertex *vx_match = getUniqueMatchVertexInternal(*track, vx_list);
+    if (vx_match) {
+      // can find matched vertex
+      trktovxmap[vx_match].push_back(track);
+    }
+  }
+
+  return trktovxmap;
+}
+
+bool TrackVertexAssociationTool::trackParticleUsedInVertexFit(const xAOD::TrackParticle& trk,
+                     const xAOD::Vertex& vx) const
+{
+  for (const auto& tpLink : vx.trackParticleLinks())
+    if (*tpLink == &trk) return true;
+
+  return false;
+}
+
+bool TrackVertexAssociationTool::trackParticleUsedInVertexFit(const xAOD::TrackParticle& trk) const
+{
+  SG::ReadHandle<xAOD::VertexContainer> vertices { m_vertexKey };
+  if (!vertices.isValid())
+  {
+    ATH_MSG_WARNING("No VertexContainer with key = " << m_vertexKey.key());
+    return false;
+  }
+
+  for (const auto& vx : *vertices)
+    if (trackParticleUsedInVertexFit(trk, *vx)) return true;
+
+  return false;
+}
+
+} // namespace CP
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h
index f8290f36598e873e71f37a0c11f75e8d2083b935..43916ba5565d0c04e74b8ea9240a71f653bd8878 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef BASETRACKVERTEXASSOCIATIONTOOL_H
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/CheckExc.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/CheckExc.h
index e6acd75688345e822da95973cda1bb2c44b215a6..6bf27eb0bba17fd1e578a2c913ded9bfe41fffa5 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/CheckExc.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/CheckExc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ElectronTrackVertexAssociationTool.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ElectronTrackVertexAssociationTool.h
index 57ef37462781d67eecb81c5e4be6ebb182925c03..ac7704a763cd525716d7219233df19a2a1bd1ed8 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ElectronTrackVertexAssociationTool.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ElectronTrackVertexAssociationTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ITrackVertexAssociationTool.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ITrackVertexAssociationTool.h
index 13cc903afb6433a9a17eeb76934bef16c71f453e..53e9ba365f21883f6786165bd8e4904f5c5ce26a 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ITrackVertexAssociationTool.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/ITrackVertexAssociationTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef ITRACKVERTEXASSOCIATIONTOOL_H
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/LooseTrackVertexAssociationTool.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/LooseTrackVertexAssociationTool.h
index 8c53877ce86ae94d7d7719c02a03116e7d762327..d620cb1ebab45d8e0288f11eaa4a2494bb4e5bdc 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/LooseTrackVertexAssociationTool.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/LooseTrackVertexAssociationTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef LOOSETRACKVERTEXASSOCIATIONTOOL_H
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/MuonTrackVertexAssociationTool.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/MuonTrackVertexAssociationTool.h
index 559baa8df1e95d137143af2aa24440e95d9e5076..e5ccb119b2a97bb42067c931e9652cd9b8de23be 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/MuonTrackVertexAssociationTool.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/MuonTrackVertexAssociationTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TightTrackVertexAssociationTool.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TightTrackVertexAssociationTool.h
index 096110ce28e0b188c124cf31e4ac246160ab44a1..f0426dca56509f6899c20ec1d36cd496c1ba4f3e 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TightTrackVertexAssociationTool.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TightTrackVertexAssociationTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TIGHTTRACKVERTEXASSOCIATIONTOOL_H
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationMap.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationMap.h
index 8384285380884480639971fbdd449c092d89c9f8..7484518a6d8b70682cd9738323d91329f91fd4df 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationMap.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationMap.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRACKVERTEXASSOCIATIONMAP_H
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationTool.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..838eed054aece0886f7e0590f361e44b2dc3063e
--- /dev/null
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationTool.h
@@ -0,0 +1,111 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRACKVERTEXASSOCIATIONTOOL_H
+#define TRACKVERTEXASSOCIATIONTOOL_H
+
+#include "AsgTools/AsgTool.h"
+#include "TrackVertexAssociationTool/ITrackVertexAssociationTool.h"
+#include "AthContainers/AuxElement.h"
+#include "AthLinks/ElementLink.h"
+
+#include "xAODTracking/TrackParticleFwd.h"
+#include "xAODTracking/TrackParticleContainerFwd.h"
+#include "xAODTracking/VertexContainer.h"
+#include "TrackVertexAssociationTool/TrackVertexAssociationMap.h"
+
+#include <string>
+
+namespace CP {
+
+  /// General track-vertex association tool
+  ///
+  /// Supported properties (set via setProperty):
+  ///
+  /// - WorkingPoint: Working Point to operate on.
+  /// - d0_cut: Cut on d0. Not applied if set to -1.
+  /// - use_d0sig: flag to cut on d0sig instead of d0.
+  /// - d0sig_cut: Cut on \f$ |d_{0}^{BL} \mathrm{significance}| \f$.  Not applied if set to -1.
+  /// - dzSinTheta_cut: Cut on \f$ |\Delta z_{0}^{BL} \sin \theta| \f$ (in mm).  Not applied if set to -1.
+  /// - doUsedInFit: Control whether to allow for a MatchStatus of UsedInFit.
+  /// - requirePriVtx: Control whether a vertex must be VxType::PriVtx in order for a track (not UsedInFit) to be uniquely matched to it
+  ///
+  /// To apply the recommendations, please visit
+  /// https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TrackingCPRecsEarly2018#Track_to_Vertex_Association_Tool
+  class TrackVertexAssociationTool : public asg::AsgTool, virtual public ITrackVertexAssociationTool
+  {
+    // MatchCode for the matching
+    enum MatchStatus{
+      UsedInFit=1, // Track used in the vertex fitting process and doUsedInFit = true
+      Matched=2,   // Track matched to the vertex by IP cuts alone
+      UnMatch=0};  // Track not matched to the vertex
+
+    ASG_TOOL_CLASS(TrackVertexAssociationTool, ITrackVertexAssociationTool)
+    public:
+      TrackVertexAssociationTool(const std::string& name);
+
+      virtual StatusCode initialize() override;
+
+      virtual bool isCompatible( const xAOD::TrackParticle &trk, const xAOD::Vertex &vx ) const override;
+
+      virtual xAOD::TrackVertexAssociationMap getMatchMap( std::vector< const xAOD::TrackParticle *> &trk_list, std::vector< const xAOD::Vertex *> &vx_list) const override;
+      virtual xAOD::TrackVertexAssociationMap getMatchMap( const xAOD::TrackParticleContainer &trkCont, const xAOD::VertexContainer &vxCont ) const override;
+
+      virtual ElementLink< xAOD::VertexContainer> getUniqueMatchVertexLink(const xAOD::TrackParticle &, const xAOD::VertexContainer &vxCont) const override;
+      virtual const xAOD::Vertex* getUniqueMatchVertex( const xAOD::TrackParticle &trk, std::vector< const xAOD::Vertex *> &vx_list) const override;
+
+      virtual xAOD::TrackVertexAssociationMap getUniqueMatchMap( std::vector< const xAOD::TrackParticle *> &trk_list , std::vector< const xAOD::Vertex *> &vx_list) const override;
+      virtual xAOD::TrackVertexAssociationMap getUniqueMatchMap( const xAOD::TrackParticleContainer &trkCont , const xAOD::VertexContainer &vxCont) const override;
+
+    private:
+      /// Checks if a track-vertex pair passes the cuts.  Returns
+      /// Δz * sin θ of the pair in `dzSinTheta` if successful.
+      MatchStatus isMatch(const xAOD::TrackParticle &trk, const xAOD::Vertex &vx,
+                   float &dzSinTheta) const;
+
+      template <typename T, typename U>
+      xAOD::TrackVertexAssociationMap getMatchMapInternal(T &trk_list,
+                                                      U &vx_list) const;
+
+      template <typename T, typename U>
+      xAOD::TrackVertexAssociationMap getUniqueMatchMapInternal(T &trk_list,
+                                                            U &vx_list) const;
+
+      template <typename T>
+      const xAOD::Vertex *getUniqueMatchVertexInternal(const xAOD::TrackParticle &trk,
+                                                   T &vx_list) const;
+
+      // check whether TrackParticle is used in the fit of a given vertex
+      bool trackParticleUsedInVertexFit(const xAOD::TrackParticle& trk, const xAOD::Vertex& vx) const;
+
+      // check whether TrackParticle is used in the fit of ANY vertex
+      bool trackParticleUsedInVertexFit(const xAOD::TrackParticle& trk) const;
+
+      // Working Point to operate on
+      std::string m_wp;
+
+      // Cut on d0
+      float m_d0_cut;
+      // flag to cut on d0sig instead of d0
+      bool m_use_d0sig;
+      // Cut on d0 significance
+      float m_d0sig_cut;
+
+      // Cut on dz*sin theta
+      float m_dzSinTheta_cut;
+
+      // Control whether to allow for a MatchStatus of UsedInFit
+      bool m_doUsedInFit;
+
+      // Control whether a vertex must be VxType::PriVtx in order for a track (not UsedInFit) to be uniquely matched to it
+      bool m_requirePriVtx;
+
+      SG::ReadHandleKey<xAOD::VertexContainer> m_vertexKey { this, "VertexContainer", "PrimaryVertices",
+                                                       "container for reconstructed primary vertices" };
+
+  };
+
+} // namespace CP
+
+#endif // TRACKVERTEXASSOCIATIONTOOL_H
\ No newline at end of file
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationToolDict.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationToolDict.h
index aeeab5f7998f4b2b564d18465a687df8289030c8..2285a9a975e267f3214ac5769f04ed8f3320c671 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationToolDict.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/TrackVertexAssociationToolDict.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TrackVertexAssociationToolDict_h
@@ -12,6 +12,7 @@
 //#include "TrackVertexAssociationTool/ITrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/LooseTrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/TightTrackVertexAssociationTool.h"
+#include "TrackVertexAssociationTool/TrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/ElectronTrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/MuonTrackVertexAssociationTool.h"
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/selection.xml b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/selection.xml
index 98b28b376d30dfd9561b3da5ee061de7d94fb477..ff9fdf6236db43f2ae9d6e3640b7a6f701efc2ac 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/selection.xml
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/TrackVertexAssociationTool/selection.xml
@@ -1,4 +1,5 @@
 <lcgdict>
+  <class name="CP::TrackVertexAssociationTool" />
   <class name="CP::TightTrackVertexAssociationTool" />
   <class name="CP::LooseTrackVertexAssociationTool" />
   <class name="CP::BaseTrackVertexAssociationTool" />
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/share/jobOption_TrackVertexAssoTest.py b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/share/jobOption_TrackVertexAssoTest.py
index d7b881ce98c2188e6956612165428fe4b6110e7d..65e16d6737faa6935f44c0afca54a685aeccfece 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/share/jobOption_TrackVertexAssoTest.py
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/share/jobOption_TrackVertexAssoTest.py
@@ -12,35 +12,21 @@ ServiceMgr.EventSelector.InputCollections = filelist
 from AthenaCommon.AlgSequence import AlgSequence
 topSequence = AlgSequence()
 
-## declare tighttrackvertexassotool by do first PV dz recovery(match the association procedure of JVF and JVT, default would be for each PV).
-tighttrackvertexassotool=CfgMgr.CP__TightTrackVertexAssociationTool("TightTrackVertexAssociationTool", dzSinTheta_cut=3, doPV=True)
-
-loosetrackvertexassotool=CfgMgr.CP__LooseTrackVertexAssociationTool("LooseTrackVertexAssociationTool", dzSinTheta_cut=3, d0_cut=2)
-electrontrackvertexassotool=CfgMgr.CP__ElectronTrackVertexAssociationTool("ElectronTrackVertexAssociationTool")
-
-
-
-#tighttrackvertexassotool.OutputLevel=DEBUG
-
-ToolSvc += tighttrackvertexassotool
-ToolSvc += loosetrackvertexassotool
-ToolSvc += electrontrackvertexassotool
+# instantiate the tool
+tvatool=CfgMgr.CP__TrackVertexAssociationTool("TrackVertexAssociationTool",
+                                              WorkingPoint="Nominal")
+ToolSvc += tvatool
 
 testAlg=CfgMgr.TrackVertexAssoTestAlg(
         TrackContainer="InDetTrackParticles",
         VertexContainer="PrimaryVertices",
-        TightTrackVertexAssoTool=tighttrackvertexassotool,
-        LooseTrackVertexAssoTool=loosetrackvertexassotool,
-        ElectronTrackVertexAssoTool=electrontrackvertexassotool
+        TVATool=tvatool
         )
 
-#testAlg.OutputLevel=DEBUG
-
-
-#theApp.setOutputLevel(DEBUG)
-
 topSequence += testAlg
 
 theApp.EvtMax = 100
+#testAlg.OutputLevel=DEBUG
+#theApp.setOutputLevel(DEBUG)
 ServiceMgr.EventSelector.SkipEvents = 0
 ServiceMgr.MessageSvc.defaultLimit = 999
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.cxx b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.cxx
index fddebc7d52faf083d8e84dd39ec17094096b8f7f..9387be90b3f4f0ffea258aa387181311b3b8748a 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.cxx
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.cxx
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 // TrackVertexAssoTestAlg.cxx 
@@ -38,10 +38,7 @@ TrackVertexAssoTestAlg::TrackVertexAssoTestAlg( const std::string& name,
   // Property declaration
   // 
   //declareProperty( "Property", m_nProperty );
-  declareProperty( "TightTrackVertexAssoTool", m_tighttrackvertexassoTool);
-  declareProperty( "LooseTrackVertexAssoTool", m_loosetrackvertexassoTool);
-  declareProperty( "ElectronTrackVertexAssoTool", m_electrontrackvertexassoTool);
-
+  declareProperty( "TVATool", m_TVATool );
 }
 
 // Destructor
@@ -58,10 +55,7 @@ StatusCode TrackVertexAssoTestAlg::initialize()
   ATH_CHECK( m_trkContname.initialize() );
   ATH_CHECK( m_vertexContname.initialize() );
   //retrieve tool from ToolHandle
-  CHECK(m_loosetrackvertexassoTool.retrieve());
-  CHECK(m_tighttrackvertexassoTool.retrieve());
-  CHECK(m_electrontrackvertexassoTool.retrieve());
-
+  CHECK(m_TVATool.retrieve());
 
   return StatusCode::SUCCESS;
 }
@@ -77,7 +71,7 @@ StatusCode TrackVertexAssoTestAlg::execute()
 {  
   ATH_MSG_DEBUG ("Executing " << name() << "...");
 
-  // retrieve TrackContainer 
+  // retrieve containers
   SG::ReadHandle<xAOD::TrackParticleContainer> trkCont(m_trkContname);
 
   SG::ReadHandle<xAOD::VertexContainer> vxCont(m_vertexContname);
@@ -88,13 +82,19 @@ StatusCode TrackVertexAssoTestAlg::execute()
     return StatusCode::FAILURE;
   }
 
-  // do Match, match to all compitable vertices
-  xAOD::TrackVertexAssociationMap trkvxassoMap_tight = m_tighttrackvertexassoTool->getMatchMap(*trkCont, *vxCont);
-  xAOD::TrackVertexAssociationMap trkvxassoMap_loose = m_loosetrackvertexassoTool->getMatchMap(*trkCont, *vxCont);
-  xAOD::TrackVertexAssociationMap trkvxassoMap_electron = m_electrontrackvertexassoTool->getMatchMap(*trkCont, *vxCont);
+  // Test isCompitable
+  ATH_MSG_INFO("Testing TrackVertexAssociationTool::isCompatible...");
+  if(trkCont->size()!=0 && vxCont->size()!=0)
+  {
+    bool isMatched = m_TVATool->isCompatible(*(trkCont->at(0)), *(vxCont->at(0)));
+    ATH_MSG_INFO("Is the first track compatible with the first vertex (the PriVx)? "<< isMatched);
+  }
 
-  ATH_MSG_INFO("Number of vertices for electron track-vertex association: " << trkvxassoMap_electron.size());
-  for (const auto& assoc: trkvxassoMap_electron) {
+  // Test getMatchMap
+  ATH_MSG_INFO("Testing TrackVertexAssociationTool::getMatchMap...");
+  xAOD::TrackVertexAssociationMap trkvxassoMap = m_TVATool->getMatchMap(*trkCont, *vxCont);
+  ATH_MSG_INFO("Number of vertices for track-vertex association: " << trkvxassoMap.size());
+  for (const auto& assoc: trkvxassoMap) {
     const xAOD::Vertex *vx = assoc.first;
     ATH_MSG_INFO("vertex at x, y, z " <<
                  setprecision(4) << setfill(' ') <<
@@ -102,47 +102,51 @@ StatusCode TrackVertexAssoTestAlg::execute()
                  " has " << assoc.second.size() << " associated tracks");
   }
 
+  // Test getUniqueMatchVertex
+  ATH_MSG_INFO("Testing TrackVertexAssociationTool::getUniqueMatchVertex...");
   std::vector<const xAOD::Vertex* > v_vx;
   v_vx.clear();
-
+  for(auto *vertex : *vxCont) {
+    v_vx.push_back(vertex);
+  }
   if(trkCont->size()!=0)
   {
-    const xAOD::Vertex *vx=m_tighttrackvertexassoTool->getUniqueMatchVertex(*(trkCont->at(0)), v_vx);
-    ATH_MSG_INFO(vx);
+    const xAOD::Vertex *vx=m_TVATool->getUniqueMatchVertex(*(trkCont->at(0)), v_vx);
+    ATH_MSG_INFO("Unique match vertex for first track: " << vx);
   }
 
-  // do Match, only match the best matched vertex
-  xAOD::TrackVertexAssociationMap trkvxassoUniqueMap_tight = m_tighttrackvertexassoTool->getUniqueMatchMap(*trkCont, *vxCont);
-  xAOD::TrackVertexAssociationMap trkvxassoUniqueMap_loose = m_loosetrackvertexassoTool->getUniqueMatchMap(*trkCont, *vxCont);
-  xAOD::TrackVertexAssociationMap trkvxassoUniqueMap_electron = m_electrontrackvertexassoTool->getUniqueMatchMap(*trkCont, *vxCont);
-
-//  std::vector<xAOD::TrackParticle &> trk_list_ref;
-//  trk_list_ref.clear();
-
-
-  // example of access tracks match to each vertex, tracks stored in std::vector<xAOD::TrackParticle* >, more seen TrackVertexAssociationMap.h file
-
-//  const xAOD::Vertex *pv=vxCont->at(0);
-//  xAOD::TrackVertexAssociationList trkvxassoList_tight=trkvxassoMap_tight[pv];
-//  ATH_MSG_INFO("Number of track PV associated: "<< trkvxassoList_tight.size());
-
-
-  // Test of ElementLink
-  if(trkCont->size()>0)
+  // Test getUniqueMatchVertexLink
+  ATH_MSG_INFO("Testing TrackVertexAssociationTool::getUniqueMatchVertexLink...");
+  if(trkCont->size() > 2)
   {
-    ElementLink<xAOD::VertexContainer> match_vx=m_tighttrackvertexassoTool->getUniqueMatchVertexLink(*(trkCont->at(0)), *vxCont );
-
-    //  // 
-
+    ElementLink<xAOD::VertexContainer> match_vx = m_TVATool->getUniqueMatchVertexLink(*(trkCont->at(2)), *vxCont );
 
     if(match_vx.isValid())
     {
-      ATH_MSG_INFO( match_vx );
-      ATH_MSG_INFO( *match_vx );
-      ATH_MSG_INFO( (*match_vx)->z());
+      ATH_MSG_INFO( "Uniquely matched vertex for third track - ");
+      ATH_MSG_INFO( "Vertex ElementLink address: " << match_vx );
+      ATH_MSG_INFO( "Vertex address: " << *match_vx );
+      ATH_MSG_INFO( "Vertex z pos: " << (*match_vx)->z());
     }
   }
 
+  // Test getUniqueMatchMap
+  ATH_MSG_INFO("Testing TrackVertexAssociationTool::getUniqueMatchMap...");
+  xAOD::TrackVertexAssociationMap trkvxassoUniqueMap = m_TVATool->getUniqueMatchMap(*trkCont, *vxCont);
+  ATH_MSG_INFO("Number of vertices for track-vertex association: " << trkvxassoUniqueMap.size());
+  for (const auto& assoc: trkvxassoUniqueMap) {
+    const xAOD::Vertex *vx = assoc.first;
+    ATH_MSG_INFO("vertex at x, y, z " <<
+                 setprecision(4) << setfill(' ') <<
+                 setw(10) << vx->x() << ", " << setw(10) << vx->y() << ", " << setw(10) << vx->z() <<
+                 " has " << assoc.second.size() << " uniquely associated tracks");
+  }
+
+  // Example of accessing tracks matched to each vertex. Tracks are stored in a std::vector<xAOD::TrackParticle* >, for more details see TrackVertexAssociationMap.h
+
+  // const xAOD::Vertex *pv=vxCont->at(0);
+  // xAOD::TrackVertexAssociationList trkvxassoList = trkvxassoMap[pv];
+  // ATH_MSG_INFO("Number of tracks associated to the PriVx: " << trkvxassoList.size());
 
 
 
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.h b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.h
index 5e64fbb28e8dba5036d6d4feefc67fa183401514..6a9580567ddfa92760b001c9b1cb6b822986294a 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.h
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/TrackVertexAssoTestAlg.h
@@ -1,7 +1,7 @@
 ///////////////////////// -*- C++ -*- /////////////////////////////
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 // TrackVertexAssoTestAlg.h 
@@ -66,9 +66,7 @@ class TrackVertexAssoTestAlg
   /// Default constructor: 
   TrackVertexAssoTestAlg();
 
-  ToolHandle<CP::ITrackVertexAssociationTool> m_tighttrackvertexassoTool;
-  ToolHandle<CP::ITrackVertexAssociationTool> m_loosetrackvertexassoTool;
-  ToolHandle<CP::ITrackVertexAssociationTool> m_electrontrackvertexassoTool;
+  ToolHandle<CP::ITrackVertexAssociationTool> m_TVATool;
 
   /// Containers
   
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/components/TrackVertexAssociationTool_entries.cxx b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/components/TrackVertexAssociationTool_entries.cxx
index fc583d5648e8a9cb6f19d5476ff7b7ba35ae3361..f96acbad665df7f46937c869ed0c253d6efc265e 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/components/TrackVertexAssociationTool_entries.cxx
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/src/components/TrackVertexAssociationTool_entries.cxx
@@ -1,3 +1,4 @@
+#include "TrackVertexAssociationTool/TrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/LooseTrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/TightTrackVertexAssociationTool.h"
 #include "TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h"
@@ -8,6 +9,7 @@
 
 using namespace xAOD;
 
+DECLARE_COMPONENT( CP::TrackVertexAssociationTool )
 DECLARE_COMPONENT( CP::LooseTrackVertexAssociationTool )
 DECLARE_COMPONENT( CP::TightTrackVertexAssociationTool )
 DECLARE_COMPONENT( CP::BaseTrackVertexAssociationTool )
diff --git a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/util/TrackVertexAssoValidator.cxx b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/util/TrackVertexAssoValidator.cxx
index 391dfd39a2f4176ad49b1eb237acac24d9e7c9fc..b7e7ebf7557d7e81bf5dc1640e01974c00844bac 100644
--- a/InnerDetector/InDetRecTools/TrackVertexAssociationTool/util/TrackVertexAssoValidator.cxx
+++ b/InnerDetector/InDetRecTools/TrackVertexAssociationTool/util/TrackVertexAssoValidator.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 // Used for validation the track vertex association tools in RootCore implementation
@@ -22,6 +22,8 @@
 #   include "xAODRootAccess/tools/ReturnCheck.h"
 #endif
 
+#include <AsgTools/MessageCheck.h>
+
 // EDM include(s):
 #include "xAODTracking/TrackParticle.h"
 #include "xAODTracking/Vertex.h"
@@ -29,12 +31,12 @@
 #include "xAODTracking/VertexContainer.h"
 
 // Local include(s):
-#include "TrackVertexAssociationTool/LooseTrackVertexAssociationTool.h"
-#include "TrackVertexAssociationTool/TightTrackVertexAssociationTool.h"
-#include "TrackVertexAssociationTool/BaseTrackVertexAssociationTool.h"
+#include "TrackVertexAssociationTool/TrackVertexAssociationTool.h"
 
 int main() {
 
+   using namespace asg::msgUserCode;
+
    // The name of the application:
    static const char* APP_NAME = "TrackVertexAssoValidator";
 
@@ -45,8 +47,7 @@ int main() {
    std::unique_ptr< TFile > infile( TFile::Open( "$ASG_TEST_FILE_MC",
                                                  "READ" ) );
    if( ( ! infile ) || infile->IsZombie() ) {
-      Error( APP_NAME,
-             XAOD_MESSAGE( "Couldn't open the ASG_TEST_FILE_MC file" ) );
+      ATH_MSG_ERROR( "Couldn't open the ASG_TEST_FILE_MC file" );
       return 1;
    }
 
@@ -55,23 +56,27 @@ int main() {
    RETURN_CHECK( APP_NAME, event.readFrom( infile.get() ) );
 
    // Set up the needed tool(s):
-   CP::BaseTrackVertexAssociationTool
-      trktovxtool( "BaseTrackVertexAssociationTool" );
+   CP::TrackVertexAssociationTool
+      trktovxtool( "TrackVertexAssociationTool" );
    RETURN_CHECK( APP_NAME, trktovxtool.setProperty( "OutputLevel",
                                                     MSG::ERROR ) );
-   RETURN_CHECK( APP_NAME, trktovxtool.setProperty( "dzSinTheta_cut", 0.5 ) );
-   RETURN_CHECK( APP_NAME, trktovxtool.setProperty( "d0sig_cut", 5 ) );
+   RETURN_CHECK( APP_NAME, trktovxtool.setProperty( "WorkingPoint", "Nominal" ) );
    RETURN_CHECK( APP_NAME, trktovxtool.initialize() );
 
    // Loop over the file:
    const Long64_t nentries = event.getEntries();
-   Info( APP_NAME, "Total Number of Events: %lld ", nentries );
-   for( Long64_t entry = 0; entry < nentries; ++entry ) {
+   ATH_MSG_INFO( "Total Number of Events: " << nentries );
+   Long64_t maxEntries = nentries;
+   // run only over the first 100 events
+   if(nentries > 100) {
+      maxEntries = 100;
+   }
+   ATH_MSG_INFO( "Running over first " << maxEntries << " events" );
+   for( Long64_t entry = 0; entry < maxEntries; ++entry ) {
 
       // Load the event:
       if( event.getEntry( entry ) < 0 ) {
-         Error( APP_NAME, XAOD_MESSAGE( "Couldn't load entry %lld" ),
-                entry );
+         ATH_MSG_ERROR( "Couldn't load entry " << entry );
          return 1;
       }
 
@@ -84,28 +89,66 @@ int main() {
 
       // A sanity check:
       if( ! vxCont->size() ) {
-         Warning( APP_NAME, "Event with no vertex found!" );
+         ATH_MSG_WARNING( "Event with no vertex found!" );
          continue;
       }
 
-      // Excercise the tool(s):
-      xAOD::TrackVertexAssociationMap trktovxmap =
-         trktovxtool.getUniqueMatchMap( *trkCont, *vxCont );
-      Info( APP_NAME, "Size of TrackVertexAssociationMap for primary vertex: "
-            "%lu", trktovxmap[ vxCont->at( 0 ) ].size() );
+      // Test isCompitable
+      ATH_MSG_INFO("Testing TrackVertexAssociationTool::isCompatible...");
+      if(trkCont->size()!=0 && vxCont->size()!=0)
+      {
+        bool isMatched = trktovxtool.isCompatible(*(trkCont->at(0)), *(vxCont->at(0)));
+        ATH_MSG_INFO("Is the first track compatible with the first vertex (the PriVx)? "<< isMatched);
+      }
 
-      ElementLink< xAOD::VertexContainer > match_vx;
-      if( trkCont->size() > 2 ) {
-         match_vx = trktovxtool.getUniqueMatchVertexLink( *( trkCont->at( 2 ) ),
-                                                          *vxCont );
+      // Test getMatchMap
+      ATH_MSG_INFO("Testing TrackVertexAssociationTool::getMatchMap...");
+      xAOD::TrackVertexAssociationMap trkvxassoMap = trktovxtool.getMatchMap(*trkCont, *vxCont);
+      ATH_MSG_INFO("Number of vertices for track-vertex association: " << trkvxassoMap.size());
+      for (const auto& assoc: trkvxassoMap) {
+        const xAOD::Vertex *vx = assoc.first;
+        ATH_MSG_INFO("vertex at x, y, z   " << vx->x() << ", " << vx->y() << ", " << vx->z() <<
+                     "   has " << assoc.second.size() << " associated tracks");
       }
-      if( match_vx.isValid() ) {
-         Info( APP_NAME, "Vertex assigned to the 3rd track particle:" );
-         std::cout << match_vx << std::endl;
-         std::cout << *match_vx << std::endl;
-         std::cout << ( *match_vx )->z() << std::endl;
+      // Test getUniqueMatchVertex
+      ATH_MSG_INFO("Testing TrackVertexAssociationTool::getUniqueMatchVertex...");
+      std::vector<const xAOD::Vertex* > v_vx;
+      v_vx.clear();
+      for(auto *vertex : *vxCont) {
+        v_vx.push_back(vertex);
       }
-   }
+      if(trkCont->size()!=0)
+      {
+        const xAOD::Vertex *vx = trktovxtool.getUniqueMatchVertex(*(trkCont->at(0)), v_vx);
+        ATH_MSG_INFO("Unique match vertex for first track: " << vx);
+      }
+
+      // Test getUniqueMatchVertexLink
+      ATH_MSG_INFO("Testing TrackVertexAssociationTool::getUniqueMatchVertexLink...");
+      if(trkCont->size() > 2)
+      {
+        ElementLink<xAOD::VertexContainer> match_vx = trktovxtool.getUniqueMatchVertexLink(*(trkCont->at(2)), *vxCont );
+
+        if(match_vx.isValid())
+        {
+          ATH_MSG_INFO( "Uniquely matched vertex for third track - ");
+          ATH_MSG_INFO( "Vertex ElementLink address: " << match_vx );
+          ATH_MSG_INFO( "Vertex address: " << *match_vx );
+          ATH_MSG_INFO( "Vertex z pos: " << (*match_vx)->z());
+        }
+      }
+
+      // Test getUniqueMatchMap
+      ATH_MSG_INFO("Testing TrackVertexAssociationTool::getUniqueMatchMap...");
+      xAOD::TrackVertexAssociationMap trkvxassoUniqueMap = trktovxtool.getUniqueMatchMap(*trkCont, *vxCont);
+      ATH_MSG_INFO("Number of vertices for track-vertex association: " << trkvxassoUniqueMap.size());
+      for (const auto& assoc: trkvxassoUniqueMap) {
+        const xAOD::Vertex *vx = assoc.first;
+        ATH_MSG_INFO("vertex at x, y, z   " << vx->x() << ", " << vx->y() << ", " << vx->z() <<
+                     "   has " << assoc.second.size() << " uniquely associated tracks");
+      }
+
+   } // end event loop
 
    // Return gracefully:
    return 0;