diff --git a/Alignment/AlignKernel/AlignKernel/AlMat.h b/Alignment/AlignKernel/AlignKernel/AlMat.h
index ad79b6a32d10349444cf772a5d1a5706f57961ca..fe29b9db4de105276d3245d0b3ca1386715ac23b 100644
--- a/Alignment/AlignKernel/AlignKernel/AlMat.h
+++ b/Alignment/AlignKernel/AlignKernel/AlMat.h
@@ -1,5 +1,5 @@
 /*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration      *
 *                                                                             *
 * This software is distributed under the terms of the GNU General Public      *
 * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
@@ -8,131 +8,21 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-#ifndef SOLVKERNEL_ALMAT_H
-#define SOLVKERNEL_ALMAT_H
 
-#include <iomanip>
-#include <iostream>
+#pragma once
 
-class AlVec;
-class AlSymMat;
-
-class AlMat
-
-{
+#pragma GCC diagnostic push
+#if !defined( __clang__ )
+#  pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#endif
+#include <Eigen/Dense>
+#pragma GCC diagnostic pop
 
+/// Basically just a wrapper around the Eigen class, but with zero initialization
+class AlMat : public Eigen::MatrixXd {
 public:
-  AlMat( size_t N, size_t M );
-  AlMat();
-  AlMat( const AlMat& m );
-  ~AlMat();
-
-  class AlMat_row {
-  public:
-    inline AlMat_row( AlMat&, size_t );
-    double& operator[]( size_t );
-
-  private:
-    AlMat& _a;
-    size_t _r;
-  };
-  class AlMat_row_const {
-  public:
-    inline AlMat_row_const( const AlMat&, size_t );
-    const double& operator[]( size_t ) const;
-
-  private:
-    const AlMat& _a;
-    size_t       _r;
-  };
-  // helper class to implement m[i][j]
-
-  inline AlMat_row       operator[]( size_t );
-  inline AlMat_row_const operator[]( size_t ) const;
-  double                 operator()( size_t irow, size_t icol ) const { return ( *this )[irow][icol]; }
-  double&                operator()( size_t irow, size_t icol ) { return ( *this )[irow][icol]; }
-
-  AlMat& operator=( const AlMat& m );
-  AlMat& operator=( const AlSymMat& m );
-  AlMat  operator+( const AlMat& m );
-  AlMat  operator+( const AlMat& m ) const;
-  AlMat& operator+=( const AlMat& m );
-  AlMat  operator-( const AlMat& m );
-  AlMat  operator-( const AlMat& m ) const;
-  AlMat& operator-=( const AlMat& m );
-  AlMat  operator*( const AlMat& m );
-  AlMat  operator*( const AlMat& m ) const;
-  AlMat  operator*( const AlSymMat& m );
-  AlMat  operator*( const AlSymMat& m ) const;
-  AlVec  operator*( const AlVec& v );
-  AlVec  operator*( const AlVec& v ) const;
-  AlMat& operator*=( const double& d );
-
-  // transposed matrix
-  AlMat T() const;
-  //
-  // invert sym matrix declared as non-symetric for convenience
-
-  void invertS( int& ierr, double Norm );
-
-  size_t nrow() const;
-  size_t ncol() const;
-  // reSize method
-  void reSize( size_t Nnew, size_t Mnew );
-  void removeRow( size_t Nr );
-  void removeCol( size_t Nr );
-
-  void copyS( const AlSymMat& m );
-
-  //  void invert(int ierr); // only if Ncol=Nrow !!
-
-private:
-  friend class AlVec;
-  friend class AlSymMat;
-  friend class AlMat_row;
-  friend class AlMat_row_const;
-
-  void copy( const AlMat& m );
-  //  void copyS(const AlSymMat&  m);
-
-  size_t  Ncol, Nrow;
-  size_t  Nele;
-  double* ptr_data;
-
-  //  double* mat_p;
-  // double** mat;
+  using Base = Eigen::MatrixXd;
+  AlMat( Index n, Index m ) : Base( Base::Zero( n, m ) ) {}
+  AlMat( size_t n, size_t m ) : Base( Base::Zero( n, m ) ) {}
+  using Base::Base;
 };
-
-// inline operators
-
-inline AlMat::AlMat_row AlMat::operator[]( size_t r ) {
-  AlMat_row b( *this, r );
-  return b;
-}
-
-inline AlMat::AlMat_row_const AlMat::operator[]( size_t r ) const
-
-{
-  const AlMat_row_const b( *this, r );
-
-  return b;
-}
-
-inline double& AlMat::AlMat_row::operator[]( size_t c ) {
-  if ( _r >= _a.Nrow || c >= _a.Ncol ) std::cerr << "Range error in AlMat::operator[][]" << std::endl;
-
-  return *( _a.ptr_data + _r * _a.Ncol + c );
-}
-
-inline const double& AlMat::AlMat_row_const::operator[]( size_t c ) const {
-
-  if ( _r >= _a.Nrow || c >= _a.Ncol ) std::cerr << "Range error in AlMat::operator[][]" << std::endl;
-
-  return *( _a.ptr_data + _r * _a.Ncol + c );
-}
-
-inline AlMat::AlMat_row::AlMat_row( AlMat& a, size_t r ) : _a( a ), _r( r ) {}
-
-inline AlMat::AlMat_row_const::AlMat_row_const( const AlMat& a, size_t r ) : _a( a ), _r( r ) {}
-
-#endif // SOLVKERNEL_ALMAT_H
diff --git a/Alignment/AlignKernel/AlignKernel/AlSymMat.h b/Alignment/AlignKernel/AlignKernel/AlSymMat.h
index af050b29b75efb717f7c51d9c87524e82aef958b..28560205ed558f4e61bdbd2cd4f99bbcdac0b4ac 100644
--- a/Alignment/AlignKernel/AlignKernel/AlSymMat.h
+++ b/Alignment/AlignKernel/AlignKernel/AlSymMat.h
@@ -8,155 +8,93 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-#ifndef SOLVKERNEL_ALSYMMAT_H
-#define SOLVKERNEL_ALSYMMAT_H
+
+#pragma once
 
 // from STD
 #include <iomanip>
 #include <iostream>
-#include <ostream>
 #include <vector>
 
-class AlVec;
-class AlMat;
+#include "AlignKernel/AlMat.h"
+#include "AlignKernel/AlVec.h"
 
 class AlSymMat {
 
 public:
-  AlSymMat( size_t N );
-  AlSymMat();
-  AlSymMat( const AlSymMat& m );
-  ~AlSymMat();
-
-  class AlSymMat_row {
-  public:
-    inline AlSymMat_row( AlSymMat&, size_t );
-    double& operator[]( size_t );
-
-  private:
-    AlSymMat& _a;
-    size_t    _r;
-  };
-  class AlSymMat_row_const {
-  public:
-    inline AlSymMat_row_const( const AlSymMat&, size_t );
-    const double& operator[]( size_t ) const;
-
-  private:
-    const AlSymMat& _a;
-    size_t          _r;
-  };
-  // helper class to implement m[i][j]
-
-  inline AlSymMat_row       operator[]( size_t );
-  inline AlSymMat_row_const operator[]( size_t ) const;
+  AlSymMat( size_t N ) { reSize( N ); }
+  AlSymMat()                    = default;
+  AlSymMat( const AlSymMat& m ) = default;
+  AlSymMat( AlSymMat&& m )      = default;
+  AlSymMat& operator=( const AlSymMat& m ) = default;
+  AlSymMat& operator=( AlSymMat&& m ) = default;
 
   // access method that requires irow>=icol without checking
-  double  fast( size_t irow, size_t icol ) const { return *( ptr_data + ( irow + 1 ) * irow / 2 + icol ); }
-  double& fast( size_t irow, size_t icol ) { return *( ptr_data + ( irow + 1 ) * irow / 2 + icol ); }
+  double  fast( size_t irow, size_t icol ) const { return m_data[( irow + 1 ) * irow / 2 + icol]; }
+  double& fast( size_t irow, size_t icol ) { return m_data[( irow + 1 ) * irow / 2 + icol]; }
   double operator()( size_t irow, size_t icol ) const { return irow >= icol ? fast( irow, icol ) : fast( icol, irow ); }
   double& operator()( size_t irow, size_t icol ) { return irow >= icol ? fast( irow, icol ) : fast( icol, irow ); }
 
-  AlSymMat& operator=( const AlSymMat& m );
-  AlSymMat  operator+( const AlSymMat& m );
-  AlSymMat  operator+( const AlSymMat& m ) const;
   AlSymMat& operator+=( const AlSymMat& m );
-  AlSymMat  operator-( const AlSymMat& m );
-  AlSymMat  operator-( const AlSymMat& m ) const;
-  AlMat     operator*( const AlSymMat& m );
-  AlMat     operator*( const AlSymMat& m ) const;
-  AlVec     operator*( const AlVec& v );
-  AlVec     operator*( const AlVec& v ) const;
-  AlMat     operator*( const AlMat& m );
-  AlMat     operator*( const AlMat& m ) const;
+  AlSymMat& operator-=( const AlSymMat& m );
   AlSymMat& operator*=( const double& d );
+  AlSymMat  operator-( const AlSymMat& m ) const;
+  AlSymMat  operator+( const AlSymMat& m ) const;
 
   // insert block from SMatrix types
   template <typename T>
   void insert( unsigned col, unsigned row, const T& rhs ) {
     for ( unsigned i = 0; i < T::kCols; ++i )
-      for ( unsigned j = 0; j < T::kRows; ++j ) ( *this )[col + i][row + j] = rhs( i, j );
+      for ( unsigned j = 0; j < T::kRows; ++j ) ( *this )( col + i, row + j ) = rhs( i, j );
   }
 
   // reSize method
-  void   reSize( size_t Nnew );
-  size_t size() const { return Size; }
-  size_t nrow() const { return size(); }
-  size_t ncol() const { return size(); }
-
-  void removeElement( size_t Nr );
-  void ShrinkDofs( std::vector<bool>& mask );
+  void reSize( size_t N ) {
+    m_N = N;
+    m_data.resize( N * ( N + 1 ) / 2, 0.0 );
+  }
+  size_t size() const { return m_N; }
+  size_t rows() const { return m_N; }
+  size_t cols() const { return m_N; }
 
-  void   invert( int& ierr );
-  double determinant();
-  int    diagonalize( char jobz, AlVec& w, AlMat& z );
-  void   diagonalize_GSL( AlVec& egval, AlMat& egvec );
+  int          diagonalize_GSL( AlVec& egval, AlMat& egvec ) const;
+  double       determinant() const;
+  inline AlMat toMatrix() const;
+  // explicit operator AlMat() const { return toMatrix() ; }
 
 private:
-  friend class AlVec;
-  friend class AlMat;
-  friend class AlSymMat_row;
-  friend class AlSymMat_row_const;
-
-  void    copy( const AlSymMat& m );
-  double* ptr_data;
-  size_t  Size;
-  size_t  Nele;
+  std::vector<double> m_data;
+  size_t              m_N{0};
 };
 
 // inline operators
 inline std::ostream& operator<<( std::ostream& lhs, const AlSymMat& rhs ) {
   lhs << "[ ";
   for ( size_t i = 0u; i < rhs.size(); ++i ) {
-    for ( size_t j = 0u; j < rhs.size(); ++j ) { lhs << " " << rhs[i][j] << " "; }
+    for ( size_t j = 0u; j < rhs.size(); ++j ) { lhs << " " << rhs( i, j ) << " "; }
     lhs << std::endl;
   }
   lhs << " ]" << std::endl;
   return lhs;
 }
 
-inline AlSymMat::AlSymMat_row AlSymMat::operator[]( size_t r ) {
-  AlSymMat_row b( *this, r );
-  return b;
-}
-
-inline AlSymMat::AlSymMat_row_const AlSymMat::operator[]( size_t r ) const
-
-{
-  const AlSymMat_row_const b( *this, r );
-
-  return b;
-}
-
-inline double& AlSymMat::AlSymMat_row::operator[]( size_t c ) {
-  if ( _r >= _a.Size || c >= _a.Size ) std::cerr << "Range error in AlSymMat::operator[][]" << std::endl;
-
-  if ( _r >= c ) {
-    return *( _a.ptr_data + ( _r + 1 ) * _r / 2 + c );
-  } else {
-    return *( _a.ptr_data + ( c + 1 ) * c / 2 + _r );
-  }
+inline AlMat AlSymMat::toMatrix() const {
+  const auto&                                           matrix = *this;
+  const auto                                            N      = m_N;
+  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> rc{N, N};
+  for ( size_t irow = 0; irow < N; ++irow )
+    for ( size_t icol = 0; icol <= irow; ++icol ) rc( irow, icol ) = rc( icol, irow ) = matrix.fast( irow, icol );
+  return rc;
 }
 
-inline const double& AlSymMat::AlSymMat_row_const::operator[]( size_t c ) const {
+inline AlMat operator*( const AlSymMat& lhs, const AlSymMat& rhs ) { return lhs.toMatrix() * rhs.toMatrix(); }
 
-  if ( _r >= _a.Size || c >= _a.Size ) std::cerr << "Range error in AlSymMat::operator[][]" << std::endl;
+inline AlMat operator*( const AlMat& lhs, const AlSymMat& rhs ) { return lhs * rhs.toMatrix(); }
 
-  if ( _r >= c ) {
-    return *( _a.ptr_data + ( _r + 1 ) * _r / 2 + c );
-  } else {
-    return *( _a.ptr_data + ( c + 1 ) * c / 2 + _r );
-  }
-}
-
-inline AlSymMat::AlSymMat_row::AlSymMat_row( AlSymMat& a, size_t r ) : _a( a ), _r( r ) {}
-
-inline AlSymMat::AlSymMat_row_const::AlSymMat_row_const( const AlSymMat& a, size_t r ) : _a( a ), _r( r ) {}
+inline AlMat operator*( const AlSymMat& lhs, const AlMat& rhs ) { return lhs.toMatrix() * rhs; }
 
 inline AlSymMat operator*( double d, const AlSymMat& m ) {
   AlSymMat rc = m;
   rc *= d;
   return rc;
 }
-
-#endif // SOLVKERNEL_ALSYMMAT_H
diff --git a/Alignment/AlignKernel/AlignKernel/AlVec.h b/Alignment/AlignKernel/AlignKernel/AlVec.h
index 2a15ae601e5a88beacce415d1780f90e83e1c1ca..a87a912e638e08930793f7dea104c21aa687e022 100644
--- a/Alignment/AlignKernel/AlignKernel/AlVec.h
+++ b/Alignment/AlignKernel/AlignKernel/AlVec.h
@@ -1,5 +1,5 @@
 /*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration      *
 *                                                                             *
 * This software is distributed under the terms of the GNU General Public      *
 * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
@@ -8,78 +8,21 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-#ifndef SOLVKERNEL_ALVEC_H
-#define SOLVKERNEL_ALVEC_H
 
-// from STD
-#include <iostream>
-#include <ostream>
-#include <vector>
+#pragma once
 
-class AlSymMat;
-class AlMat;
-
-class AlVec {
+#pragma GCC diagnostic push
+#if !defined( __clang__ )
+#  pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#endif
+#include <Eigen/Dense>
+#pragma GCC diagnostic pop
 
+/// Basically just a wrapper around the Eigen class, but with zero initialization
+class AlVec : public Eigen::VectorXd {
 public:
-  AlVec( size_t N );
-  AlVec();
-  AlVec( const AlVec& v );
-  ~AlVec();
-
-  double&       operator[]( size_t i );
-  const double& operator[]( size_t i ) const;
-  double&       operator()( size_t i ) { return *( ptr_data + i ); }
-  const double& operator()( size_t i ) const { return *( ptr_data + i ); }
-
-  AlVec& operator=( const AlVec& v );
-  //  AlVec& operator=(const double& v);
-  AlVec  operator+( const AlVec& v );
-  AlVec  operator+( const AlVec& v ) const;
-  AlVec& operator+=( const AlVec& v );
-  AlVec  operator-( const AlVec& v );
-  AlVec  operator-( const AlVec& v ) const;
-  AlVec& operator-=( const AlVec& v );
-  double operator*( const AlVec& v );
-  double operator*( const AlVec& v ) const;
-  AlVec  operator*( const AlMat& m );
-  AlVec  operator*( const AlMat& m ) const;
-  AlVec  operator*( const AlSymMat& m );
-  AlVec  operator*( const AlSymMat& m ) const;
-  AlVec  operator*( const double& d );
-  AlVec  operator*( const double& d ) const;
-  AlVec& operator*=( const double& d );
-
-  // insert block from SMatrix types
-  template <typename T>
-  void insert( unsigned row, const T& rhs ) {
-    for ( unsigned i = 0; i < T::kSize; ++i ) ( *this )[row + i] = rhs( i );
-  }
-
-  void   reSize( size_t Nnew );
-  void   removeElement( size_t Nr );
-  void   ShrinkDofs( std::vector<bool>& mask );
-  size_t size() const { return Nele; }
-
-private:
-  friend class AlSymMat;
-  friend class AlMat;
-
-  size_t  Nele;
-  double* ptr_data;
+  using Base = Eigen::VectorXd;
+  AlVec( Index n ) : Base( Base::Zero( n ) ) {}
+  AlVec( size_t n ) : Base( Base::Zero( n ) ) {}
+  using Base::Base;
 };
-
-inline std::ostream& operator<<( std::ostream& lhs, const AlVec& rhs ) {
-  lhs << "[ ";
-  for ( size_t i = 0u; i < rhs.size(); ++i ) lhs << " " << rhs[i] << " ";
-  lhs << " ]" << std::endl;
-  return lhs;
-}
-
-inline AlVec operator*( double d, const AlVec& vec ) {
-  AlVec rc = vec;
-  rc *= d;
-  return rc;
-}
-
-#endif // SOLVKERNEL_ALVEC_H
diff --git a/Alignment/AlignKernel/CMakeLists.txt b/Alignment/AlignKernel/CMakeLists.txt
index d5c21e4b1f7b2beef0ab888012ee3bd6376eedb4..2a5ba3621e1ff79fe76c8a8df8d24549b14cd4d7 100644
--- a/Alignment/AlignKernel/CMakeLists.txt
+++ b/Alignment/AlignKernel/CMakeLists.txt
@@ -14,42 +14,22 @@ gaudi_depends_on_subdirs(GaudiAlg
                          GaudiGSL
                          GaudiKernel)
 
-# helper function used as fall-back solution to find BLAS/LAPACK
-macro(simple_find_lib _name)
-  find_library(${_name}_LIB ${_name})
-  if(${_name}_LIB)
-    message(STATUS "Found ${_name}: ${${_name}_LIB}")
-    set(${_name}_LIBRARIES ${${_name}_LIB})
-    set(${_name}_FOUND True CACHE INTERNAL "${_name} library found")
-  else()
-    message(FATAL_ERROR "Cannot find ${_name}")
-  endif()
-endmacro()
-
 find_package(ROOT)
 find_package(GSL)
 
 include_directories(SYSTEM ${ROOT_INCLUDE_DIRS})
 
-# Try regular LAPACK finder
-find_package(LAPACK QUIET)
-
-# Fall-back solution for HEPTools versions of LAPACK and BLAS
-if(NOT LAPACK_FOUND)
-  simple_find_lib(BLAS)
-  simple_find_lib(LAPACK)
-  set(LAPACK_LIBRARIES ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})
-endif()
-
+find_package(Eigen) 
+include_directories(SYSTEM ${EIGEN_INCLUDE_DIRS}) 
 
 gaudi_add_library(AlignKernel
                   src/*.cpp
                   PUBLIC_HEADERS AlignKernel
-                  INCLUDE_DIRS GSL
-                  LINK_LIBRARIES GSL LAPACK gfortran GaudiAlgLib GaudiGSLLib GaudiKernel)
+                  INCLUDE_DIRS GSL Eigen
+                  LINK_LIBRARIES GSL Eigen GaudiAlgLib GaudiGSLLib GaudiKernel)
 
 gaudi_add_dictionary(AlignKernel
                      dict/AlignKernelDict.h
                      dict/AlignKernelDict.xml
-                     INCLUDE_DIRS GSL
-                     LINK_LIBRARIES GSL GaudiAlgLib GaudiGSLLib GaudiKernel AlignKernel)
+                     INCLUDE_DIRS GSL Eigen
+                     LINK_LIBRARIES GSL Eigen GaudiAlgLib GaudiGSLLib GaudiKernel AlignKernel)
diff --git a/Alignment/AlignKernel/src/AlMat.cpp b/Alignment/AlignKernel/src/AlMat.cpp
deleted file mode 100644
index 70c554f0ea01d1e650a551aa3d47ba797dc106d7..0000000000000000000000000000000000000000
--- a/Alignment/AlignKernel/src/AlMat.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#include "AlignKernel/AlMat.h"
-#include "AlignKernel/AlSymMat.h"
-#include "AlignKernel/AlVec.h"
-#include <iomanip>
-#include <iostream>
-
-AlMat::AlMat() {
-
-  Ncol     = 0;
-  Nrow     = 0;
-  Nele     = 0;
-  ptr_data = 0; // set pointer to null
-}
-
-AlMat::AlMat( size_t N, size_t M ) {
-
-  Nrow     = N;
-  Ncol     = M;
-  Nele     = N * M;
-  ptr_data = new double[Nele];
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { *( ptr_data + i * Ncol + j ) = 0.; }
-  }
-}
-
-AlMat::AlMat( const AlMat& m ) {
-  Nrow     = m.Nrow;
-  Ncol     = m.Ncol;
-  Nele     = Nrow * Ncol;
-  ptr_data = new double[Nele];
-  copy( m );
-}
-
-AlMat::~AlMat() { delete[] ptr_data; }
-
-void AlMat::copy( const AlMat& m ) {
-
-  size_t n = Nrow <= m.Nrow ? Nrow : m.Nrow;
-  size_t l = Ncol <= m.Ncol ? Ncol : m.Ncol;
-
-  for ( size_t i = 0; i < n; i++ ) {
-    for ( size_t j = 0; j < l; j++ ) { *( ptr_data + i * Ncol + j ) = *( m.ptr_data + i * m.Ncol + j ); }
-  }
-}
-
-void AlMat::copyS( const AlSymMat& m ) {
-
-  size_t n = Nrow <= m.Size ? Nrow : m.Size;
-  size_t l = Ncol <= m.Size ? Ncol : m.Size;
-
-  for ( size_t i = 0; i < n; i++ ) {
-    for ( size_t j = 0; j < l; j++ ) {
-
-      if ( j <= i ) {
-        *( ptr_data + i * Ncol + j ) = *( m.ptr_data + ( i + 1 ) * i / 2 + j );
-      } else {
-        *( ptr_data + i * Ncol + j ) = *( m.ptr_data + ( j + 1 ) * j / 2 + i );
-      }
-    }
-  }
-}
-
-AlMat& AlMat::operator=( const AlMat& m ) {
-
-  if ( ( Nrow != 0 || Ncol != 0 ) && ( Nrow != m.Nrow || Ncol != m.Ncol ) ) {
-    std::cerr << "AlMat AlMat Assignment: size do not match!" << std::endl;
-    return *this;
-  }
-
-  if ( ptr_data != m.ptr_data ) {
-    reSize( m.Nrow, m.Ncol );
-    copy( m );
-  };
-  return ( *this );
-}
-
-AlMat& AlMat::operator=( const AlSymMat& m ) {
-
-  if ( ( Nrow != 0 || Ncol != 0 ) && ( Nrow != m.Size || Ncol != m.Size ) ) {
-    std::cerr << "AlMat AlSymMat Assignment: size do not match!" << std::endl;
-    return *this;
-  }
-
-  if ( ptr_data != m.ptr_data ) {
-    reSize( m.Size, m.Size );
-    copyS( m );
-  }
-  return ( *this );
-}
-
-AlMat AlMat::operator+( const AlMat& m ) {
-
-  if ( Nrow != m.Nrow || Ncol != m.Ncol ) {
-    std::cerr << "operator+: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlMat b( Nrow, Ncol );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { *( b.ptr_data + i * b.Ncol + j ) = *( ptr_data + i * Ncol + j ) + m[i][j]; }
-  }
-
-  return b;
-}
-
-AlMat AlMat::operator+( const AlMat& m ) const {
-
-  if ( Nrow != m.Nrow || Ncol != m.Ncol ) {
-    std::cerr << "operator+: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlMat b( Nrow, Ncol );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { *( b.ptr_data + i * b.Ncol + j ) = *( ptr_data + i * Ncol + j ) + m[i][j]; }
-  }
-
-  return b;
-}
-
-AlMat& AlMat::operator+=( const AlMat& m ) {
-
-  if ( Nrow != m.Nrow || Ncol != m.Ncol ) {
-    std::cerr << "operator+=: size do not match!" << std::endl;
-    return *this;
-  }
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { *( ptr_data + i * Ncol + j ) += *( m.ptr_data + i * m.Ncol + j ); };
-  };
-
-  return *this;
-}
-
-AlMat AlMat::operator-( const AlMat& m ) {
-  if ( Nrow != m.Nrow || Ncol != m.Ncol ) {
-    std::cerr << "operator-: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlMat b( Nrow, Ncol );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { *( b.ptr_data + i * b.Ncol + j ) = *( ptr_data + i * Ncol + j ) - m[i][j]; }
-  }
-
-  return b;
-}
-
-AlMat AlMat::operator-( const AlMat& m ) const {
-  if ( Nrow != m.Nrow || Ncol != m.Ncol ) {
-    std::cerr << "operator-: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlMat b( Nrow, Ncol );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { *( b.ptr_data + i * b.Ncol + j ) = *( ptr_data + i * Ncol + j ) - m[i][j]; }
-  }
-
-  return b;
-}
-
-AlMat& AlMat::operator-=( const AlMat& m ) {
-
-  if ( Nrow != m.Nrow || Ncol != m.Ncol ) {
-    std::cerr << "operator-=: size do not match!" << std::endl;
-    return *this;
-  }
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { *( ptr_data + i * Ncol + j ) -= *( m.ptr_data + i * m.Ncol + j ); };
-  };
-
-  return *this;
-}
-
-AlMat AlMat::operator*( const AlMat& m ) {
-
-  if ( Ncol != m.Nrow ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-    return m;
-  }
-
-  AlMat b( Nrow, m.Ncol );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < m.Ncol; j++ ) {
-      for ( size_t k = 0; k < m.Nrow; k++ ) b[i][j] += *( ptr_data + i * Ncol + k ) * ( m[k][j] );
-    }
-  }
-
-  return b;
-}
-
-AlMat AlMat::operator*( const AlMat& m ) const {
-
-  if ( Ncol != m.Nrow ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-    return m;
-  }
-
-  AlMat b( Nrow, m.Ncol );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < m.Ncol; j++ ) {
-      for ( size_t k = 0; k < m.Nrow; k++ ) b[i][j] += *( ptr_data + i * Ncol + k ) * ( m[k][j] );
-    }
-  }
-
-  return b;
-}
-
-AlMat AlMat::operator*( const AlSymMat& m ) {
-  if ( Ncol != m.Size ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlMat b( Nrow, m.Size );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < m.Size; j++ ) {
-      for ( size_t k = 0; k < m.Size; k++ ) *( b.ptr_data + i * b.Ncol + j ) += *( ptr_data + i * Ncol + k ) * m[k][j];
-    }
-  }
-  return b;
-}
-
-AlMat AlMat::operator*( const AlSymMat& m ) const {
-  if ( Ncol != m.Size ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlMat b( Nrow, m.Size );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = 0; j < m.Size; j++ ) {
-      for ( size_t k = 0; k < m.Size; k++ ) *( b.ptr_data + i * b.Ncol + j ) += *( ptr_data + i * Ncol + k ) * m[k][j];
-    }
-  }
-  return b;
-}
-
-AlVec AlMat::operator*( const AlVec& v ) {
-
-  if ( Ncol != v.Nele ) {
-    std::cerr << "operator*: size do not match! " << std::endl;
-    return v;
-  }
-
-  AlVec b( Nrow );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-
-    for ( size_t j = 0; j < Ncol; j++ ) b[i] += ( *( ptr_data + i * Ncol + j ) ) * ( v[j] );
-  }
-
-  return b;
-}
-
-AlVec AlMat::operator*( const AlVec& v ) const {
-
-  if ( Ncol != v.Nele ) {
-    std::cerr << "operator*: size do not match! " << std::endl;
-    return v;
-  }
-
-  AlVec b( Nrow );
-
-  for ( size_t i = 0; i < Nrow; i++ ) {
-
-    for ( size_t j = 0; j < Ncol; j++ ) b[i] += ( *( ptr_data + i * Ncol + j ) ) * ( v[j] );
-  }
-
-  return b;
-}
-
-AlMat& AlMat::operator*=( const double& d ) {
-
-  double* p = ptr_data + Nele;
-
-  while ( p > ptr_data ) *( --p ) *= d;
-
-  return *this;
-}
-
-// transposition
-
-AlMat AlMat::T() const {
-  AlMat b( Ncol, Nrow );
-  for ( size_t i = 0; i < b.Nrow; i++ ) {
-    for ( size_t j = 0; j < b.Ncol; j++ ) { b[i][j] = *( ptr_data + j * Ncol + i ); }
-  }
-  return b;
-}
-
-// invert sym matrix declared as non-symetric for convenience
-
-void AlMat::invertS( int& ierr, double Norm = 1. ) {
-
-  if ( Nrow != Ncol ) {
-    std::cerr << "AlMat invertS: non-square matrix!" << std::endl;
-    return;
-  }
-
-  AlSymMat b( Nrow );
-  //  double minelem=99999999.;
-  // double maxelem=0.;
-
-  for ( size_t i = 0; i < b.Size; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) {
-
-      b[i][j] = ( *this )[i][j];
-      //   if (fabs(b[i][j])<fabs(minelem)) minelem=b[i][j];
-      //  if (fabs(b[i][j])>fabs(maxelem)) maxelem=b[i][j];
-    }
-  }
-
-  // proceed to regularization before and after inversion, if needed
-
-  //  std::cout<<" >>>>> MAXELEM: "<<maxelem<<std::endl;
-  //    Norm = 1./maxelem;
-  //  std::cout<<" >>>>> NORM: "<<Norm<<std::endl;
-  /*   if ((log(fabs(maxelem)))<0.) {
-     size_t factor = size_t(log(fabs(maxelem)))-1;
-     Norm=1./1e(factor);
-     }*/
-  b *= Norm;
-
-  b.invert( ierr );
-  b *= Norm;
-
-  if ( ierr == 0 ) ( *this ).copyS( b );
-}
-
-// reSize
-
-void AlMat::reSize( size_t Nnew, size_t Mnew ) {
-
-  if ( Nnew != Nrow || Mnew != Ncol ) {
-
-    double* p       = ptr_data;
-    Nele            = Nnew * Mnew;
-    ptr_data        = new double[Nele];
-    size_t Nrow_old = Nrow;
-    size_t Ncol_old = Ncol;
-
-    Nrow     = Nnew;
-    Ncol     = Mnew;
-    size_t k = Nrow <= Nrow_old ? Nrow : Nrow_old;
-    size_t l = Ncol <= Ncol_old ? Ncol : Ncol_old;
-
-    for ( size_t i = 0; i < k; i++ ) {
-      for ( size_t j = 0; j < l; j++ ) { *( ptr_data + i * Ncol + j ) = *( p + i * Ncol_old + j ); }
-    }
-
-    delete[] p;
-  }
-}
-
-void AlMat::removeRow( size_t Nr ) {
-
-  // reorganize matrix by filling holes, etc...
-  for ( size_t i = Nr; i < Nrow - 1; i++ ) {
-    for ( size_t j = 0; j < Ncol; j++ ) { ( *this )[i][j] = ( *this )[i + 1][j]; }
-  }
-  // delete obsolete space and shrink matrix row size by one unit
-  size_t max = Nrow - 1;
-  for ( size_t col = 0; col < Ncol; col++ ) delete ( ptr_data + max * Ncol + col );
-
-  Nrow--;
-}
-
-void AlMat::removeCol( size_t Nr ) {
-
-  // reorganize matrix by filling holes, etc...
-  for ( size_t i = 0; i < Nrow; i++ ) {
-    for ( size_t j = Nr; j < Ncol - 1; j++ ) { ( *this )[i][j] = ( *this )[i][j + 1]; }
-  }
-  // delete obsolete space and shrink matrix column size by one unit
-  size_t max = Ncol - 1;
-  for ( size_t row = 0; row < Nrow; row++ ) delete ( ptr_data + row * Ncol + max );
-
-  Ncol--;
-}
-
-size_t AlMat::nrow() const { return Nrow; }
-
-size_t AlMat::ncol() const { return Ncol; }
diff --git a/Alignment/AlignKernel/src/AlSymMat.cpp b/Alignment/AlignKernel/src/AlSymMat.cpp
index 6abfa51b06a8c969d723f254a63e4f1d43d1a3de..8e60c2393999c438a688038425dc5b9e63ace918 100644
--- a/Alignment/AlignKernel/src/AlSymMat.cpp
+++ b/Alignment/AlignKernel/src/AlSymMat.cpp
@@ -11,389 +11,69 @@
 #include "gsl/gsl_eigen.h"
 #include "gsl/gsl_math.h"
 #include "gsl/gsl_matrix.h"
-#include <float.h> //for DBL_EPSILON
-#include <iomanip>
-#include <iostream>
-#include <math.h>
-#include <string.h>
-//#include <Nag/nag.h>
-//#include <Nag/nagf03.h>
-#include "AlignKernel/AlMat.h"
-#include "AlignKernel/AlSymMat.h"
-#include "AlignKernel/AlVec.h"
-
-extern "C" {
-void dsptrf_( char*, const int*, double*, int*, int* );
-void dsptri_( char*, const int*, double*, int*, double*, int* );
-void dspev_( char*, char*, const int*, double*, double*, double*, const int*, double*, int* );
-}
-
-AlSymMat::AlSymMat() {
-  Size     = 0;
-  Nele     = 0;
-  ptr_data = 0; // set pointer to null
-}
-
-AlSymMat::AlSymMat( size_t N ) {
-
-  Size     = N;
-  Nele     = N * ( N + 1 ) / 2;
-  ptr_data = new double[Nele];
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) { *( ptr_data + ( i + 1 ) * i / 2 + j ) = 0.; }
-  }
-}
-
-AlSymMat::AlSymMat( const AlSymMat& m ) {
 
-  Size     = m.Size;
-  Nele     = m.Nele;
-  ptr_data = new double[Nele];
-  copy( m );
-}
-
-AlSymMat::~AlSymMat() { delete[] ptr_data; }
-
-void AlSymMat::copy( const AlSymMat& m ) {
-
-  size_t n = Size <= m.Size ? Size : m.Size;
-
-  for ( size_t i = 0; i < n; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) { *( ptr_data + ( i + 1 ) * i / 2 + j ) = m[i][j]; }
-  }
-}
-
-AlSymMat& AlSymMat::operator=( const AlSymMat& m ) {
-  if ( size() != m.size() ) {
-    delete[] ptr_data;
-    Nele     = m.Nele;
-    Size     = m.Size;
-    ptr_data = new double[Nele];
-  }
-  memcpy( ptr_data, m.ptr_data, Nele * sizeof( double ) );
-  return *this;
-}
-
-AlSymMat AlSymMat::operator+( const AlSymMat& m ) {
-
-  if ( Size != m.Size ) {
-    std::cerr << "operator+: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlSymMat b( Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) { b[i][j] = *( ptr_data + ( i + 1 ) * i / 2 + j ) + m[i][j]; }
-  }
-
-  return b;
-}
-
-AlSymMat AlSymMat::operator+( const AlSymMat& m ) const {
-
-  if ( Size != m.Size ) {
-    std::cerr << "operator+: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlSymMat b( Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) { b[i][j] = *( ptr_data + ( i + 1 ) * i / 2 + j ) + m[i][j]; }
-  }
+#include "AlignKernel/AlSymMat.h"
 
+AlSymMat AlSymMat::operator+( const AlSymMat& rhs ) const {
+  auto b = *this;
+  b += rhs;
   return b;
 }
 
-AlSymMat& AlSymMat::operator+=( const AlSymMat& m ) {
+AlSymMat& AlSymMat::operator+=( const AlSymMat& rhs ) {
 
-  if ( Size != m.Size ) {
+  if ( size() != rhs.size() ) {
     std::cerr << "operator+=: size do not match!" << std::endl;
     return *this;
   }
 
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) { *( ptr_data + ( i + 1 ) * i / 2 + j ) += m[i][j]; };
-  };
-
+  for ( size_t i = 0; i < m_data.size(); ++i ) m_data[i] += rhs.m_data[i];
   return *this;
 }
 
-AlSymMat AlSymMat::operator-( const AlSymMat& m ) {
-
-  if ( Size != m.Size ) {
-    std::cerr << "operator-: size do not match!" << std::endl;
-    return *this;
-  }
-
-  AlSymMat b( Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) { b[i][j] = *( ptr_data + ( i + 1 ) * i / 2 + j ) - m[i][j]; }
-  }
-
+AlSymMat AlSymMat::operator-( const AlSymMat& rhs ) const {
+  auto b = *this;
+  b -= rhs;
   return b;
 }
 
-AlSymMat AlSymMat::operator-( const AlSymMat& m ) const {
+AlSymMat& AlSymMat::operator-=( const AlSymMat& rhs ) {
 
-  if ( Size != m.Size ) {
-    std::cerr << "operator-: size do not match!" << std::endl;
+  if ( size() != rhs.size() ) {
+    std::cerr << "operator+=: size do not match!" << std::endl;
     return *this;
   }
 
-  AlSymMat b( Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) { b[i][j] = *( ptr_data + ( i + 1 ) * i / 2 + j ) - m[i][j]; }
-  }
-
-  return b;
-}
-
-AlMat AlSymMat::operator*( const AlSymMat& m ) {
-
-  if ( Size != m.Size ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-
-    AlMat b( Size, m.Size );
-
-    return b;
-  }
-
-  AlMat b( Size, Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j < Size; j++ ) {
-      for ( size_t k = 0; k < Size; k++ ) {
-        if ( k <= i ) b[i][j] += *( ptr_data + ( i + 1 ) * i / 2 + k ) * ( m[k][j] );
-        if ( k > i ) b[i][j] += *( ptr_data + ( k + 1 ) * k / 2 + i ) * ( m[k][j] );
-      }
-    }
-  }
-
-  return b;
-}
-
-AlMat AlSymMat::operator*( const AlSymMat& m ) const {
-
-  if ( Size != m.Size ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-
-    AlMat b( Size, m.Size );
-
-    return b;
-  }
-
-  AlMat b( Size, Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j < Size; j++ ) {
-      for ( size_t k = 0; k < Size; k++ ) {
-        if ( k <= i ) b[i][j] += *( ptr_data + ( i + 1 ) * i / 2 + k ) * ( m[k][j] );
-        if ( k > i ) b[i][j] += *( ptr_data + ( k + 1 ) * k / 2 + i ) * ( m[k][j] );
-      }
-    }
-  }
-
-  return b;
-}
-
-AlMat AlSymMat::operator*( const AlMat& m ) {
-
-  if ( Size != m.Nrow ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-    return m;
-  }
-
-  AlMat b( Size, m.Ncol );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j < m.Ncol; j++ ) {
-      for ( size_t k = 0; k < Size; k++ ) {
-        if ( k <= i ) b[i][j] += *( ptr_data + ( i + 1 ) * i / 2 + k ) * ( m[k][j] );
-        if ( k > i ) b[i][j] += *( ptr_data + ( k + 1 ) * k / 2 + i ) * ( m[k][j] );
-      }
-    }
-  }
-
-  return b;
-}
-
-AlMat AlSymMat::operator*( const AlMat& m ) const {
-
-  if ( Size != m.Nrow ) {
-    std::cerr << "operator*: size do not match!" << std::endl;
-    return m;
-  }
-
-  AlMat b( Size, m.Ncol );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j < m.Ncol; j++ ) {
-      for ( size_t k = 0; k < Size; k++ ) {
-        if ( k <= i ) b[i][j] += *( ptr_data + ( i + 1 ) * i / 2 + k ) * ( m[k][j] );
-        if ( k > i ) b[i][j] += *( ptr_data + ( k + 1 ) * k / 2 + i ) * ( m[k][j] );
-      }
-    }
-  }
-
-  return b;
-}
-
-AlVec AlSymMat::operator*( const AlVec& v ) {
-
-  if ( Size != v.Nele ) {
-    std::cerr << "operator*: size do not match! " << std::endl;
-    return v;
-  }
-
-  AlVec b( Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j < Size; j++ ) {
-      if ( j <= i ) b[i] += *( ptr_data + ( i + 1 ) * i / 2 + j ) * v[j];
-      if ( j > i ) b[i] += *( ptr_data + ( j + 1 ) * j / 2 + i ) * v[j];
-    }
-  }
-
-  return b;
-}
-
-AlVec AlSymMat::operator*( const AlVec& v ) const {
-
-  if ( Size != v.Nele ) {
-    std::cerr << "operator*: size do not match! " << std::endl;
-    return v;
-  }
-
-  AlVec b( Size );
-
-  for ( size_t i = 0; i < Size; i++ ) {
-    for ( size_t j = 0; j < Size; j++ ) {
-      if ( j <= i ) b[i] += *( ptr_data + ( i + 1 ) * i / 2 + j ) * v[j];
-      if ( j > i ) b[i] += *( ptr_data + ( j + 1 ) * j / 2 + i ) * v[j];
-    }
-  }
-
-  return b;
+  for ( size_t i = 0; i < m_data.size(); ++i ) m_data[i] -= rhs.m_data[i];
+  return *this;
 }
 
 AlSymMat& AlSymMat::operator*=( const double& d ) {
-
-  double* p = ptr_data + Nele;
-
-  while ( p > ptr_data ) *( --p ) *= d;
-
+  for ( auto& e : m_data ) e *= d;
   return *this;
 }
 
-void AlSymMat::reSize( size_t Nnew ) {
-
-  if ( Nnew != Size && Size != 0 ) {
-
-    double* p       = ptr_data;
-    Nele            = Nnew * ( Nnew + 1 ) / 2;
-    ptr_data        = new double[Nele];
-    size_t Size_old = Size;
-    Size            = Nnew;
-    size_t k        = Size <= Size_old ? Size : Size_old;
-    for ( size_t i = 0; i < k; i++ ) {
-      for ( size_t j = 0; j <= i; j++ ) { *( ptr_data + ( i + 1 ) * i / 2 + j ) = *( p + ( i + 1 ) * i / 2 + j ); }
-    }
-
-    delete[] p;
-  }
-
-  if ( Size == 0 ) *this = AlSymMat( Nnew );
-}
-
-void AlSymMat::removeElement( size_t Nr ) {
-
-  // reorganize matrix by filling holes, etc...
-  for ( size_t i = Nr; i < Size - 1; i++ ) {
-    for ( size_t j = 0; j <= i; j++ ) {
-      if ( j < Nr )
-        ( *this )[i][j] = ( *this )[i + 1][j];
-      else
-        ( *this )[i][j] = ( *this )[i + 1][j + 1];
-    }
-  }
-  // delete obsolete space and shrink matrix size by one unit
-  size_t max = Size - 1;
-  for ( size_t col = 0; col < Size; col++ ) delete ( ptr_data + ( max + 1 ) * max / 2 + col );
-  Size--;
-}
-
-void AlSymMat::ShrinkDofs( std::vector<bool>& mask ) {
-
-  if ( mask.size() != Size ) {
-    std::cerr << "Beware, mask size different from matrix size, skip..." << std::endl;
-    return;
-  }
-
-  size_t offset = 0;
-
-  for ( size_t iR = 0; iR < mask.size(); iR++ ) {
-    if ( !mask[iR] ) {
-      removeElement( iR - offset );
-      offset++;
-    }
-  }
-}
-
-void AlSymMat::invert( int& ierr ) {
-
-  // add a protection to detect singular matrices:
-
-  double det    = ( *this ).determinant();
-  double detcut = 1.E-20;
-
-  if ( fabs( det ) > detcut ) {
-
-    char    uplo = 'U';
-    int     N    = Size;
-    int*    ipiv = new int[N];
-    double* work = new double[N];
-    double* mx   = ptr_data;
-
-    dsptrf_( &uplo, &N, mx, ipiv, &ierr );
-
-    dsptri_( &uplo, &N, mx, ipiv, work, &ierr );
-
-    delete[] ipiv;
-    delete[] work;
-
-  } else {
-
-    ierr = 999;
-  }
-}
-
-double AlSymMat::determinant() {
+double AlSymMat::determinant() const {
 
   double deter = 1.;
 
   // get determinant using LU decomposition + Crout algorithm
 
-  AlMat A( Size, Size );
-  A.copyS( *this );
+  AlMat A = this->toMatrix();
 
-  double AMAX, DUM, SUM;
-  int    CODE;
-  double TINY = 1.E-20;
-  double D;
-  size_t N = Size;
+  double     AMAX, DUM, SUM;
+  int        CODE;
+  double     TINY = 1.E-20;
+  double     D;
+  const auto N = rows();
 
   D    = 1.;
   CODE = 0;
 
-  for ( size_t I = 0; I < N; I++ ) {
+  for ( size_t I = 0; I < N; ++I ) {
     AMAX = 0.;
-    for ( size_t J = 0; J < N; J++ ) {
-      if ( fabs( A[I][J] ) > AMAX ) AMAX = fabs( A[I][J] );
+    for ( size_t J = 0; J < N; ++J ) {
+      if ( std::abs( A( I, J ) ) > AMAX ) AMAX = std::abs( A( I, J ) );
     }
     if ( AMAX < TINY ) {
       CODE = 1; // matrix is singular
@@ -405,38 +85,38 @@ double AlSymMat::determinant() {
 
     for ( size_t I = 0; I < N; I++ ) {
 
-      SUM         = A[I][J];
+      SUM         = A( I, J );
       size_t KMAX = ( I < J ) ? I : J;
-      for ( size_t K = 0; K < KMAX; K++ ) SUM = SUM - A[I][K] * A[K][J];
-      A[I][J] = SUM;
+      for ( size_t K = 0; K < KMAX; K++ ) SUM = SUM - A( I, K ) * A( K, J );
+      A( I, J ) = SUM;
     }
 
     // find pivot and exchange if necessary
 
     size_t IMAX = J;
     for ( size_t I = J + 1; I < N; I++ ) {
-      if ( fabs( A[I][J] ) > fabs( A[IMAX][J] ) ) IMAX = I;
+      if ( std::abs( A( I, J ) ) > std::abs( A( IMAX, J ) ) ) IMAX = I;
     }
 
     if ( IMAX != J ) {
       for ( size_t K = 0; K < N; K++ ) {
-        DUM        = A[IMAX][K];
-        A[IMAX][K] = A[J][K];
-        A[J][K]    = DUM;
+        DUM          = A( IMAX, K );
+        A( IMAX, K ) = A( J, K );
+        A( J, K )    = DUM;
       }
       D = -D;
     }
 
-    if ( J < N && ( fabs( A[J][J] ) > TINY ) ) {
+    if ( J < N && ( std::abs( A( J, J ) ) > TINY ) ) {
 
-      DUM = 1. / A[J][J];
-      for ( size_t I = J + 1; I < N; I++ ) A[I][J] = A[I][J] * DUM;
+      DUM = 1. / A( J, J );
+      for ( size_t I = J + 1; I < N; I++ ) A( I, J ) = A( I, J ) * DUM;
     }
   }
 
   if ( CODE == 0 ) {
     deter = deter * D;
-    for ( size_t I = 0; I < N; I++ ) { deter = deter * A[I][I]; }
+    for ( size_t I = 0; I < N; I++ ) { deter = deter * A( I, I ); }
     return deter;
 
   } else {
@@ -444,73 +124,47 @@ double AlSymMat::determinant() {
   }
 }
 
-int AlSymMat::diagonalize( char jobz, AlVec& w, AlMat& z ) {
-
-  int     info = 0;
-  char    uplo = 'U';
-  int     N    = Size;
-  double* work = new double[3 * N];
+int AlSymMat::diagonalize_GSL( AlVec& egval, AlMat& egvec ) const {
 
-  double* ap = ptr_data;
+  const auto N = rows();
 
-  dspev_( &jobz, &uplo, &N, ap, w.ptr_data, z.ptr_data, &N, work, &info );
-
-  delete[] work;
-
-  return info;
-}
-
-void AlSymMat::diagonalize_GSL( AlVec& egval, AlMat& egvec ) {
-
-  size_t N = Size;
-
-  std::cout << " Debug...before gsl_matrix_alloc" << std::endl;
+  // std::cout << " Debug...before gsl_matrix_alloc" << std::endl;
 
   gsl_matrix* m = gsl_matrix_alloc( N, N );
 
-  std::cout << " Debug...after gsl_matrix_alloc" << std::endl;
+  // std::cout << " Debug...after gsl_matrix_alloc" << std::endl;
 
   //  if (1) {
   //    AlMat V(N,N);
   //    V.copyS((*this));
   //    m->data = V.ptr_data;
   for ( size_t ig = 0; ig < N; ig++ ) {
-    for ( size_t jg = 0; jg < N; jg++ ) { gsl_matrix_set( m, ig, jg, ( *this )[ig][jg] ); }
+    for ( size_t jg = 0; jg < N; jg++ ) { gsl_matrix_set( m, ig, jg, ( *this )( ig, jg ) ); }
   }
   //    gsl_matrix_set(m,0,0,temp00);
   //  std::cout<<"gsl00: "<<gsl_matrix_get(m,0,0)<<std::endl;
 
   // }
 
-  std::cout << "Debut....printing gsl matrix elements" << std::endl;
-
-  for ( size_t ig = 0; ig < N; ig++ ) {
-    for ( size_t jg = 0; jg < N; jg++ ) { std::cout << gsl_matrix_get( m, ig, jg ) << "   "; }
-    std::cout << std::endl;
-  }
-
-  std::cout << " Debug...after copy ptr data" << std::endl;
-
   gsl_vector* eval = gsl_vector_alloc( N );
   gsl_matrix* evec = gsl_matrix_alloc( N, N );
 
-  gsl_eigen_symmv_workspace* w = gsl_eigen_symmv_alloc( N );
-  gsl_eigen_symmv( m, eval, evec, w );
+  gsl_eigen_symmv_workspace* w  = gsl_eigen_symmv_alloc( N );
+  int                        rc = gsl_eigen_symmv( m, eval, evec, w );
 
   gsl_eigen_symmv_free( w );
 
-  std::cout << " Debug...after diagonalization" << std::endl;
+  // std::cout << " Debug...after diagonalization" << std::endl;
 
   // sort eigen values/eigen vectors in ascending order
   gsl_eigen_symmv_sort( eval, evec, GSL_EIGEN_SORT_VAL_ASC );
 
-  egval.ptr_data = eval->data;
-  egvec.ptr_data = evec->data;
+  for ( size_t ig = 0; ig < N; ++ig ) {
+    egval( ig ) = gsl_vector_get( eval, ig );
+    for ( size_t jg = 0; jg < N; ++jg ) { egvec( ig, jg ) = gsl_matrix_get( evec, ig, jg ); }
+  }
+  gsl_matrix_free( evec );
+  gsl_vector_free( eval );
 
-  // for(int ig=0;ig<N;ig++) {
-  //  egval[ig]=gsl_vector_get(eval,ig);
-  // for(int jg=0;jg<N;jg++) {
-  //    egvec[ig][jg]=gsl_matrix_get(evec,ig,jg);
-  //  }
-  //}
+  return rc;
 }
diff --git a/Alignment/AlignKernel/src/AlVec.cpp b/Alignment/AlignKernel/src/AlVec.cpp
deleted file mode 100644
index c1eebc41b15eac7bdf1d4fc8f72551895b239a46..0000000000000000000000000000000000000000
--- a/Alignment/AlignKernel/src/AlVec.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-#include "AlignKernel/AlVec.h"
-#include "AlignKernel/AlMat.h"
-#include "AlignKernel/AlSymMat.h"
-#include <iomanip>
-#include <iostream>
-#include <string.h>
-
-AlVec::AlVec() {
-
-  Nele     = 0;
-  ptr_data = 0; // set pointer to null
-}
-
-AlVec::AlVec( size_t N ) {
-
-  Nele     = N;
-  ptr_data = new double[Nele];
-  for ( size_t i = 0; i < Nele; i++ ) *( ptr_data + i ) = 0.;
-}
-
-AlVec::AlVec( const AlVec& v ) {
-
-  Nele     = v.Nele;
-  ptr_data = new double[Nele];
-  memcpy( ptr_data, v.ptr_data, Nele * sizeof( double ) );
-}
-
-AlVec::~AlVec() { delete[] ptr_data; }
-
-double& AlVec::operator[]( size_t i ) {
-
-  if ( i >= Nele ) {
-    std::cerr << "AlVec: Index too large! " << std::endl;
-    return ptr_data[0];
-  };
-
-  return *( ptr_data + i );
-}
-
-const double& AlVec::operator[]( size_t i ) const {
-
-  if ( i >= Nele ) {
-    std::cerr << "AlVec: Index too large! " << std::endl;
-    return ptr_data[0];
-  };
-
-  return *( ptr_data + i );
-}
-
-AlVec& AlVec::operator=( const AlVec& v ) {
-  if ( size() != v.size() ) {
-    delete[] ptr_data;
-    Nele     = v.Nele;
-    ptr_data = new double[Nele];
-  }
-  memcpy( ptr_data, v.ptr_data, Nele * sizeof( double ) );
-  return *this;
-}
-
-AlVec AlVec::operator+( const AlVec& v ) {
-
-  if ( Nele != v.Nele ) {
-    std::cerr << "operator+: vectors size does not match!" << std::endl;
-    return *this;
-  };
-  AlVec b( Nele );
-
-  for ( size_t i = 0; i < Nele; i++ ) b[i] = *( ptr_data + i ) + v[i];
-  return b;
-}
-
-AlVec AlVec::operator+( const AlVec& v ) const {
-
-  if ( Nele != v.Nele ) {
-    std::cerr << "operator+: vectors size does not match!" << std::endl;
-    return *this;
-  };
-  AlVec b( Nele );
-
-  for ( size_t i = 0; i < Nele; i++ ) b[i] = *( ptr_data + i ) + v[i];
-  return b;
-}
-
-AlVec& AlVec::operator+=( const AlVec& v ) {
-
-  if ( Nele != v.Nele ) {
-    std::cerr << "operator+=: vectors size does not match!" << std::endl;
-    return *this;
-  };
-
-  for ( size_t i = 0; i < Nele; i++ ) *( ptr_data + i ) += v[i];
-  return *this;
-}
-
-AlVec AlVec::operator-( const AlVec& v ) {
-
-  if ( Nele != v.Nele ) {
-    std::cerr << "operator+: vectors size does not match!" << std::endl;
-    return *this;
-  }
-  AlVec b( Nele );
-
-  for ( size_t i = 0; i < Nele; i++ ) b[i] = *( ptr_data + i ) - v[i];
-  return b;
-}
-
-AlVec AlVec::operator-( const AlVec& v ) const {
-
-  if ( Nele != v.Nele ) {
-    std::cerr << "operator+: vectors size does not match!" << std::endl;
-    return *this;
-  }
-  AlVec b( Nele );
-
-  for ( size_t i = 0; i < Nele; i++ ) b[i] = *( ptr_data + i ) - v[i];
-  return b;
-}
-
-AlVec& AlVec::operator-=( const AlVec& v ) {
-
-  if ( Nele != v.Nele ) {
-    std::cerr << "operator+=: vectors size does not match!" << std::endl;
-    return *this;
-  }
-
-  for ( size_t i = 0; i < Nele; i++ ) *( ptr_data + i ) -= v[i];
-  return *this;
-}
-
-double AlVec::operator*( const AlVec& v ) {
-  double b = 0.;
-  if ( Nele != v.Nele ) {
-    std::cerr << "scalar product: vectors size does not match!" << std::endl;
-    return b;
-  }
-
-  for ( size_t i = 0; i < Nele; i++ ) b += *( ptr_data + i ) * v[i];
-  return b;
-}
-
-double AlVec::operator*( const AlVec& v ) const {
-  double b = 0.;
-  if ( Nele != v.Nele ) {
-    std::cerr << "scalar product: vectors size does not match!" << std::endl;
-    return b;
-  }
-
-  for ( size_t i = 0; i < Nele; i++ ) b += *( ptr_data + i ) * v[i];
-  return b;
-}
-
-AlVec AlVec::operator*( const AlMat& m ) {
-
-  if ( Nele != m.Nrow ) {
-    std::cerr << "Left hand vector-matrix multiplication: size does not match!" << std::endl;
-    return *this;
-  }
-
-  AlVec b( m.Ncol );
-
-  for ( size_t i = 0; i < m.Ncol; i++ ) {
-    for ( size_t j = 0; j < Nele; j++ ) b[i] += *( ptr_data + j ) * m[j][i];
-  }
-
-  return b;
-}
-
-AlVec AlVec::operator*( const AlMat& m ) const {
-
-  if ( Nele != m.Nrow ) {
-    std::cerr << "Left hand vector-matrix multiplication: size does not match!" << std::endl;
-    return *this;
-  }
-
-  AlVec b( m.Ncol );
-
-  for ( size_t i = 0; i < m.Ncol; i++ ) {
-    for ( size_t j = 0; j < Nele; j++ ) b[i] += *( ptr_data + j ) * m[j][i];
-  }
-
-  return b;
-}
-
-AlVec AlVec::operator*( const AlSymMat& m ) {
-
-  if ( Nele != m.Size ) {
-    std::cerr << "Left hand vector-matrix multiplication: size does not match!" << std::endl;
-    return *this;
-  }
-
-  AlVec b( m.Size );
-
-  for ( size_t i = 0; i < m.Size; i++ ) {
-    for ( size_t j = 0; j < Nele; j++ ) b[i] += *( ptr_data + j ) * m[j][i];
-  }
-
-  return b;
-}
-
-AlVec AlVec::operator*( const AlSymMat& m ) const {
-
-  if ( Nele != m.Size ) {
-    std::cerr << "Left hand vector-matrix multiplication: size does not match!" << std::endl;
-    return *this;
-  }
-
-  AlVec b( m.Size );
-
-  for ( size_t i = 0; i < m.Size; i++ ) {
-    for ( size_t j = 0; j < Nele; j++ ) b[i] += *( ptr_data + j ) * m[j][i];
-  }
-
-  return b;
-}
-
-AlVec& AlVec::operator*=( const double& d ) {
-
-  for ( size_t i = 0; i < Nele; i++ ) *( ptr_data + i ) *= d;
-
-  return *this;
-}
-
-AlVec AlVec::operator*( const double& d ) {
-  AlVec b( Nele );
-  for ( size_t i = 0; i < Nele; i++ ) b[i] = *( ptr_data + i ) * d;
-  return b;
-}
-
-AlVec AlVec::operator*( const double& d ) const {
-  AlVec b( Nele );
-  for ( size_t i = 0; i < Nele; i++ ) b[i] = *( ptr_data + i ) * d;
-  return b;
-}
-
-void AlVec::reSize( size_t Nnew ) {
-
-  if ( Nnew != Nele && Nele != 0 ) {
-    double* p        = ptr_data;
-    size_t  Nele_old = Nele;
-    ptr_data         = new double[Nnew];
-    Nele             = Nnew;
-    size_t k         = Nele <= Nele_old ? Nele : Nele_old;
-
-    p += k;
-    double* q = ptr_data + k;
-    while ( q > ptr_data ) *( --q ) = *( --p );
-
-    delete[] p;
-  }
-
-  if ( Nele == 0 ) *this = AlVec( Nnew );
-}
-
-void AlVec::removeElement( size_t Nr ) {
-
-  // reorganize vector by filling holes, etc...
-  for ( size_t i = Nr; i < Nele - 1; i++ ) ( *this )[i] = ( *this )[i + 1];
-
-  // delete obsolete space and shrink vector size by one unit
-  delete ( ptr_data + Nele - 1 );
-  Nele--;
-}
-
-void AlVec::ShrinkDofs( std::vector<bool>& mask ) {
-
-  if ( mask.size() != Nele ) {
-    std::cerr << "Beware, mask size different from vector size, skip..." << std::endl;
-    return;
-  }
-
-  size_t offset = 0;
-
-  for ( size_t iR = 0; iR < mask.size(); iR++ ) {
-    if ( !mask[iR] ) {
-      removeElement( iR - offset );
-      offset++;
-    }
-  }
-}
diff --git a/Alignment/AlignSolvTools/src/CLHEPSolver.cpp b/Alignment/AlignSolvTools/src/CLHEPSolver.cpp
index 5241345bb607f1583a9702500298bb2059917dfa..f1042f25dff9f4272a8e5cc588c273e0a3e0e9c1 100755
--- a/Alignment/AlignSolvTools/src/CLHEPSolver.cpp
+++ b/Alignment/AlignSolvTools/src/CLHEPSolver.cpp
@@ -27,15 +27,15 @@ class CLHEPSolver : public extends<GaudiTool, IAlignSolvTool> {
 
 public:
   /// Standard constructor
-  CLHEPSolver( const std::string& type, const std::string& name, const IInterface* parent );
+  using extends::extends;
 
   using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
   /// Solves Ax = b using gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, gsl_vector * work)
-  bool compute( AlSymMat& symMatrix, AlVec& vector ) const override;
+  StatusCode compute( AlSymMat& symMatrix, AlVec& vector ) const override;
 
 private:
-  bool   m_useSVD;
-  size_t m_numberOfPrintedEigenvalues;
+  Gaudi::Property<size_t> m_numberOfPrintedEigenvalues{this, "NumberOfPrintedEigenvalues", 20};
+  Gaudi::Property<bool>   m_useSVD{this, "UseSVD", true};
 };
 
 //-----------------------------------------------------------------------------
@@ -51,22 +51,12 @@ DECLARE_COMPONENT( CLHEPSolver )
 #include "CLHEP/Matrix/SymMatrix.h"
 #include "CLHEP/Matrix/Vector.h"
 
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-CLHEPSolver::CLHEPSolver( const std::string& type, const std::string& name, const IInterface* parent )
-    : base_class( type, name, parent ) {
-  declareInterface<IAlignSolvTool>( this );
-  declareProperty( "NumberOfPrintedEigenvalues", m_numberOfPrintedEigenvalues = 20 );
-  declareProperty( "UseSVD", m_useSVD = true );
-}
-
 // fix CLHEP bug exposed in gcc 4.3
 namespace CLHEP {
   double dot( const HepVector& v1, const HepVector& v2 );
 }
 
-bool CLHEPSolver::compute( AlSymMat& symMatrix, AlVec& vector ) const {
+StatusCode CLHEPSolver::compute( AlSymMat& symMatrix, AlVec& vector ) const {
 
   // copy system into CLHEP matrices
   size_t              size = symMatrix.size();
@@ -74,7 +64,7 @@ bool CLHEPSolver::compute( AlSymMat& symMatrix, AlVec& vector ) const {
   CLHEP::HepVector    b( size );
   for ( size_t irow = 0; irow < size; ++irow ) {
     b( irow + 1 ) = vector[irow];
-    for ( size_t icol = 0; icol <= irow; ++icol ) A.fast( irow + 1, icol + 1 ) = symMatrix[irow][icol];
+    for ( size_t icol = 0; icol <= irow; ++icol ) A.fast( irow + 1, icol + 1 ) = symMatrix.fast( irow, icol );
   }
 
   clock_t starttime = clock();
@@ -129,8 +119,8 @@ bool CLHEPSolver::compute( AlSymMat& symMatrix, AlVec& vector ) const {
   // now copy everything back
   for ( size_t irow = 0; irow < size; ++irow ) {
     vector[irow] = delta( irow + 1 );
-    for ( size_t icol = 0; icol <= irow; ++icol ) symMatrix[irow][icol] = cov.fast( irow + 1, icol + 1 );
+    for ( size_t icol = 0; icol <= irow; ++icol ) symMatrix.fast( irow, icol ) = cov.fast( irow + 1, icol + 1 );
   }
 
-  return true;
+  return StatusCode::SUCCESS;
 }
diff --git a/Alignment/AlignSolvTools/src/DiagSolvTool.cpp b/Alignment/AlignSolvTools/src/DiagSolvTool.cpp
deleted file mode 100755
index b99fbb87c00ad28b90a3a158be95b30078ac197d..0000000000000000000000000000000000000000
--- a/Alignment/AlignSolvTools/src/DiagSolvTool.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-// Include files
-
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <math.h>
-#include <set>
-#include <stdio.h>
-#include <string>
-
-#include "AlignKernel/AlMat.h"
-#include "AlignKernel/AlSymMat.h"
-#include "AlignKernel/AlVec.h"
-
-// local
-#include "DiagSolvTool.h"
-
-//-----------------------------------------------------------------------------
-// Implementation file for class : DiagSolvTool
-//
-// 2007-06 : Adlene Hicheur
-//-----------------------------------------------------------------------------
-
-// Declaration of the Tool Factory
-DECLARE_COMPONENT( DiagSolvTool )
-
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-DiagSolvTool::DiagSolvTool( const std::string& type, const std::string& name, const IInterface* parent )
-    : GaudiTool( type, name, parent ) {
-  declareInterface<IAlignSolvTool>( this );
-  declareProperty( "NumberOfPrintedEigenvalues", m_numberOfPrintedEigenvalues = 20 );
-  declareProperty( "EigenValueThreshold", m_eigenValueThreshold = -1 );
-  declareProperty( "ApplyScaling", m_applyScaling = false );
-  declareProperty( "MinEigenModeChisquare", m_minEigenModeChisquare = -1 );
-}
-
-//=============================================================================
-// Destructor
-//=============================================================================
-DiagSolvTool::~DiagSolvTool() {}
-
-//=============================================================================
-// Initialize
-//=============================================================================
-StatusCode DiagSolvTool::initialize() {
-  StatusCode sc = GaudiTool::initialize();
-  info() << "EigenValueThreshold = " << m_eigenValueThreshold << endmsg;
-  info() << "MinEigenModeChisquare = " << m_minEigenModeChisquare << endmsg;
-  return sc;
-}
-
-//=============================================================================
-
-bool DiagSolvTool::compute( AlSymMat& m, AlVec& b ) const {
-  IAlignSolvTool::SolutionInfo info;
-  StatusCode                   sc = compute( m, b, info );
-  return sc.isSuccess();
-}
-
-namespace {
-  struct SortByAbsSecond {
-    template <class T>
-    bool operator()( const T& lhs, const T& rhs ) const {
-      return std::abs( lhs.second ) < std::abs( rhs.second );
-    }
-  };
-} // namespace
-
-StatusCode DiagSolvTool::compute( AlSymMat& m_bigmatrix, AlVec& m_bigvector,
-                                  IAlignSolvTool::SolutionInfo& solinfo ) const {
-  StatusCode sc = StatusCode::SUCCESS;
-
-  info() << "Solving with diagonalization method " << endmsg;
-
-  char   jobz = 'V';
-  size_t N    = m_bigmatrix.size();
-
-  // declare transition matrix + vector to store eigenvalues
-  AlMat z( N, N );
-  AlVec w( N );
-  AlVec rweight( N ), cweight( N );
-
-  info() << "After z/w allocation" << endmsg;
-
-  // do solving, default diagonalization via LAPACK
-
-  int infjob = m_bigmatrix.diagonalize( jobz, w, z );
-
-  // diagonalize via GSL
-  //  m_bigmatrix.diagonalize_GSL(w,z);
-
-  info() << "After diagonalization" << endmsg;
-
-  // Dump the 10 smallest eigenvalues. We'll sort these really in abs,
-  // ignoring the sign.
-  {
-    // count the number of negative eigenvalues and number smaller than one
-    solinfo.numNegativeEigenvalues = solinfo.numSmallEigenvalues = 0;
-    std::vector<std::pair<size_t, double>> sortedev( N );
-    for ( size_t ipar = 0; ipar < N; ++ipar ) {
-      sortedev[ipar] = std::make_pair( ipar, w[ipar] );
-      if ( std::abs( w[ipar] ) < 1.0 ) ++solinfo.numSmallEigenvalues;
-      if ( w[ipar] < 0.0 ) ++solinfo.numNegativeEigenvalues;
-    }
-
-    std::sort( sortedev.begin(), sortedev.end(), SortByAbsSecond() );
-    std::ostringstream logmessage;
-    logmessage << "Smallest eigen values: [ " << std::setprecision( 4 );
-    size_t maxpar = std::min( N, m_numberOfPrintedEigenvalues );
-    for ( size_t ipar = 0; ipar < maxpar; ++ipar )
-      logmessage << sortedev[ipar].second << ( ( ipar < maxpar - 1 ) ? ", " : " ]" );
-
-    // consider the smallest eigenvalue
-    if ( N > 0 ) {
-      // dump the corresponding eigenvector
-      if ( N <= m_numberOfPrintedEigenvalues ) {
-        logmessage << std::endl;
-        logmessage << "Eigenvector for smallest eigenvalue: [ ";
-        for ( size_t ipar = 0; ipar < N; ++ipar ) {
-          logmessage << z[sortedev[0].first][ipar] << ( ( ipar < N - 1 ) ? ", " : " ]" );
-        }
-      }
-      // figure out which parameter contributes most to this eigenvector
-      size_t thepar( 0 );
-      for ( size_t ipar = 0; ipar < N; ++ipar ) {
-        if ( std::abs( z[sortedev[0].first][thepar] ) < std::abs( z[sortedev[0].first][ipar] ) ) thepar = ipar;
-      }
-      solinfo.minEigenValue         = sortedev[0].second;
-      solinfo.weakestModeMaxPar     = thepar;
-      solinfo.weakestModeMaxParCoef = z[sortedev[0].first][thepar];
-    }
-    info() << logmessage.str() << endmsg;
-  }
-
-  if ( infjob == 0 ) {
-
-    //   Compute bigvector in diagonal basis
-    AlVec D( N );
-
-    D = z * m_bigvector;
-    // Warning: with GSL, the definition of z is transposed:
-    // D = z.T()*m_bigvector;
-
-    // Issue a warning for each negative eigenvalue
-    for ( size_t ipar = 0; ipar < N; ++ipar )
-      if ( !( w[ipar] > 0 ) )
-        warning() << "Negative eigenvalue (i,val,chi2)= " << ipar << " " << w[ipar] << " "
-                  << D[ipar] * D[ipar] / w[ipar] << endmsg;
-
-    // compute alignment corrections and their variance. first flag
-    // modes that we cut away by eigenvalue. (constraints have large
-    // negative value, so the 'abs' should do)
-    std::vector<bool> keepEigenValue( N, true );
-    if ( m_eigenValueThreshold > 0 )
-      for ( size_t i = 0; i < N; i++ )
-        keepEigenValue[i] = std::abs( w[i] ) > m_eigenValueThreshold ||
-                            ( m_minEigenModeChisquare > 0 && D[i] * D[i] / w[i] > m_minEigenModeChisquare );
-
-    double                sumchisqaccepted( 0 ), sumchisqrejected( 0 ), maxchisq( 0 );
-    size_t                numrejected( 0 );
-    std::multiset<double> chisqvalues;
-    for ( size_t i = 0; i < N; i++ ) {
-      double thischisq = D[i] * D[i] / w[i];
-      if ( !keepEigenValue[i] ) {
-        info() << "Rejecting eigenvalue: val = " << w[i] << " chisq = " << thischisq << endmsg;
-        ++numrejected;
-        sumchisqrejected += thischisq;
-      } else {
-        chisqvalues.insert( thischisq );
-        if ( maxchisq < thischisq ) maxchisq = thischisq;
-        sumchisqaccepted += thischisq;
-        if ( std::abs( w[i] ) < m_eigenValueThreshold )
-          info() << "Accepting eigenvalue: val = " << w[i] << " chisq = " << thischisq << endmsg;
-      }
-    }
-
-    solinfo.totalChisq = sumchisqaccepted;
-
-    info() << "Number / total chi2 of rejected eigenvalues: " << numrejected << " " << sumchisqrejected << endmsg;
-    info() << "Total chi2 of accepted eigenvalues: " << sumchisqaccepted << endmsg;
-    info() << "Maximum chi2 of individual mode: " << maxchisq << endmsg;
-
-    // because the lagrange constraints lead to negative ev, they also
-    // give negative chi2 contributions. that's all fine for the total
-    // chi2, but it leads to problems if you want to identify the
-    // 'largest' chi2 contribution: such contributions may be
-    // compensated by large negative contributions. Let's solve this
-    // pragmatically:
-    // - make a multiset of all chisq contributions
-    // - while the smallest one is negative, remove the smallest and
-    //   largest from the set, and reinsert the sum
-    // - the largest remaining eigenvalue is the one we need;
-    while ( !chisqvalues.empty() && *( chisqvalues.begin() ) < 0 && *( chisqvalues.rbegin() ) > 0 ) {
-      double a = *( chisqvalues.begin() );
-      chisqvalues.erase( chisqvalues.begin() );
-      double b = *( chisqvalues.rbegin() );
-      chisqvalues.erase( --( chisqvalues.rbegin().base() ) );
-      chisqvalues.insert( a + b );
-    }
-    if ( !chisqvalues.empty() ) solinfo.maxChisqEigenMode = *( chisqvalues.rbegin() );
-
-    info() << "Maximum chi2 of individual mode after correcting for lagrange constraints: " << solinfo.maxChisqEigenMode
-           << endmsg;
-
-    // reset the input
-    for ( size_t i = 0; i < N; i++ ) {
-      m_bigvector[i] = 0;
-      for ( size_t j = 0; j <= i; j++ ) m_bigmatrix[i][j] = 0.;
-    }
-
-    // now fill it
-    for ( size_t k = 0; k < N; ++k )
-      if ( keepEigenValue[k] )
-        for ( size_t i = 0; i < N; ++i ) {
-          m_bigvector[i] += z[k][i] * D[k] / w[k];
-          for ( size_t j = 0; j <= i; ++j ) m_bigmatrix[i][j] += ( z[k][i] * z[k][j] / ( w[k] ) );
-        }
-
-  } else {
-    error() << "inversion (diagonalization) of big matrix failed" << endmsg;
-    sc = StatusCode::FAILURE;
-  }
-
-  return sc;
-}
diff --git a/Alignment/AlignSolvTools/src/DiagSolvToolBase.cpp b/Alignment/AlignSolvTools/src/DiagSolvToolBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c1d33c2708f3d48cb6533689c8ceedc0b5060346
--- /dev/null
+++ b/Alignment/AlignSolvTools/src/DiagSolvToolBase.cpp
@@ -0,0 +1,199 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+// Include files
+
+#include <iomanip>
+#include <iostream>
+#include <set>
+
+// local
+#include "DiagSolvToolBase.h"
+
+//-----------------------------------------------------------------------------
+// Implementation file for class : DiagSolvTool
+//
+// 2007-06 : Adlene Hicheur
+//-----------------------------------------------------------------------------
+
+// Declaration of the Tool Factory
+// DECLARE_COMPONENT( DiagSolvTool )
+
+//=============================================================================
+// Initialize
+//=============================================================================
+StatusCode DiagSolvToolBase::initialize() {
+  StatusCode sc = GaudiTool::initialize();
+  info() << "EigenValueThreshold = " << m_eigenValueThreshold << endmsg;
+  info() << "MinEigenModeChisquare = " << m_minEigenModeChisquare << endmsg;
+  return sc;
+}
+
+namespace {
+  struct SortByAbsSecond {
+    template <class T>
+    bool operator()( const T& lhs, const T& rhs ) const {
+      return std::abs( lhs.second ) < std::abs( rhs.second );
+    }
+  };
+} // namespace
+
+StatusCode DiagSolvToolBase::compute( AlSymMat& bigmatrix, AlVec& bigvector,
+                                      IAlignSolvTool::SolutionInfo& solinfo ) const {
+  info() << "Solving with diagonalization method" << endmsg;
+
+  // declare transition matrix + vector to store eigenvalues
+  const size_t N = bigmatrix.rows();
+  AlMat        U( N, N );
+  AlMat        V( N, N );
+  AlVec        S( N );
+
+  debug() << "Before diagonalization" << endmsg;
+
+  // defer the diagonalization to whatever tool derives from this.
+  // bigmatrix = U S V^T
+  StatusCode sc = diagonalize( bigmatrix, U, V, S );
+  if ( !sc.isSuccess() ) {
+    error() << "Diagonalization failed" << endmsg;
+    return sc;
+  }
+
+  debug() << "After diagonalization" << endmsg;
+
+  //   Compute bigvector in diagonal basis. Here we need the transpose of U, just like it would be in GSL.
+  const Eigen::VectorXd D = U.transpose() * bigvector;
+
+  // Perform some analysis of the eigenvalues.
+  solinfo.numNegativeEigenvalues = solinfo.numSmallEigenvalues = 0;
+  {
+    // count the number of negative eigenvalues and number smaller than one
+    std::vector<std::pair<size_t, double>> sortedev( N );
+    for ( size_t ipar = 0; ipar < N; ++ipar ) {
+      sortedev[ipar] = std::make_pair( ipar, S[ipar] );
+      if ( std::abs( S[ipar] ) < 1.0 ) ++solinfo.numSmallEigenvalues;
+
+      // Eigen and Gsl put the 'sign' of negative eigenvalues in a
+      // difference between U and V. This explains why we do not see
+      // negative Eigenvalues and need to use both U and V in the
+      // solution.
+      const double sign = U.col( ipar ).dot( V.col( ipar ) );
+      if ( !( sign * S[ipar] > 0.0 ) ) {
+        ++solinfo.numNegativeEigenvalues;
+        // Issue a warning for each negative eigenvalue.
+        warning() << "Negative eigenvalue (i,val,chi2)= " << ipar << " " << sign * S( ipar ) << " "
+                  << D( ipar ) * D( ipar ) / S( ipar ) << endmsg;
+      }
+    }
+
+    // Dump the 10 smallest eigenvalues. We'll sort these really in
+    // abs, ignoring the sign.
+    std::sort( sortedev.begin(), sortedev.end(), SortByAbsSecond() );
+    std::ostringstream logmessage;
+    logmessage << "Smallest eigen values: [ " << std::setprecision( 4 );
+    size_t maxpar = std::min( N, m_numberOfPrintedEigenvalues.value() );
+    for ( size_t ipar = 0; ipar < maxpar; ++ipar )
+      logmessage << sortedev[ipar].second << ( ( ipar < maxpar - 1 ) ? ", " : " ]" );
+
+    // consider the smallest eigenvalue
+    if ( N > 0 ) {
+      // dump the corresponding eigenvector
+      if ( N <= m_numberOfPrintedEigenvalues ) {
+        logmessage << std::endl;
+        logmessage << "Eigenvector for smallest eigenvalue: [ ";
+        for ( size_t ipar = 0; ipar < N; ++ipar ) {
+          logmessage << U( sortedev[0].first, ipar ) << ( ( ipar < N - 1 ) ? ", " : " ]" );
+        }
+      }
+      // figure out which parameter contributes most to this eigenvector
+      size_t thepar( 0 );
+      for ( size_t ipar = 0; ipar < N; ++ipar ) {
+        if ( std::abs( U( sortedev[0].first, thepar ) ) < std::abs( U( sortedev[0].first, ipar ) ) ) thepar = ipar;
+      }
+      solinfo.minEigenValue         = sortedev[0].second;
+      solinfo.weakestModeMaxPar     = thepar;
+      solinfo.weakestModeMaxParCoef = U( sortedev[0].first, thepar );
+    }
+    info() << logmessage.str() << endmsg;
+  }
+
+  // compute alignment corrections and their variance. first flag
+  // modes that we cut away by eigenvalue. (constraints have large
+  // negative value, so the 'abs' should do)
+  std::vector<bool> keepEigenValue( N, true );
+  if ( m_eigenValueThreshold > 0 )
+    for ( size_t i = 0; i < N; i++ )
+      keepEigenValue[i] = std::abs( S( i ) ) > m_eigenValueThreshold ||
+                          ( m_minEigenModeChisquare > 0 && D( i ) * D( i ) / S( i ) > m_minEigenModeChisquare );
+
+  double                sumchisqaccepted( 0 ), sumchisqrejected( 0 ), maxchisq( 0 );
+  size_t                numrejected( 0 );
+  std::multiset<double> chisqvalues;
+  for ( size_t i = 0; i < N; i++ ) {
+    double thischisq = D( i ) * D( i ) / S( i );
+    if ( !keepEigenValue[i] ) {
+      info() << "Rejecting eigenvalue: val = " << S( i ) << " chisq = " << thischisq << endmsg;
+      ++numrejected;
+      sumchisqrejected += thischisq;
+    } else {
+      chisqvalues.insert( thischisq );
+      if ( maxchisq < thischisq ) maxchisq = thischisq;
+      sumchisqaccepted += thischisq;
+      if ( std::abs( S( i ) ) < m_eigenValueThreshold )
+        info() << "Accepting low eigenvalue: val = " << S( i ) << " chisq = " << thischisq << endmsg;
+    }
+  }
+
+  solinfo.totalChisq = sumchisqaccepted;
+
+  info() << "Number / total chi2 of rejected eigenvalues: " << numrejected << " " << sumchisqrejected << endmsg;
+  info() << "Total chi2 of accepted eigenvalues: " << sumchisqaccepted << endmsg;
+  info() << "Maximum chi2 of individual mode: " << maxchisq << endmsg;
+
+  // because the lagrange constraints lead to negative ev, they also
+  // give negative chi2 contributions. that's all fine for the total
+  // chi2, but it leads to problems if you want to identify the
+  // 'largest' chi2 contribution: such contributions may be
+  // compensated by large negative contributions. Let's solve this
+  // pragmatically:
+  // - make a multiset of all chisq contributions
+  // - while the smallest one is negative, remove the smallest and
+  //   largest from the set, and reinsert the sum
+  // - the largest remaining eigenvalue is the one we need;
+  while ( !chisqvalues.empty() && *( chisqvalues.begin() ) < 0 && *( chisqvalues.rbegin() ) > 0 ) {
+    double a = *( chisqvalues.begin() );
+    chisqvalues.erase( chisqvalues.begin() );
+    double b = *( chisqvalues.rbegin() );
+    chisqvalues.erase( --( chisqvalues.rbegin().base() ) );
+    chisqvalues.insert( a + b );
+  }
+  if ( !chisqvalues.empty() ) solinfo.maxChisqEigenMode = *( chisqvalues.rbegin() );
+
+  info() << "Maximum chi2 of individual mode after correcting for lagrange constraints: " << solinfo.maxChisqEigenMode
+         << endmsg;
+
+  // reset the input
+  for ( size_t i = 0; i < N; i++ ) {
+    bigvector( i ) = 0.;
+    for ( size_t j = 0; j <= i; j++ ) bigmatrix( i, j ) = 0.;
+  }
+
+  // now fill it
+  for ( size_t k = 0; k < N; ++k )
+    if ( keepEigenValue[k] ) {
+      for ( size_t i = 0; i < N; ++i ) {
+        bigvector( i ) += V( i, k ) * D( k ) / S( k );
+        for ( size_t j = 0; j <= i; ++j ) bigmatrix( i, j ) += V( i, k ) * U( j, k ) / S( k );
+      }
+    } else {
+      warning() << "Rejecting eigenvalue: " << k << " " << S( k ) << endmsg;
+    }
+
+  return sc;
+}
diff --git a/Alignment/AlignSolvTools/src/DiagSolvTool.h b/Alignment/AlignSolvTools/src/DiagSolvToolBase.h
old mode 100755
new mode 100644
similarity index 63%
rename from Alignment/AlignSolvTools/src/DiagSolvTool.h
rename to Alignment/AlignSolvTools/src/DiagSolvToolBase.h
index b168cc43b15c85d11ea10d98acd8998944c176ef..58d19f73467f4e940b769d5b0abb82625f87bc7d
--- a/Alignment/AlignSolvTools/src/DiagSolvTool.h
+++ b/Alignment/AlignSolvTools/src/DiagSolvToolBase.h
@@ -8,37 +8,34 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// $Id: DiagSolvTool.h,v 1.11 2010-03-02 15:55:26 wouter Exp $
-#ifndef ALIGNSOLVTOOLS_DIAGSOLVTOOL_H
-#define ALIGNSOLVTOOLS_DIAGSOLVTOOL_H 1
+#pragma once
 
 // Include files
 // from Gaudi
 #include "AlignmentInterfaces/IAlignSolvTool.h" // Interface
 #include "GaudiAlg/GaudiTool.h"
 
-class AlSymMat;
-class AlMat;
-class AlVec;
-
 /** @class DiagSolvTool DiagSolvTool.h AlignSolvTools/DiagSolvTool.h
  *
  *
  *  @author Adlene Hicheur
  *  @date   2007-06
  */
-class DiagSolvTool : public GaudiTool, virtual public IAlignSolvTool {
+
+class DiagSolvToolBase : public extends<GaudiTool, IAlignSolvTool> {
 public:
   /// Standard constructor
-  DiagSolvTool( const std::string& type, const std::string& name, const IInterface* parent );
-
-  virtual ~DiagSolvTool(); ///< Destructor
+  using extends::extends;
 
   using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
+
   ///< Call method to compute the solution, get symetric
   /// matrix and vector in input and replaces them by
   /// inverse matrix and solution vector in output.
-  bool compute( AlSymMat&, AlVec& ) const override;
+  StatusCode compute( AlSymMat& A, AlVec& b ) const override {
+    IAlignSolvTool::SolutionInfo info;
+    return compute( A, b, info );
+  }
 
   // Solves the system Ax=b for x. Return A=A^{-1} and
   // b=x. Furthermore, returns the total chi2 (b^T*A^{-1}*b) and the
@@ -46,19 +43,16 @@ public:
   StatusCode compute( AlSymMat& A, AlVec& b, IAlignSolvTool::SolutionInfo& ) const override;
 
   StatusCode initialize() override;
-  // enum Solver {SPMINV,
-  //               DIAG,
-  //             MINRES};
 
-protected:
-private:
-  // parameters
-  size_t m_numberOfPrintedEigenvalues;
-  bool   m_applyScaling;
-  double m_eigenValueThreshold;
-  double m_minEigenModeChisquare;
+  // Diagonalizes A symmetric matrix A such that A = U D V^T
+  // * S is the vector with eigenvalues, the diagonal elements of D
+  // * the columns of U are the eigen vectors of A
+  // * for symmetric matrices a solution exists for which V=U, but ... both Eigen and Gsl do not obey that!
+  virtual StatusCode diagonalize( const AlSymMat& A, AlMat& U, AlMat& V, AlVec& S ) const = 0;
 
-  void MonitorDiag( AlMat& z, AlVec& w, AlVec& D, double scale );
-  int  SolvMinRes( AlSymMat& m_bigmatrix, AlVec& m_bigvector, AlVec& result );
+protected:
+  Gaudi::Property<size_t> m_numberOfPrintedEigenvalues{this, "NumberOfPrintedEigenvalues", 20};
+  Gaudi::Property<double> m_eigenValueThreshold{this, "EigenValueThreshold", -1};
+  Gaudi::Property<bool>   m_applyScaling{this, "ApplyScaling", false};
+  Gaudi::Property<double> m_minEigenModeChisquare{this, "MinEigenModeChisquare", -1};
 };
-#endif // ALIGNSOLVTOOLS_ALIGNSOLVTOOL_H
diff --git a/Alignment/AlignSolvTools/src/EigenDiagSolvTool.cpp b/Alignment/AlignSolvTools/src/EigenDiagSolvTool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55a162cc52200be2e5d270bca05b8894ef5154ee
--- /dev/null
+++ b/Alignment/AlignSolvTools/src/EigenDiagSolvTool.cpp
@@ -0,0 +1,35 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+// Include files
+
+#include "DiagSolvToolBase.h"
+
+class EigenDiagSolvTool : public DiagSolvToolBase {
+public:
+  using DiagSolvToolBase::DiagSolvToolBase;
+
+  using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
+
+  StatusCode diagonalize( const AlSymMat& A, AlMat& U, AlMat& V, AlVec& S ) const override;
+};
+
+// Declaration of the Tool Factory
+DECLARE_COMPONENT( EigenDiagSolvTool )
+
+StatusCode EigenDiagSolvTool::diagonalize( const AlSymMat& A, AlMat& U, AlMat& V, AlVec& S ) const {
+  // There are several options in Eigen. We just start with one.
+  Eigen::MatrixXd                eigenA = A.toMatrix();
+  Eigen::BDCSVD<Eigen::MatrixXd> svdcalculator{eigenA, Eigen::ComputeFullU | Eigen::ComputeFullV};
+  S = svdcalculator.singularValues();
+  U = svdcalculator.matrixU();
+  V = svdcalculator.matrixV();
+  return StatusCode::SUCCESS;
+}
diff --git a/Alignment/AlignSolvTools/src/GslDiagSolvTool.cpp b/Alignment/AlignSolvTools/src/GslDiagSolvTool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c693e46031ad9663c62c225e83f88764edbdd948
--- /dev/null
+++ b/Alignment/AlignSolvTools/src/GslDiagSolvTool.cpp
@@ -0,0 +1,117 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+// Include files
+
+#include <cmath>
+
+// from GSL
+#include "gsl/gsl_linalg.h"
+
+// Interface
+#include "DiagSolvToolBase.h"
+
+class GslDiagSolvTool : public DiagSolvToolBase {
+public:
+  using DiagSolvToolBase::DiagSolvToolBase;
+
+  using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
+
+  StatusCode diagonalize( const AlSymMat& A, AlMat& U, AlMat& V, AlVec& S ) const override;
+
+private:
+  Gaudi::Property<bool> m_svdJacobi{this, "SVDJacobi", false}; ///< Use Jacobi SVD?
+};
+
+// Declaration of the Tool Factory
+DECLARE_COMPONENT( GslDiagSolvTool )
+
+/*
+namespace {
+
+  std::ostream& operator<<( std::ostream& lhs, const gsl_vector& rhs ) {
+    lhs << std::endl;
+    lhs << "[ " << std::endl;
+    for ( unsigned i = 0u; i < rhs.size; ++i ) {
+      lhs << " " << ( *gsl_vector_const_ptr( &rhs, i ) ) << " ";
+      lhs << std::endl;
+    }
+    lhs << " ]" << std::endl;
+    return lhs;
+  }
+
+  std::ostream& operator<<( std::ostream& lhs, const gsl_matrix& rhs ) {
+    lhs << std::endl;
+    lhs << "[ " << std::endl;
+    for ( unsigned i = 0u; i < rhs.size1; ++i ) {
+      for ( unsigned j = 0u; j < rhs.size2; ++j ) { lhs << " " << ( *gsl_matrix_const_ptr( &rhs, i, j ) ) << " "; }
+      lhs << std::endl;
+    }
+    lhs << " ]" << std::endl;
+    return lhs;
+  }
+} // namespace
+*/
+
+StatusCode GslDiagSolvTool::diagonalize( const AlSymMat& A, AlMat& U, AlMat& V, AlVec& S ) const {
+
+  const auto N = A.rows();
+
+  debug() << "Size of AlSymMat A = " << N << endmsg;
+  /// Allocate matrix A
+  gsl_matrix* matrixA = gsl_matrix_alloc( N, N );
+  debug() << "Size of gsl_matrix A = " << matrixA->size1 << endmsg;
+  /// Fill matrix A
+  for ( unsigned i = 0u; i < N; ++i ) {
+    for ( unsigned j = 0u; j < N; ++j ) {
+      debug() << "Element (i,j) of AlSymMat A = " << A( i, j ) << endmsg;
+      gsl_matrix_set( matrixA, i, j, A( i, j ) );
+      debug() << "Element (i,j) of gsl_matrix A = " << gsl_matrix_get( matrixA, i, j ) << endmsg;
+    }
+  }
+
+  /// Allocate required matrix, vector and workspace
+  gsl_matrix* matrixV = gsl_matrix_alloc( N, N );
+  gsl_vector* vectorS = gsl_vector_alloc( N );
+  gsl_vector* vectorW = gsl_vector_alloc( N );
+  // gsl_matrix* matrixU = matrixA ;
+
+  debug() << "Factorising matrix A" << endmsg;
+  /// Factorise A into the SVD A = USV^T. Note matrix A is replaced with matrix U.
+  /// GSL returns 0 if successful
+  int factorised = 1;
+  if ( !m_svdJacobi.value() ) {
+    info() << "==> SVD standard" << endmsg;
+    factorised = gsl_linalg_SV_decomp( matrixA, matrixV, vectorS, vectorW );
+  } else {
+    info() << "==> SVD Jacobi" << endmsg;
+    factorised = gsl_linalg_SV_decomp_jacobi( matrixA, matrixV, vectorS );
+  }
+  if ( factorised != 0 ) {
+    error() << "==> Couldn't factorise  matrix" << endmsg;
+    return StatusCode::FAILURE;
+  }
+  debug() << "Done factorising matrix A" << endmsg;
+
+  //
+  for ( size_t irow = 0; irow < N; ++irow ) S( irow ) = gsl_vector_get( vectorS, irow );
+  for ( size_t irow = 0; irow < N; ++irow )
+    for ( size_t icol = 0; icol < N; ++icol ) {
+      U( irow, icol ) = gsl_matrix_get( matrixA, irow, icol );
+      V( irow, icol ) = gsl_matrix_get( matrixV, irow, icol );
+    }
+
+  gsl_matrix_free( matrixA );
+  gsl_matrix_free( matrixV );
+  gsl_vector_free( vectorS );
+  gsl_vector_free( vectorW );
+
+  return StatusCode::SUCCESS;
+}
diff --git a/Alignment/AlignSolvTools/src/SolvExample.cpp b/Alignment/AlignSolvTools/src/SolvExample.cpp
index 1ecc435d220435678af36b9129a652f469198b9c..c20e7174075756b1902283e08c5c846fa9e80b3d 100755
--- a/Alignment/AlignSolvTools/src/SolvExample.cpp
+++ b/Alignment/AlignSolvTools/src/SolvExample.cpp
@@ -8,15 +8,6 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
-
-// local
-#include "SolvExample.h"
-
-// Matrix, vector classes
-#include "AlignKernel/AlMat.h"
-#include "AlignKernel/AlSymMat.h"
-#include "AlignKernel/AlVec.h"
 
 //-----------------------------------------------------------------------------
 // Implementation file for class : SolvExample
@@ -24,35 +15,32 @@
 // 2007-03-07 : Adlene Hicheur
 //-----------------------------------------------------------------------------
 
-// Declaration of the Algorithm Factory
-DECLARE_COMPONENT( SolvExample )
+// Include files
+// from Gaudi
+#include "GaudiAlg/GaudiAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
 
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-SolvExample::SolvExample( const std::string& name, ISvcLocator* pSvcLocator ) : GaudiAlgorithm( name, pSvcLocator ) {
-  declareProperty( "SolvMethod", m_solvtoolname = "SpmInvTool" );
-}
-//=============================================================================
-// Destructor
-//=============================================================================
-SolvExample::~SolvExample() {}
+// Solver
+#include "AlignmentInterfaces/IAlignSolvTool.h"
 
-//=============================================================================
-// Initialization
-//=============================================================================
-StatusCode SolvExample::initialize() {
-  StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first
-  if ( sc.isFailure() ) return sc;              // error printed already by GaudiAlgorithm
+class IAlignSolvTool;
 
-  // solver tool
+class SolvExample : public GaudiAlgorithm {
+public:
+  /// Standard constructor
+  using GaudiAlgorithm::GaudiAlgorithm;
+  StatusCode execute() override; ///< Algorithm execution
+private:
+  ToolHandle<IAlignSolvTool> m_solver{this, "SolvMethod", "SpmInvTool"};
+};
 
-  m_solver = tool<IAlignSolvTool>( m_solvtoolname );
-
-  debug() << "==> Initialize" << endmsg;
+// Matrix, vector classes
+#include "AlignKernel/AlMat.h"
+#include "AlignKernel/AlSymMat.h"
+#include "AlignKernel/AlVec.h"
 
-  return StatusCode::SUCCESS;
-}
+// Declaration of the Algorithm Factory
+DECLARE_COMPONENT( SolvExample )
 
 //=============================================================================
 // Main execution
@@ -75,7 +63,7 @@ StatusCode SolvExample::execute() {
   }
   b -= c;
 
-  debug() << "scalar product c*d..." << ( b * c ) << endmsg;
+  debug() << "scalar product c*d..." << b.dot( c ) << endmsg;
 
   AlSymMat md( Nvec );
   AlSymMat ma( Nvec );
@@ -83,9 +71,9 @@ StatusCode SolvExample::execute() {
   for ( unsigned i = 0; i < md.size(); ++i ) {
     debug() << "AlSymMat md values line " << i << " -- ";
     for ( unsigned j = 0; j <= i; ++j ) {
-      md[i][j] = i - j;
-      if ( i == j ) ma[i][j] = 3;
-      debug() << md[i][j] << " - ";
+      md( i, j ) = i - j;
+      if ( i == j ) ma( i, j ) = 3;
+      debug() << md( i, j ) << " - ";
     }
     debug() << "finish line" << endmsg;
   }
@@ -98,12 +86,11 @@ StatusCode SolvExample::execute() {
 
   for ( unsigned i = 0; i < mdT.size(); ++i ) {
     debug() << "AlSymMat mdT values line " << i << " -- ";
-    for ( unsigned j = 0; j < mdT.size(); ++j ) { debug() << mdT[i][j] << " - "; }
+    for ( unsigned j = 0; j < mdT.size(); ++j ) { debug() << mdT( i, j ) << " - "; }
     debug() << endmsg;
   }
 
-  AlVec e;
-  e = md * c;
+  AlVec e = md * c;
   debug() << "md*c Nelem..." << e.size() << endmsg;
   debug() << "md*c values..." << endmsg;
   for ( unsigned i = 0; i < e.size(); ++i ) debug() << e[i] << " - ";
@@ -113,32 +100,32 @@ StatusCode SolvExample::execute() {
   AlMat mk = ma * me;
   AlMat mj = me * ma;
 
-  for ( size_t i = 0; i < me.nrow(); i++ ) {
+  for ( auto i = 0; i < me.rows(); i++ ) {
     debug() << "AlMat me values line " << i << " -- ";
-    for ( size_t j = 0; j < me.ncol(); j++ ) { debug() << me[i][j] << " - "; }
+    for ( auto j = 0; j < me.cols(); j++ ) { debug() << me( i, j ) << " - "; }
     debug() << endmsg;
   }
 
-  for ( size_t i = 0; i < mk.nrow(); i++ ) {
+  for ( auto i = 0; i < mk.rows(); i++ ) {
     debug() << "AlSymMat*AlMat mk=ma*me values line " << i << " -- ";
-    for ( size_t j = 0; j < mk.ncol(); j++ ) { debug() << mk[i][j] << " - "; }
+    for ( auto j = 0; j < mk.cols(); j++ ) { debug() << mk( i, j ) << " - "; }
     debug() << endmsg;
   }
 
-  for ( size_t i = 0; i < mj.nrow(); i++ ) {
+  for ( auto i = 0; i < mj.rows(); i++ ) {
     debug() << "AlMat*AlSymMat mj=me*ma values line " << i << " -- ";
-    for ( size_t j = 0; j < mj.ncol(); j++ ) { debug() << mj[i][j] << " - "; }
+    for ( auto j = 0; j < mj.cols(); j++ ) { debug() << mj( i, j ) << " - "; }
     debug() << endmsg;
   }
 
   me *= 5.;
-  AlSymMat mf( me.nrow() );
+  AlSymMat mf( me.rows() );
 
-  for ( size_t i = 0; i < me.nrow(); i++ ) {
+  for ( auto i = 0; i < me.rows(); i++ ) {
     debug() << "AlMat me*5 values line " << i << " -- ";
-    for ( size_t j = 0; j < me.ncol(); j++ ) {
-      debug() << me[i][j] << " - ";
-      mf[i][j] = me[i][j];
+    for ( auto j = 0; j < me.cols(); j++ ) {
+      debug() << me( i, j ) << " - ";
+      mf( i, j ) = me( i, j );
     }
     debug() << endmsg;
   }
@@ -150,7 +137,7 @@ StatusCode SolvExample::execute() {
 
   int ierr = 0;
 
-  mf.invert( ierr );
+  // mf.invert(ierr);
 
   if ( ierr == 0 ) {
 
@@ -158,32 +145,30 @@ StatusCode SolvExample::execute() {
 
     for ( unsigned i = 0; i < mf.size(); ++i ) {
       debug() << "AlSymMat mf values line " << i << " -- ";
-      for ( unsigned j = 0; j < mf.size(); ++j ) { debug() << mf[i][j] << " - "; }
+      for ( unsigned j = 0; j < mf.size(); ++j ) { debug() << mf( i, j ) << " - "; }
       debug() << endmsg;
     }
 
     debug() << "AlSymMat me*me^-1 values line " << endmsg;
 
-    for ( size_t i = 0; i < ( mf * mfi ).nrow(); i++ ) {
+    for ( auto i = 0; i < ( mf * mfi ).rows(); i++ ) {
       debug() << "AlSymMat me*me^-1 values line " << i << " -- ";
-      for ( size_t j = 0; j < ( mf * mfi ).ncol(); j++ ) { debug() << ( mf * mfi )[i][j] << " - "; }
+      for ( auto j = 0; j < ( mf * mfi ).cols(); j++ ) { debug() << ( mf * mfi )( i, j ) << " - "; }
       debug() << endmsg;
     }
   }
 
   debug() << "Now using indirect inversion via diagonalization..." << endmsg;
 
-  int  info = 999;
-  char jobz = 'V';
   // declare transition matrix + vector to store eigenvalues
-  size_t dim = mf.size();
+  const size_t dim = mf.size();
 
   AlMat z( dim, dim );
   AlVec w( dim );
 
   AlSymMat mfi_bis( mfi );
 
-  info = mfi.diagonalize( jobz, w, z );
+  const auto info = mfi.diagonalize_GSL( w, z );
 
   if ( info == 0 ) {
     debug() << "*** successful diagonalization ***" << endmsg;
@@ -192,7 +177,7 @@ StatusCode SolvExample::execute() {
     for ( unsigned i = 0; i < invmat.size(); ++i ) {
       debug() << w[i] << "  " << endmsg;
       for ( unsigned j = 0; j <= i; ++j ) {
-        for ( size_t k = 0; k < dim; k++ ) invmat[i][j] = invmat[i][j] + ( z[k][i] * z[k][j] / w[k] );
+        for ( size_t k = 0; k < dim; k++ ) invmat( i, j ) = invmat( i, j ) + ( z( k, i ) * z( k, j ) / w[k] );
       }
     }
 
@@ -200,30 +185,17 @@ StatusCode SolvExample::execute() {
 
     for ( unsigned i = 0; i < invmat.size(); ++i ) {
       //    debug()<<"AlSymMat me*me^-1 values line "<<i<<" -- ";
-      for ( unsigned j = 0; j < invmat.size(); ++j ) { debug() << ( me * invmat )[i][j] << "   "; }
+      for ( unsigned j = 0; j < invmat.size(); ++j ) { debug() << ( me * invmat )( i, j ) << "   "; }
       debug() << endmsg;
     }
   }
 
   // Calling the solver
 
-  m_solver->compute( mf, e );
+  m_solver->compute( mf, e ).ignore();
   debug() << "Printing solution of mf*X = e..." << endmsg;
   for ( unsigned i = 0; i < e.size(); ++i ) debug() << e[i] << " - ";
   debug() << endmsg;
 
   return StatusCode::SUCCESS;
 }
-
-//=============================================================================
-//  Finalize
-//=============================================================================
-StatusCode SolvExample::finalize() {
-
-  debug() << "==> Finalize" << endmsg;
-  // finalize the tool to close it properly
-  m_solver->finalize().ignore();
-  return GaudiAlgorithm::finalize(); // must be called after all other actions
-}
-
-//=============================================================================
diff --git a/Alignment/AlignSolvTools/src/SparseSolver.cpp b/Alignment/AlignSolvTools/src/SparseSolver.cpp
index 2ec4b5aad7ea9b1bd6f386a4f5075fe649e3416b..55edeb58120d94170e596dee392866db8eb25948 100644
--- a/Alignment/AlignSolvTools/src/SparseSolver.cpp
+++ b/Alignment/AlignSolvTools/src/SparseSolver.cpp
@@ -23,17 +23,15 @@
  *  @date   2007-07-24
  */
 
-class SparseSolver : public GaudiTool, virtual public IAlignSolvTool {
+class SparseSolver : public extends<GaudiTool, IAlignSolvTool> {
 
 public:
   /// Standard constructor
-  SparseSolver( const std::string& type, const std::string& name, const IInterface* parent );
-
-  virtual ~SparseSolver(); ///< Destructor
+  using extends::extends;
 
   using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
-  /// Solves Ax = b using gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, gsl_vector * work)
-  bool compute( AlSymMat& symMatrix, AlVec& vector ) const override;
+  /// Solves Ax = b
+  StatusCode compute( AlSymMat& symMatrix, AlVec& vector ) const override;
 
 private:
 };
@@ -52,19 +50,7 @@ DECLARE_COMPONENT( SparseSolver )
 #include "TMatrixDSym.h"
 #include "TVectorD.h"
 
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-SparseSolver::SparseSolver( const std::string& type, const std::string& name, const IInterface* parent )
-    : GaudiTool( type, name, parent ) {
-  declareInterface<IAlignSolvTool>( this );
-}
-//=============================================================================
-// Destructor
-//=============================================================================
-SparseSolver::~SparseSolver() {}
-
-bool SparseSolver::compute( AlSymMat& symMatrix, AlVec& vector ) const {
+StatusCode SparseSolver::compute( AlSymMat& symMatrix, AlVec& vector ) const {
   // create a sparce matrix. I think that this is most efficient via
   // TMatrix, because the structure of the TSparseMatrix isn't
   // entirely self evident.
@@ -98,5 +84,5 @@ bool SparseSolver::compute( AlSymMat& symMatrix, AlVec& vector ) const {
     tmp.fast( irow, irow ) = c != 0 ? 1 / c : 0;
   }
   symMatrix = tmp;
-  return ierr ? false : true;
+  return ierr ? StatusCode::FAILURE : StatusCode::SUCCESS;
 }
diff --git a/Alignment/AlignSolvTools/src/SpmInvTool.cpp b/Alignment/AlignSolvTools/src/SpmInvTool.cpp
index 99bdc222da1ac74da5cb3cc31e7655fa78c338cb..5aa56e8603f0e32c71c5fdc53d4f638621bedd17 100755
--- a/Alignment/AlignSolvTools/src/SpmInvTool.cpp
+++ b/Alignment/AlignSolvTools/src/SpmInvTool.cpp
@@ -8,87 +8,78 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files
+/** @class SpmInvTool SpmInvTool.cpp AlignSolvTools/SpmInvTool.cpp
+ *
+ *
+ *  @author Adlene Hicheur
+ *  @date   2007-06
+ */
 
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <math.h>
-#include <stdio.h>
-#include <string>
+// Include files
+#include <vector>
 
 // from Gaudi
-#include "GaudiKernel/INTupleSvc.h"
-#include "GaudiKernel/NTuple.h"
-#include "GaudiKernel/SmartDataPtr.h"
+#include "GaudiAlg/GaudiTool.h"
+
+// Interface
+#include "AlignmentInterfaces/IAlignSolvTool.h"
+
+class SpmInvTool : public extends<GaudiTool, IAlignSolvTool> {
+public:
+  /// Standard constructor
+  using extends::extends;
+
+  using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
+  // Call method to compute the solution, get symetric matrix and
+  // vector in input and replaces them by inverse matrix and solution vector in output.
+  StatusCode compute( AlSymMat&, AlVec& ) const override;
 
-// local
-#include "SpmInvTool.h"
+private:
+  // parameters
 
-//-----------------------------------------------------------------------------
-// Implementation file for class : SpmInvTool
-//
-// 2007-06 : Adlene Hicheur
-//-----------------------------------------------------------------------------
+  int SolvSpmInv( AlSymMat& M, AlVec& B );
+
+  void Precond( AlSymMat& M, AlVec& r, AlVec& c, bool equIn );
+};
 
 // Declaration of the Tool Factory
 DECLARE_COMPONENT( SpmInvTool )
 
-//=============================================================================
-// Standard constructor, initializes variables
-//=============================================================================
-SpmInvTool::SpmInvTool( const std::string& type, const std::string& name, const IInterface* parent )
-    : GaudiTool( type, name, parent ) {
-  declareInterface<IAlignSolvTool>( this );
-}
-//=============================================================================
-// Destructor
-//=============================================================================
-SpmInvTool::~SpmInvTool() {}
-
 //=============================================================================
 
-bool SpmInvTool::compute( AlSymMat& m, AlVec& b ) const {
+StatusCode SpmInvTool::compute( AlSymMat& m, AlVec& b ) const {
   if ( m.size() > 0 ) {
     const_cast<SpmInvTool*>( this )->SolvSpmInv( m, b );
-    return true;
+    return StatusCode::SUCCESS;
   } else {
     error() << "Error, null matrix size, don't call the solving!" << endmsg;
-    return false;
+    return StatusCode::FAILURE;
   }
 }
 
 int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
 
-  AlMat V( M.size(), M.size() );
-  V.copyS( M );
+  AlMat V = M.toMatrix();
 
   int N = M.size();
 
-  AlVec diag( N );
-  bool* flag = new bool[N];
+  AlVec             diag( N );
+  std::vector<bool> flag( N, true );
 
   int    i, j, jj, k, nrank;
   double vkk;
   double eps = 1e-16;
 
-  AlVec r( N );
-  AlVec c( N );
-
-  AlVec temp( N );
-
-  for ( i = 0; i < N; i++ ) {
-    flag[i] = true;
-
-    //   for (j=0; j<=i; j++) {if (V[j][i] == 0) {V[j][i] = V[i][j];}}
-  }
+  AlVec r{N};
+  AlVec c{N};
+  AlVec temp{N};
 
   // Small loop for matrix equilibration (gives a better conditioning)
 
   for ( i = 0; i < N; i++ ) {
     for ( j = 0; j < N; j++ ) {
-      if ( fabs( V[i][j] ) >= r[i] ) r[i] = fabs( V[i][j] ); // Max elemt of row i
-      if ( fabs( V[j][i] ) >= c[i] ) c[i] = fabs( V[j][i] ); // Max elemt of column i
+      if ( fabs( V( i, j ) ) >= r[i] ) r[i] = fabs( V( i, j ) ); // Max elemt of row i
+      if ( fabs( V( j, i ) ) >= c[i] ) c[i] = fabs( V( j, i ) ); // Max elemt of column i
     }
   }
   for ( i = 0; i < N; i++ ) {
@@ -98,13 +89,13 @@ int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
 
   for ( i = 0; i < N; i++ ) // Equilibrate the V matrix
   {
-    for ( j = 0; j < N; j++ ) { V[i][j] = sqrt( r[i] ) * V[i][j] * sqrt( c[j] ); }
+    for ( j = 0; j < N; j++ ) { V( i, j ) = sqrt( r[i] ) * V( i, j ) * sqrt( c[j] ); }
   }
 
   nrank = 0;
 
   // save diagonal elem absolute values
-  for ( i = 0; i < N; i++ ) { diag[i] = fabs( V[i][i] ); }
+  for ( i = 0; i < N; i++ ) { diag[i] = fabs( V( i, i ) ); }
 
   for ( i = 0; i < N; i++ ) {
     vkk = 0.0;
@@ -112,8 +103,8 @@ int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
 
     for ( j = 0; j < N; j++ ) // First look for the pivot, ie max unused diagonal element
     {
-      if ( flag[j] && ( fabs( V[j][j] ) > std::max( fabs( vkk ), eps * diag[j] ) ) ) {
-        vkk = V[j][j];
+      if ( flag[j] && ( fabs( V( j, j ) ) > std::max( fabs( vkk ), eps * diag[j] ) ) ) {
+        vkk = V( j, j );
         k   = j;
       }
     }
@@ -122,16 +113,16 @@ int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
     {
       debug() << "Pivot value :" << vkk << endmsg;
       nrank++;
-      flag[k] = false; // This value is used
-      vkk     = 1.0 / vkk;
-      V[k][k] = -vkk; // Replace pivot by its inverse
+      flag[k]   = false; // This value is used
+      vkk       = 1.0 / vkk;
+      V( k, k ) = -vkk; // Replace pivot by its inverse
 
       for ( j = 0; j < N; j++ ) {
         for ( jj = 0; jj < N; jj++ ) {
           if ( j != k && jj != k ) // Other elements (!!! do them first as you use old Vk][j]'s !!!)
           {
-            V[j][jj] = V[j][jj] - vkk * V[j][k] * V[k][jj];
-            //    V[j][jj] = V[j][jj] + vkk*V[j][k]*V[k][jj];
+            V( j, jj ) = V( j, jj ) - vkk * V( j, k ) * V( k, jj );
+            //    V(j,jj) = V(j,jj) + vkk*V(j,k)*V(k,jj);
           }
         }
       }
@@ -139,8 +130,8 @@ int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
       for ( j = 0; j < N; j++ ) {
         if ( j != k ) // Pivot row or column elements
         {
-          V[j][k] = ( V[j][k] ) * vkk; // Column
-          V[k][j] = ( V[k][j] ) * vkk; // Line
+          V( j, k ) = ( V( j, k ) ) * vkk; // Column
+          V( k, j ) = ( V( k, j ) ) * vkk; // Line
         }
       }
     } else // No more pivot value (clear those elements)
@@ -150,7 +141,7 @@ int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
           B[j] = 0.0;
 
           for ( k = 0; k <= j; k++ ) {
-            V[j][k] = 0.0;
+            V( j, k ) = 0.0;
             //           V[k][j] = 0.0;
           }
         }
@@ -161,7 +152,7 @@ int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
   }
   for ( i = 0; i < N; i++ ) // Correct matrix V
   {
-    for ( j = 0; j < N; j++ ) { V[i][j] = sqrt( c[i] ) * V[i][j] * sqrt( r[j] ); }
+    for ( j = 0; j < N; j++ ) { V( i, j ) = sqrt( c[i] ) * V( i, j ) * sqrt( r[j] ); }
   }
 
   for ( j = 0; j < N; j++ ) {
@@ -169,23 +160,20 @@ int SpmInvTool::SolvSpmInv( AlSymMat& M, AlVec& B ) {
 
     for ( jj = 0; jj < N; jj++ ) // Reverse matrix elements
     {
-      V[j][jj] = -V[j][jj];
-      M[j][jj] = V[j][jj];
-      temp[j] += V[j][jj] * B[jj];
+      V( j, jj ) = -V( j, jj );
+      M( j, jj ) = V( j, jj );
+      temp[j] += V( j, jj ) * B[jj];
     }
   }
 
   for ( j = 0; j < N; j++ ) { B[j] = temp[j]; } // The final result
-  delete[] flag;
   return nrank;
 }
 
 // Routine to equilibrate the matrix for better conditioning
 
 void SpmInvTool::Precond( AlSymMat& M, AlVec& r, AlVec& c, bool equIn = true ) {
-
-  AlMat V( M.size(), M.size() );
-  V.copyS( M );
+  AlMat V = M.toMatrix();
 
   int N = M.size();
 
@@ -199,8 +187,8 @@ void SpmInvTool::Precond( AlSymMat& M, AlVec& r, AlVec& c, bool equIn = true ) {
 
     for ( i = 0; i < N; i++ ) {
       for ( j = 0; j < N; j++ ) {
-        if ( fabs( V[i][j] ) >= r[i] ) r[i] = fabs( V[i][j] ); // Max elemt of row i
-        if ( fabs( V[j][i] ) >= c[i] ) c[i] = fabs( V[j][i] ); // Max elemt of column i
+        if ( fabs( V( i, j ) ) >= r[i] ) r[i] = fabs( V( i, j ) ); // Max elemt of row i
+        if ( fabs( V( j, i ) ) >= c[i] ) c[i] = fabs( V( j, i ) ); // Max elemt of column i
       }
     }
 
@@ -213,8 +201,8 @@ void SpmInvTool::Precond( AlSymMat& M, AlVec& r, AlVec& c, bool equIn = true ) {
     {
       for ( j = 0; j < N; j++ ) {
 
-        V[i][j] = r[i] * V[i][j] * c[j];
-        M[i][j] = V[i][j];
+        V( i, j ) = r[i] * V( i, j ) * c[j];
+        M( i, j ) = V( i, j );
       }
     }
 
@@ -224,8 +212,8 @@ void SpmInvTool::Precond( AlSymMat& M, AlVec& r, AlVec& c, bool equIn = true ) {
     {
       for ( j = 0; j < N; j++ ) {
 
-        V[i][j] = c[i] * V[i][j] * r[j];
-        M[i][j] = V[i][j];
+        V( i, j ) = c[i] * V( i, j ) * r[j];
+        M( i, j ) = V( i, j );
       }
     }
   }
diff --git a/Alignment/AlignSolvTools/src/SpmInvTool.h b/Alignment/AlignSolvTools/src/SpmInvTool.h
deleted file mode 100755
index b94aee5ab440bdaf0af8107ebc524c1ab9bd9355..0000000000000000000000000000000000000000
--- a/Alignment/AlignSolvTools/src/SpmInvTool.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-// $Id: SpmInvTool.h,v 1.4 2009-08-16 14:16:24 wouter Exp $
-#ifndef ALIGNSOLVTOOLS_SPMINVTOOL_H
-#define ALIGNSOLVTOOLS_SPMINVTOOL_H 1
-
-// Include files
-// from Gaudi
-#include "GaudiAlg/GaudiTool.h"
-
-// Interface
-#include "AlignmentInterfaces/IAlignSolvTool.h"
-
-/** @class SpmInvTool SpmInvTool.h AlignSolvTools/SpmInvTool.h
- *
- *
- *  @author Adlene Hicheur
- *  @date   2007-06
- */
-
-class SpmInvTool : public GaudiTool, virtual public IAlignSolvTool {
-public:
-  /// Standard constructor
-  SpmInvTool( const std::string& type, const std::string& name, const IInterface* parent );
-
-  virtual ~SpmInvTool(); ///< Destructor
-
-  using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
-  // Call method to compute the solution, get symetric matrix and
-  // vector in input and replaces them by inverse matrix and solution vector in output.
-  bool compute( AlSymMat&, AlVec& ) const override;
-
-protected:
-private:
-  // parameters
-
-  int SolvSpmInv( AlSymMat& M, AlVec& B );
-
-  void Precond( AlSymMat& M, AlVec& r, AlVec& c, bool equIn );
-};
-#endif // ALIGNSOLVTOOLS_ALIGNSOLVTOOL_H
diff --git a/Alignment/AlignSolvTools/src/gslSVDsolver.cpp b/Alignment/AlignSolvTools/src/gslSVDsolver.cpp
index 297c747bee14274becef082cf0219178e225f1ff..b15eed9aa69f75fc4f3dfe8cfbb350ec00812193 100755
--- a/Alignment/AlignSolvTools/src/gslSVDsolver.cpp
+++ b/Alignment/AlignSolvTools/src/gslSVDsolver.cpp
@@ -1,5 +1,5 @@
 /*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration      *
 *                                                                             *
 * This software is distributed under the terms of the GNU General Public      *
 * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
@@ -12,12 +12,55 @@
 
 #include <cmath>
 
-// local
-#include "gslSVDsolver.h"
+// Include files
+// from Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+// from GSL
+#include "gsl/gsl_linalg.h"
+
+// Interface
+#include "AlignmentInterfaces/IAlignSolvTool.h"
+
+/** @class gslSVDsolver gslSVDsolver.h
+ *
+ *
+ *  @author Jan Amoraal
+ *  @date   2007-07-24
+ */
+
+class gslSVDsolver : public GaudiTool, virtual public IAlignSolvTool {
+
+public:
+  /// Standard constructor
+  gslSVDsolver( const std::string& type, const std::string& name, const IInterface* parent );
+
+  virtual ~gslSVDsolver(); ///< Destructor
+
+  using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
+  /// Solves Ax = b using gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, gsl_vector * work)
+  StatusCode compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector ) const override;
+
+  StatusCode compute( AlSymMat& symMatrix, AlVec& vector ) const override {
+    AlVec dummy( vector.size() );
+    return compute( symMatrix, vector, dummy );
+  }
+
+protected:
+private:
+  bool         m_svdJacobi;  ///< Use Jacobi SVD?
+  double       m_svdEpsilon; ///< SVD threshold. The singular values are stored in gsl_vector S.
+  unsigned int m_nZero;      ///< remove the n smallest eigenvalues
+  double       m_eigenValueThreshold;
+  size_t       m_numberOfPrintedEigenvalues;
+};
 
 //-----------------------------------------------------------------------------
 // Implementation file for class : gslSVDsolver
 //
+// See also
+//  http://home.thep.lu.se/~jari/documents/gsl-ref.html/Singular-Value-Decomposition.html
+//
 // 2007-07-24 : Jan Amoraal
 //-----------------------------------------------------------------------------
 
@@ -41,7 +84,7 @@ gslSVDsolver::gslSVDsolver( const std::string& type, const std::string& name, co
 //=============================================================================
 gslSVDsolver::~gslSVDsolver() {}
 
-bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector ) const {
+StatusCode gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector ) const {
 
   size_t size = symMatrix.size();
 
@@ -52,8 +95,8 @@ bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector
   /// Fill matrix A
   for ( unsigned i = 0u; i < size; ++i ) {
     for ( unsigned j = 0u; j < size; ++j ) {
-      debug() << "Element (i,j) of AlSymMat A = " << symMatrix[i][j] << endmsg;
-      gsl_matrix_set( matrixA, i, j, symMatrix[i][j] );
+      debug() << "Element (i,j) of AlSymMat A = " << symMatrix( i, j ) << endmsg;
+      gsl_matrix_set( matrixA, i, j, symMatrix( i, j ) );
       debug() << "Element (i,j) of gsl_matrix A = " << gsl_matrix_get( matrixA, i, j ) << endmsg;
     }
   }
@@ -64,8 +107,6 @@ bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector
   gsl_vector* vectorW = gsl_vector_alloc( size );
   gsl_matrix* matrixU = matrixA;
 
-  debug() << "==> Matrix A  = " << ( *matrixA ) << endmsg;
-
   debug() << "Factorising matrix A" << endmsg;
   /// Factorise A into the SVD A = USV^T. Note matrix A is replaced with matrix U.
   /// GSL returns 0 if successful
@@ -79,14 +120,10 @@ bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector
   }
   if ( factorised != 0 ) {
     error() << "==> Couldn't factorise  matrix" << endmsg;
-    return false;
+    return StatusCode::FAILURE;
   }
   debug() << "Done factorising matrix A" << endmsg;
 
-  debug() << "==> Matrix U  = " << ( *matrixA ) << endmsg;
-  debug() << "==> Vector S  = " << ( *vectorS ) << endmsg;
-  debug() << "==> Matrix V  = " << ( *matrixV ) << endmsg;
-
   {
     // print the eigenvalues, but make sure to insert minus signs where needed
     std::vector<double> eigenvalues;
@@ -139,11 +176,10 @@ bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector
   }
 
   info() << "Number of removed eigenvalues = " << numremoved << endmsg;
-  debug() << "==> Regularised Vector S  = " << ( *vectorS ) << endmsg;
 
   // Replace symMatrix with its inverse (the covariance matrix)
   for ( unsigned irow = 0; irow < size; ++irow )
-    for ( unsigned int icol = 0; icol <= irow; ++icol ) symMatrix[irow][icol] = 0;
+    for ( unsigned int icol = 0; icol <= irow; ++icol ) symMatrix( irow, icol ) = 0;
   for ( unsigned int k = 0; k < size; ++k ) {
     double s = gsl_vector_get( vectorS, k );
     if ( s > 0 ) {
@@ -152,7 +188,7 @@ bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector
           // honestly: don't have a clue about the order of U and V
           // here, but they should be identical for our symmetric
           // systems
-          symMatrix[irow][icol] += gsl_matrix_get( matrixV, irow, k ) * gsl_matrix_get( matrixU, icol, k ) / s;
+          symMatrix( irow, icol ) += gsl_matrix_get( matrixV, irow, k ) * gsl_matrix_get( matrixU, icol, k ) / s;
         }
     }
   }
@@ -165,14 +201,12 @@ bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector
   int solved = gsl_linalg_SV_solve( matrixA, matrixV, vectorS, vectorB, vectorX );
   if ( solved != 0 ) {
     error() << "==> Couldn't solve system Ax=b" << endmsg;
-    return false;
+    return StatusCode::FAILURE;
   }
 
   /// Fill AlVec
   for ( unsigned i = 0; i < size; ++i ) vector[i] = ( *gsl_vector_const_ptr( vectorX, i ) );
 
-  debug() << "==> Vector x = " << ( *vectorX ) << endmsg;
-
   /// free gsl vector and matrices
   gsl_matrix_free( matrixA );
   gsl_matrix_free( matrixV );
@@ -181,7 +215,7 @@ bool gslSVDsolver::compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector
   gsl_vector_free( vectorB );
   gsl_vector_free( vectorX );
 
-  return true;
+  return StatusCode::SUCCESS;
 }
 
 //=============================================================================
diff --git a/Alignment/AlignSolvTools/src/gslSVDsolver.h b/Alignment/AlignSolvTools/src/gslSVDsolver.h
deleted file mode 100755
index 469f562fe039c5761403907163514bb17920ba4a..0000000000000000000000000000000000000000
--- a/Alignment/AlignSolvTools/src/gslSVDsolver.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
-*                                                                             *
-* This software is distributed under the terms of the GNU General Public      *
-* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
-*                                                                             *
-* In applying this licence, CERN does not waive the privileges and immunities *
-* granted to it by virtue of its status as an Intergovernmental Organization  *
-* or submit itself to any jurisdiction.                                       *
-\*****************************************************************************/
-// $Id: gslSVDsolver.h,v 1.9 2009-08-16 14:31:51 wouter Exp $
-#ifndef GSLSVDSOLVER_H
-#define GSLSVDSOLVER_H 1
-
-// Include files
-// from Gaudi
-#include "GaudiAlg/GaudiTool.h"
-
-// from GSL
-#include "gsl/gsl_linalg.h"
-
-// Interface
-#include "AlignmentInterfaces/IAlignSolvTool.h"
-
-/** @class gslSVDsolver gslSVDsolver.h
- *
- *
- *  @author Jan Amoraal
- *  @date   2007-07-24
- */
-
-class gslSVDsolver : public GaudiTool, virtual public IAlignSolvTool {
-
-public:
-  /// Standard constructor
-  gslSVDsolver( const std::string& type, const std::string& name, const IInterface* parent );
-
-  virtual ~gslSVDsolver(); ///< Destructor
-
-  using IAlignSolvTool::compute; ///< avoids hiding the original function definitions
-  /// Solves Ax = b using gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, gsl_vector * work)
-  bool compute( AlSymMat& symMatrix, AlVec& vector, AlVec& evvector ) const override;
-
-  bool compute( AlSymMat& symMatrix, AlVec& vector ) const override {
-    AlVec dummy( vector.size() );
-    return compute( symMatrix, vector, dummy );
-  }
-
-protected:
-private:
-  bool         m_svdJacobi;  ///< Use Jacobi SVD?
-  double       m_svdEpsilon; ///< SVD threshold. The singular values are stored in gsl_vector S.
-  unsigned int m_nZero;      ///< remove the n smallest eigenvalues
-  double       m_eigenValueThreshold;
-  size_t       m_numberOfPrintedEigenvalues;
-};
-
-inline std::ostream& operator<<( std::ostream& lhs, const gsl_vector& rhs ) {
-  lhs << std::endl;
-  lhs << "[ " << std::endl;
-  for ( unsigned i = 0u; i < rhs.size; ++i ) {
-    lhs << " " << ( *gsl_vector_const_ptr( &rhs, i ) ) << " ";
-    lhs << std::endl;
-  }
-  lhs << " ]" << std::endl;
-  return lhs;
-}
-
-inline std::ostream& operator<<( std::ostream& lhs, const gsl_matrix& rhs ) {
-  lhs << std::endl;
-  lhs << "[ " << std::endl;
-  for ( unsigned i = 0u; i < rhs.size1; ++i ) {
-    for ( unsigned j = 0u; j < rhs.size2; ++j ) { lhs << " " << ( *gsl_matrix_const_ptr( &rhs, i, j ) ) << " "; }
-    lhs << std::endl;
-  }
-  lhs << " ]" << std::endl;
-  return lhs;
-}
-
-#endif // GSLSVDSOLVER_H
diff --git a/Alignment/AlignTrTools/src/ATrackSelector.h b/Alignment/AlignTrTools/src/ATrackSelector.h
index 254969f4da9faef1646a4e7c791b2cb635ce1d5b..b5d3695063df9dbb3befe977596f0ecec56e4579 100755
--- a/Alignment/AlignTrTools/src/ATrackSelector.h
+++ b/Alignment/AlignTrTools/src/ATrackSelector.h
@@ -72,9 +72,8 @@ private:
 
 private:
   // Interfaces:
-  IATrackSelectorTool* m_trackselector;
-  ITrackExtrapolator*  m_extrapolator;
-  ITrackCaloMatch*     m_trackenergy;
+  ITrackExtrapolator* m_extrapolator;
+  ITrackCaloMatch*    m_trackenergy;
 
   bool   Unify( const LHCb::Track& );
   bool   uniformCut( int& );
diff --git a/Alignment/AlignTrTools/src/AlignSaveTuple.h b/Alignment/AlignTrTools/src/AlignSaveTuple.h
index 1bbfa7204e46050b8ede5e7e786fa24cb3d2b45a..6d63cc70759b17ab91567fc1e42877367fbf8531 100755
--- a/Alignment/AlignTrTools/src/AlignSaveTuple.h
+++ b/Alignment/AlignTrTools/src/AlignSaveTuple.h
@@ -44,9 +44,9 @@
 //===========================================================================
 // Forward declarations
 //===========================================================================
-class ITrackExtrapolator;
+struct ITrackExtrapolator;
 class IMagneticFieldSvc;
-class ITrackGhostClassification;
+struct ITrackGhostClassification;
 class GhostTrackInfo;
 //===========================================================================
 
diff --git a/Alignment/AlignTrTools/src/AlignTrackMonitor.h b/Alignment/AlignTrTools/src/AlignTrackMonitor.h
index 5994ba6e45cb4b24df56cac08ae2357910da3db3..a13b8d08927f28854ab609e433fdf2efe85927c2 100755
--- a/Alignment/AlignTrTools/src/AlignTrackMonitor.h
+++ b/Alignment/AlignTrTools/src/AlignTrackMonitor.h
@@ -43,7 +43,7 @@
 //===========================================================================
 // Forward declarations
 //===========================================================================
-class ITrackExtrapolator;
+struct ITrackExtrapolator;
 class IMagneticFieldSvc;
 //===========================================================================
 
diff --git a/Alignment/AlignTrTools/src/DToKPiTwoProng.h b/Alignment/AlignTrTools/src/DToKPiTwoProng.h
index 9fdd8697fd8c86f018fdef5aafef4366ddf9a754..3116198aeb7b12b11b86edb16344b13ec56b0e53 100644
--- a/Alignment/AlignTrTools/src/DToKPiTwoProng.h
+++ b/Alignment/AlignTrTools/src/DToKPiTwoProng.h
@@ -24,10 +24,9 @@ namespace LHCb {
 
 class ILHCbMagnetSvc;
 class IHitExpectation;
-class ITrackVertexer;
-class ITrackExtrapolator;
-
-class ITrackFitter;
+struct ITrackVertexer;
+struct ITrackExtrapolator;
+struct ITrackFitter;
 
 class DToKPiTwoProng final : public GaudiTupleAlg {
 
diff --git a/Alignment/AlignTrTools/src/MakeMuonTracks.h b/Alignment/AlignTrTools/src/MakeMuonTracks.h
index 956c671f6a73b3759ddfdc972b09604e190d7657..ccf3e90b1edf4004c73cca8c69da78975a4f5957 100644
--- a/Alignment/AlignTrTools/src/MakeMuonTracks.h
+++ b/Alignment/AlignTrTools/src/MakeMuonTracks.h
@@ -21,7 +21,7 @@
 #include "MuonDet/DeMuonDetector.h"
 #include "MuonInterfaces/IMuonTrackRec.h"
 
-class ITrackMomentumEstimate;
+struct ITrackMomentumEstimate;
 
 /** @class MakeMuonTracks MakeMuonTracks.h
  *  Simple algorithm to make "LHCb" tracks from MuonNNet tracks
diff --git a/Alignment/AlignTrTools/src/MuonTrackSelector.cpp b/Alignment/AlignTrTools/src/MuonTrackSelector.cpp
index f0691e1600ec3ee49568f0f7f4ffbb5e649b7a96..35c563b78c5b2f86902e2e7008dda4c490cac9d8 100644
--- a/Alignment/AlignTrTools/src/MuonTrackSelector.cpp
+++ b/Alignment/AlignTrTools/src/MuonTrackSelector.cpp
@@ -31,8 +31,7 @@ MuonTrackSelector::MuonTrackSelector( const std::string& name, ISvcLocator* pSvc
     , m_tracksInputContainer( "" )
     , m_tracksOutputContainer( "" )
     , m_trackType( "" )
-    , m_trackSelectorName( "" )
-    , m_trackSelector( 0 ) {
+    , m_trackSelectorName( "" ) {
   declareProperty( "TracksInputContainer", m_tracksInputContainer = TrackLocation::Default );
   declareProperty( "TracksOutputContainer", m_tracksOutputContainer = "Alignment/FilteredTracks" );
   declareProperty( "TrackType", m_trackType = "Long" );
diff --git a/Alignment/AlignTrTools/src/MuonTrackSelector.h b/Alignment/AlignTrTools/src/MuonTrackSelector.h
index cc103f8e88de5dde657431af6f003395b5d39037..5d375fdcfcdd23e72cbe3801608312b514423df3 100644
--- a/Alignment/AlignTrTools/src/MuonTrackSelector.h
+++ b/Alignment/AlignTrTools/src/MuonTrackSelector.h
@@ -26,9 +26,6 @@
 // from TrackEvent
 #include "Event/Track.h"
 
-// from AlignmentInterfaces
-#include "TrackInterfaces/ITrackSelector.h"
-
 /** @class TrackFilterAlg TrackFilterAlg.h
  *  A small algorithm that filters tracks of a certain type.
  *
@@ -55,17 +52,16 @@ private:
 
   void filterMuonTrack( LHCb::Track* track, LHCb::Tracks* outputContainer );
 
-  std::string     m_tracksInputContainer;  ///< Tracks input container
-  std::string     m_tracksOutputContainer; ///< Tracks output container
-  std::string     m_trackType;             ///< Type of tracks to filter
-  std::string     m_trackSelectorName;     ///< Name of track selector for alignment
-  ITrackSelector* m_trackSelector;         ///< Pointer to track selector tool for alignment
-  bool            m_calo;
-  bool            m_noOverlap;
-  double          m_pcut;
-  double          m_muonChisquareCut;
-  int             m_nStation;
-  int             m_theR;
+  std::string m_tracksInputContainer;  ///< Tracks input container
+  std::string m_tracksOutputContainer; ///< Tracks output container
+  std::string m_trackType;             ///< Type of tracks to filter
+  std::string m_trackSelectorName;     ///< Name of track selector for alignment
+  bool        m_calo;
+  bool        m_noOverlap;
+  double      m_pcut;
+  double      m_muonChisquareCut;
+  int         m_nStation;
+  int         m_theR;
 };
 
 /*
diff --git a/Alignment/AlignTrTools/src/OTMuonCosmicsMatching.h b/Alignment/AlignTrTools/src/OTMuonCosmicsMatching.h
index 4f5025e76212a45530ca49f9d12b804fc65a13d4..5e3525b4733736109f078104f794c1805d975d68 100755
--- a/Alignment/AlignTrTools/src/OTMuonCosmicsMatching.h
+++ b/Alignment/AlignTrTools/src/OTMuonCosmicsMatching.h
@@ -34,7 +34,7 @@
 #include "TrackInterfaces/ITrackChi2Calculator.h"
 
 namespace MatchingHelpers {
-  class MatchedTrack;
+  struct MatchedTrack;
 }
 
 /** @class OTMuonCosmicsMatching OTMuonCosmicsMatching.h
diff --git a/Alignment/AlignTrTools/src/ParticleToTrackContainer.cpp b/Alignment/AlignTrTools/src/ParticleToTrackContainer.cpp
index b6e78656941bc5e6e6248582067119ad170f4c22..ff602300b5023449aba27f2f852828147bd9bdc3 100644
--- a/Alignment/AlignTrTools/src/ParticleToTrackContainer.cpp
+++ b/Alignment/AlignTrTools/src/ParticleToTrackContainer.cpp
@@ -40,8 +40,6 @@ public:
 private:
   std::string                m_inputLocation;
   std::string                m_outputLocation;
-  double                     m_minMass;
-  double                     m_maxMass;
   ToolHandle<ITrackSelector> m_selector;
 };
 
diff --git a/Alignment/TAlignment/src/TStation.cpp b/Alignment/AlignTrTools/src/TStation.cpp
similarity index 100%
rename from Alignment/TAlignment/src/TStation.cpp
rename to Alignment/AlignTrTools/src/TStation.cpp
diff --git a/Alignment/TAlignment/src/TStation.h b/Alignment/AlignTrTools/src/TStation.h
similarity index 100%
rename from Alignment/TAlignment/src/TStation.h
rename to Alignment/AlignTrTools/src/TStation.h
diff --git a/Alignment/AlignTrTools/src/TrackMuonMatching.h b/Alignment/AlignTrTools/src/TrackMuonMatching.h
index 81f2aae2868ccdb6017f336b9439f05fc8f77f44..dacbbdece8c0f87147aae2f0b992272fa70635af 100644
--- a/Alignment/AlignTrTools/src/TrackMuonMatching.h
+++ b/Alignment/AlignTrTools/src/TrackMuonMatching.h
@@ -66,7 +66,6 @@ private:
   std::string           m_tracksOutputLocation;
   double                m_matchAtZ;
   bool                  m_matchAtFirstMuonHit;
-  bool                  m_matchAtOT;
   double                m_matchChi2Cut;
   bool                  m_allCombinations;
   DeMuonDetector*       m_muonDet;
diff --git a/Alignment/AlignTrTools/src/TrackPVRefitter.cpp b/Alignment/AlignTrTools/src/TrackPVRefitter.cpp
index 883cbe17310da7bf76b1a10cf0dff34c95cc4f81..032f26b5f56edc8371a86ca20664cf4148678c8c 100644
--- a/Alignment/AlignTrTools/src/TrackPVRefitter.cpp
+++ b/Alignment/AlignTrTools/src/TrackPVRefitter.cpp
@@ -35,7 +35,6 @@ public:
 private:
   std::string m_trackContainerName;
   std::string m_pvContainerName;
-  double      m_maxLongTrackChisqPerDof;
 
   ToolHandle<ITrackVertexer> m_vertexer;
   ToolHandle<ITrackFitter>   m_trackfitter;
diff --git a/Alignment/AlignTrTools/src/TrackParticleRefitter.cpp b/Alignment/AlignTrTools/src/TrackParticleRefitter.cpp
index 3824887ca58ae818cf6055f2d1c99ee2c450d59f..fd3e7536602a49ccbb1e5896069d94a21e9a604f 100644
--- a/Alignment/AlignTrTools/src/TrackParticleRefitter.cpp
+++ b/Alignment/AlignTrTools/src/TrackParticleRefitter.cpp
@@ -19,143 +19,81 @@
 #include "Event/KalmanFitResult.h"
 #include "Event/Particle.h"
 #include "Event/Track.h"
-#include "Event/Vertex.h"
 #include "GaudiAlg/GaudiAlgorithm.h"
-#include "GaudiKernel/SharedObjectsContainer.h"
 #include "GaudiKernel/ToolHandle.h"
-#include "Kernel/IParticlePropertySvc.h"
-#include "Kernel/ParticleID.h"
-#include "Kernel/ParticleProperty.h"
+#include "Kernel/IVertexFit.h"
 #include "LHCbMath/LorentzVectorWithError.h"
 #include "TrackInterfaces/ITrackFitter.h"
 #include "TrackInterfaces/ITrackStateProvider.h"
-#include "TrackKernel/TrackStateVertex.h"
-#include <boost/foreach.hpp>
+
 #include <string>
 
 class TrackParticleRefitter : public GaudiAlgorithm {
 
 public:
   // Constructors and destructor
-  TrackParticleRefitter( const std::string& name, ISvcLocator* pSvcLocator );
-  virtual ~TrackParticleRefitter();
-
-  StatusCode initialize() override;
-  StatusCode finalize() override;
+  using GaudiAlgorithm::GaudiAlgorithm;
   StatusCode execute() override;
 
 private:
-  std::string                     m_inputLocation;
-  std::string                     m_particleName;
-  int                             m_pid;
-  ToolHandle<ITrackFitter>        m_trackfitter;
-  ToolHandle<ITrackStateProvider> m_stateprovider;
+  StatusCode refittree( const LHCb::Particle& p, std::set<const LHCb::Particle*>& refittedparticles );
+
+private:
+  Gaudi::Property<std::string>          m_inputLocation{this, "ParticleLocation"};
+  Gaudi::Property<bool>                 m_forceTrackRefit{this, "ForceTrackRefit", false};
+  ToolHandle<IVertexFit>                m_vertexfitter{this, "VeretxFitter", "ParticleVertexFitter"};
+  ToolHandle<ITrackFitter>              m_trackfitter{this, "TrackFitter", "TrackMasterFitter"};
+  PublicToolHandle<ITrackStateProvider> m_stateprovider{this, "TrackStateProvider", "TrackStateProvider"};
 };
 
 DECLARE_COMPONENT( TrackParticleRefitter )
 
-TrackParticleRefitter::TrackParticleRefitter( const std::string& name, ISvcLocator* pSvcLocator )
-    : GaudiAlgorithm( name, pSvcLocator )
-    , m_pid( 0 )
-    , m_trackfitter( "TrackMasterFitter", this )
-    , m_stateprovider( "TrackStateProvider" ) {
-  // constructor
-  declareProperty( "ParticleName", m_particleName = "" );
-  declareProperty( "ParticleLocation", m_inputLocation );
-  declareProperty( "TrackFitter", m_trackfitter );
-}
-
-StatusCode TrackParticleRefitter::initialize() {
-  StatusCode sc = GaudiAlgorithm::initialize();
-  if ( sc.isSuccess() ) sc = m_trackfitter.retrieve();
-  if ( sc.isSuccess() ) sc = m_stateprovider.retrieve();
-  if ( sc.isSuccess() && !m_particleName.empty() ) {
-    LHCb::IParticlePropertySvc*   propertysvc = svc<LHCb::IParticlePropertySvc>( "LHCb::ParticlePropertySvc", true );
-    const LHCb::ParticleProperty* prop        = propertysvc->find( m_particleName );
-    if ( prop != 0 )
-      m_pid = prop->particleID().pid();
-    else {
-      error() << "Cannot find particle property for \'" << m_particleName << "\'" << endmsg;
-      sc = StatusCode::FAILURE;
-    }
-  }
-  return sc;
-}
-
-StatusCode TrackParticleRefitter::finalize() {
-  m_trackfitter.release().ignore();
-  m_stateprovider.release().ignore();
-  return GaudiAlgorithm::finalize();
-}
-
-TrackParticleRefitter::~TrackParticleRefitter() {
-  // destructor
-}
-
-namespace {
-  void addTracks( const LHCb::Particle& p, std::vector<const LHCb::Track*>& tracks, std::vector<double>& masshypos ) {
+StatusCode TrackParticleRefitter::refittree( const LHCb::Particle&            p,
+                                             std::set<const LHCb::Particle*>& refittedparticles ) {
+  StatusCode sc = StatusCode::SUCCESS;
+  if ( refittedparticles.find( &p ) == refittedparticles.end() ) {
+    // if we are a simple track, then refit the track
     if ( p.proto() && p.proto()->track() ) {
-      tracks.push_back( p.proto()->track() );
-      masshypos.push_back( p.momentum().M() );
+      auto tr = p.proto()->track();
+      if ( m_forceTrackRefit || !dynamic_cast<const LHCb::KalmanFitResult*>( tr->fitResult() ) ) {
+        StatusCode thissc = m_trackfitter->operator()( const_cast<LHCb::Track&>( *tr ) );
+        if ( !sc.isSuccess() ) {
+          warning() << "problem fitting track" << endmsg;
+          sc = thissc;
+        }
+        m_stateprovider->clearCache( *tr ); // better safe than sorry
+      }
     } else {
-      BOOST_FOREACH ( const LHCb::Particle* dau, p.daughters() )
-        addTracks( *dau, tracks, masshypos );
+      // make sure to refit all daughters
+      for ( const LHCb::Particle* dau : p.daughters() ) {
+        StatusCode thissc = refittree( *dau, refittedparticles );
+        if ( !thissc.isSuccess() ) sc = thissc;
+      }
+      // if we have an endvertex, do a vertex fit
+      if ( p.endVertex() ) {
+        LHCb::Particle& ncp    = const_cast<LHCb::Particle&>( p );
+        StatusCode      thissc = m_vertexfitter->reFit( ncp );
+        // never quite understood why we need to set this separately
+        ncp.setMeasuredMass( ncp.momentum().M() );
+        ncp.setMeasuredMassErr( Gaudi::Math::LorentzVectorWithError( ncp.momentum(), ncp.momCovMatrix() ).m().error() );
+        if ( !thissc.isSuccess() ) sc = thissc;
+      }
     }
+    // add this particle to the list of particles that we already treated
+    refittedparticles.insert( &p );
   }
-} // namespace
+  return sc;
+}
 
 StatusCode TrackParticleRefitter::execute() {
-  LHCb::Particle::Range inputparticles = get<LHCb::Particle::Range>( m_inputLocation );
-  BOOST_FOREACH ( const LHCb::Particle* p, inputparticles ) {
-    double z = p->referencePoint().z();
-
-    std::vector<const LHCb::Track*> tracks;
-    std::vector<double>             masshypos;
-    addTracks( *p, tracks, masshypos );
-    if ( tracks.size() < 2 ) {
-      warning() << "Not enough tracks! .. skipping particle" << p->daughters().size() << " " << tracks.size() << endmsg;
-
-    } else {
 
-      std::vector<const LHCb::State*> states;
-      BOOST_FOREACH ( const LHCb::Track* tr, tracks ) {
-        if ( !dynamic_cast<const LHCb::KalmanFitResult*>( tr->fitResult() ) ) {
-          StatusCode sc = m_trackfitter->operator()( const_cast<LHCb::Track&>( *tr ) );
-          if ( !sc.isSuccess() ) warning() << "problem fitting track" << endmsg;
-        }
-        LHCb::State* state = new LHCb::State();
-        StatusCode   sc    = m_stateprovider->stateFromTrajectory( *state, *tr, z );
-        if ( !sc.isSuccess() ) warning() << "problem getting state from stateprovider" << endmsg;
-        states.push_back( state );
-      }
-
-      LHCb::TrackStateVertex vertex( states );
-      vertex.fit();
-      // now copy everything
-      LHCb::Particle* ncp = const_cast<LHCb::Particle*>( p );
-      if ( m_pid ) ncp->setParticleID( LHCb::ParticleID( m_pid ) );
-      ncp->setMomentum( vertex.p4( masshypos ) );
-      ncp->setReferencePoint( vertex.position() );
-      Gaudi::SymMatrix7x7 cov7x7 = vertex.covMatrix7x7( masshypos );
-      ncp->setMomCovMatrix( cov7x7.Sub<Gaudi::SymMatrix4x4>( 3, 3 ) );
-      ncp->setPosCovMatrix( cov7x7.Sub<Gaudi::SymMatrix3x3>( 0, 0 ) );
-      ncp->setPosMomCovMatrix( cov7x7.Sub<Gaudi::Matrix4x3>( 3, 0 ) );
-      ncp->setMeasuredMass( ncp->momentum().M() );
-      // ncp->setMeasuredMassErr(  vertex.massErr(masshypos) ) ;
-      ncp->setMeasuredMassErr(
-          Gaudi::Math::LorentzVectorWithError( ncp->momentum(), ncp->momCovMatrix() ).m().error() );
-      LHCb::Vertex* endvertex = ncp->endVertex();
-      if ( endvertex ) {
-        endvertex->setPosition( vertex.position() );
-        endvertex->setChi2AndDoF( vertex.chi2(), vertex.nDoF() );
-        endvertex->setCovMatrix( vertex.covMatrix() );
-      }
-
-      // don't forget to delete all  states !
-      BOOST_FOREACH ( const LHCb::State* s, states )
-        delete s;
-    }
+  LHCb::Particle::Range inputparticles = get<LHCb::Particle::Range>( m_inputLocation );
+  // we keep track of which particles were treated, so we don't do them more than once.
+  std::set<const LHCb::Particle*> refittedparticles;
+  // now do the vertex fits
+  for ( const LHCb::Particle* p : inputparticles ) {
+    StatusCode sc = refittree( *p, refittedparticles );
+    if ( !sc.isSuccess() ) warning() << "Vertex fit failed" << endmsg;
   }
-
   return StatusCode::SUCCESS;
 }
diff --git a/Alignment/AlignmentInterfaces/AlignmentInterfaces/IAlignSolvTool.h b/Alignment/AlignmentInterfaces/AlignmentInterfaces/IAlignSolvTool.h
index f2dab86c3d357542cec58926eed9eae54aa685bd..c8ddf5a390582b3df5e6729feda4d6ee64f2c219 100755
--- a/Alignment/AlignmentInterfaces/AlignmentInterfaces/IAlignSolvTool.h
+++ b/Alignment/AlignmentInterfaces/AlignmentInterfaces/IAlignSolvTool.h
@@ -8,13 +8,11 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// $Id: IAlignSolvTool.h,v 1.7 2009-07-06 14:06:44 wouter Exp $
-#ifndef ALIGNSOLVTOOLS_IALIGNSOLVTOOL_H
-#define ALIGNSOLVTOOLS_IALIGNSOLVTOOL_H 1
+#pragma once
 
 // Include files
 // from STL
-#include <string>
+//#include <string>
 
 // from Gaudi
 #include "GaudiKernel/IAlgTool.h"
@@ -47,11 +45,11 @@ public:
   };
 
   // Solves the system Ax=b for x. Returns A=A^{-1} and b=x.
-  virtual bool compute( AlSymMat& A, AlVec& b ) const = 0;
+  virtual StatusCode compute( AlSymMat& A, AlVec& b ) const = 0;
 
   // Solves the system Ax=b for x. Returns A=A^{-1}, b=x and S =
   // eigenvalues of A.
-  virtual bool compute( AlSymMat& A, AlVec& b, AlVec& /*S*/ ) const { return compute( A, b ); }
+  virtual StatusCode compute( AlSymMat& A, AlVec& b, AlVec& /*S*/ ) const { return compute( A, b ); }
 
   // Solves the system Ax=b for x. Return A=A^{-1} and
   // b=x. Furthermore, returns an object with some characteristics of
@@ -60,4 +58,3 @@ public:
     return compute( A, b ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
   }
 };
-#endif // ALIGNSOLVTOOLS_IALIGNSOLVTOOL_H
diff --git a/Alignment/Escher/scripts/solvertest.py b/Alignment/Escher/scripts/solvertest.py
new file mode 100644
index 0000000000000000000000000000000000000000..79901021320e0a9e035bad248c793c8e6c0e7deb
--- /dev/null
+++ b/Alignment/Escher/scripts/solvertest.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+###############################################################################
+# (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      #
+#                                                                             #
+# This software is distributed under the terms of the GNU General Public      #
+# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
+#                                                                             #
+# In applying this licence, CERN does not waive the privileges and immunities #
+# granted to it by virtue of its status as an Intergovernmental Organization  #
+# or submit itself to any jurisdiction.                                       #
+###############################################################################
+
+# first parse all options
+from optparse import OptionParser
+parser = OptionParser(usage="%prog [options] <opts_file> ...")
+parser.add_option(
+    "-n",
+    "--numiter",
+    type="int",
+    dest="numiter",
+    help="number of iterations",
+    default=1)
+parser.add_option(
+    "-e",
+    "--numevents",
+    type="int",
+    dest="numevents",
+    help="number of events",
+    default=-1)
+parser.add_option(
+    "-d",
+    "--aligndb",
+    action='append',
+    dest="aligndb",
+    help="path to file with CALIBOFF/LHCBCOND/SIMCOND database layer")
+parser.add_option(
+    "--dddb",
+    action='append',
+    dest="dddb",
+    help="path to file with DDDB database layer")
+parser.add_option(
+    "--skipprintsequence",
+    action="store_true",
+    help="skip printing the sequence")
+parser.add_option(
+    "-l",
+    "--lhcbcond",
+    action="store_true",
+    dest="lhcbcondtag",
+    help="activate if constants in lhcbcondDB",
+    default=False)
+(opts, args) = parser.parse_args()
+
+# Prepare the "configuration script" to parse (like this it is easier than
+# having a list with files and python commands, with an if statements that
+# decides to do importOptions or exec)
+options = ["importOptions(%r)" % f for f in args]
+
+# The option lines are inserted into the list of commands using their
+# position on the command line
+#optlines = list(opts.options)
+#optlines.reverse() # this allows to avoid to have to care about corrections of the positions
+#for pos, l in optlines:
+#   options.insert(pos,l)
+
+# "execute" the configuration script generated (if any)
+from Gaudi.Configuration import logging
+if options:
+    g = {}
+    l = {}
+    exec "from Gaudi.Configuration import *" in g, l
+    for o in options:
+        logging.debug(o)
+        exec o in g, l
+
+#options = [ "importOptions(%r)" % f for f in args ]
+
+# make sure that the algorithms know how many iterations are coming
+from Configurables import TAlignment
+TAlignment().UpdateInFinalize = False
+
+# set the database layer
+if opts.aligndb:
+    counter = 1
+    for db in opts.aligndb:
+        from Configurables import CondDB
+        if ".db" in db:
+            # this is an sqlite file
+            from Configurables import CondDBAccessSvc
+            alignCond = CondDBAccessSvc('AlignCond' + str(counter))
+            alignCond.ConnectionString = 'sqlite_file:' + db + condtag
+            CondDB().addLayer(alignCond)
+            counter += 1
+        else:
+            # this is a git layer
+            CondDB().addLayer(db)
+        print "adding layer: ", db
+
+if opts.dddb:
+    counter = 1
+    for db in opts.dddb:
+        from Configurables import (CondDB, CondDBAccessSvc)
+        alignCond = CondDBAccessSvc('AlignDDDB' + str(counter))
+        alignCond.ConnectionString = 'sqlite_file:' + db + '/DDDB'
+        CondDB().addLayer(alignCond)
+        counter += 1
+
+## configure all solver tools (before creating the appmgr)
+solvers = [
+    "GslDiagSolvTool", "EigenDiagSolvTool", "SpmInvTool", "gslSVDsolver",
+    "CLHEPSolver", "SparseSolver"
+]
+updatetools = []
+for solvername in solvers:
+    # first configure it, then retrieve it via the toolsvc. does that make sense?
+    from Configurables import Al__AlignUpdateTool as AlignUpdateTool
+    updatetoolname = "UpdateTool" + solvername
+    dir(AlignUpdateTool())
+    AlignUpdateTool().clone(updatetoolname)
+
+    updatetool = AlignUpdateTool(
+        updatetoolname,
+        MatrixSolverTool=solvername,
+        SkipGeometryUpdate=True,
+        LogFile="alignlog_" + solvername + ".txt",
+        OutputLevel=3)
+    # for now we do it like this
+    from Configurables import SurveyConstraints, TAlignment
+    SurveyConstraints().configureTool(updatetool.SurveyConstraintTool)
+    updatetool.LagrangeConstraintTool.Constraints = TAlignment().getProp(
+        "Constraints")
+    updatetool.LagrangeConstraintTool.UseWeightedAverage = TAlignment(
+    ).getProp("UseWeightedAverageConstraint")
+    updatetools.append(updatetoolname)
+
+## Instantiate application manager
+from GaudiPython.Bindings import AppMgr
+appMgr = AppMgr()
+
+## print the sequence
+if not opts.skipprintsequence:
+    from Escher.Utils import printsequence
+    printsequence(appMgr)
+
+evtSel = appMgr.evtSel()
+evtSel.OutputLevel = 1
+mainSeq = appMgr.algorithm("EscherSequencer")
+
+print evtSel.Input
+
+# event loop
+appMgr.run(opts.numevents)
+
+# get the derivatives
+import copy
+det = appMgr.detsvc()
+alignderivatives = det['AlignDerivativeData']
+print "alignderivatives:", alignderivatives
+for updatetoolname in updatetools:
+    print ["*" * 40]
+    print "UpdateTool: ", updatetoolname
+    updatetool = appMgr.toolsvc().create(
+        typ="Al::AlignUpdateTool",
+        name=updatetoolname,
+        interface="Al::IAlignUpdateTool")
+
+    equations = copy.deepcopy(alignderivatives.equations())
+    updatetool.process(equations, 0, 1)
+
+#exit the appmgr for finalize
+#appMgr.exit()
diff --git a/Alignment/TAlignment/python/TAlignment/Configuration.py b/Alignment/TAlignment/python/TAlignment/Configuration.py
index ff0fc60cc8dcaf4c1651418892058d0fd52fb7ab..ac6995c24bc8d9db91a05840cb8684be43a8078e 100644
--- a/Alignment/TAlignment/python/TAlignment/Configuration.py
+++ b/Alignment/TAlignment/python/TAlignment/Configuration.py
@@ -84,7 +84,7 @@ class TAlignment(LHCbConfigurableUser):
         True  # Pre-conditioning
         ,
         "SolvTool":
-        "DiagSolvTool"  # Solver to use
+        "EigenDiagSolvTool"  # Solver to use
         ,
         "EigenValueThreshold":
         -1  # Eigenvalue threshold for cutting out weak modes
@@ -396,7 +396,7 @@ class TAlignment(LHCbConfigurableUser):
 
             from Configurables import (
                 AlignAlgorithm, GetElementsToBeAligned, gslSVDsolver,
-                CLHEPSolver, SparseSolver, DiagSolvTool,
+                CLHEPSolver, SparseSolver, EigenDiagSolvTool, GslDiagSolvTool,
                 Al__AlignConstraintTool, Al__AlignUpdateTool,
                 Al__TrackResidualTool, WriteMultiAlignmentConditionsTool)
 
@@ -457,7 +457,9 @@ class TAlignment(LHCbConfigurableUser):
             # and these too
             gslSVDsolver().EigenValueThreshold = self.getProp(
                 "EigenValueThreshold")
-            DiagSolvTool().EigenValueThreshold = self.getProp(
+            EigenDiagSolvTool().EigenValueThreshold = self.getProp(
+                "EigenValueThreshold")
+            GslDiagSolvTool().EigenValueThreshold = self.getProp(
                 "EigenValueThreshold")
 
             alignSequencer.Members.append(alignAlg)
diff --git a/Alignment/TAlignment/src/AlElementHistos.h b/Alignment/TAlignment/src/AlElementHistos.h
index d4555cb12ce99d0f498fb69d0ce3428f5018c335..a9ef61a0f3b1c260c8a58387b77713ab1a565205 100755
--- a/Alignment/TAlignment/src/AlElementHistos.h
+++ b/Alignment/TAlignment/src/AlElementHistos.h
@@ -18,7 +18,7 @@ namespace AIDA {
   class IHistogram2D;
 } // namespace AIDA
 class AlignmentElement;
-class GaudiHistoAlg;
+struct GaudiHistoAlg;
 
 struct AlElementHistos {
   AlElementHistos( GaudiHistoAlg& parent, const AlignmentElement& elem, std::size_t niter );
diff --git a/Alignment/TAlignment/src/AlParameters.cpp b/Alignment/TAlignment/src/AlParameters.cpp
index 1c7b2bb33e2e0e2a2a98217a24d8b5be7cbdc109..316af10b77b88f3654c802d80fdfa4d59ed3c3ef 100755
--- a/Alignment/TAlignment/src/AlParameters.cpp
+++ b/Alignment/TAlignment/src/AlParameters.cpp
@@ -28,8 +28,8 @@ AlParameters::AlParameters( DofMask mask ) : m_mask( mask ), m_parameters( dim()
 AlParameters::AlParameters( const Vector& parameters, const Covariance& covariance, DofMask mask, size_t offset )
     : m_mask( mask ), m_parameters( dim() ), m_covariance( dim() ), m_weightmatrix( dim() ) {
   for ( unsigned int i = 0u; i < dim(); ++i ) {
-    m_parameters[i] = parameters[i + offset];
-    for ( unsigned int j = 0u; j <= i; ++j ) m_covariance[i][j] = covariance[offset + i][offset + j];
+    m_parameters( i ) = parameters( i + offset );
+    for ( unsigned int j = 0u; j <= i; ++j ) m_covariance( i, j ) = covariance( offset + i, offset + j );
   }
 }
 
@@ -37,10 +37,10 @@ AlParameters::AlParameters( const Vector& parameters, const Covariance& covarian
                             DofMask mask, size_t offset )
     : m_mask( mask ), m_parameters( dim() ), m_covariance( dim() ), m_weightmatrix( dim() ) {
   for ( unsigned int i = 0u; i < dim(); ++i ) {
-    m_parameters[i] = parameters[i + offset];
+    m_parameters( i ) = parameters( i + offset );
     for ( unsigned int j = 0u; j <= i; ++j ) {
-      m_covariance[i][j]   = covariance[offset + i][offset + j];
-      m_weightmatrix[i][j] = weightmatrix[offset + i][offset + j];
+      m_covariance( i, j )   = covariance( offset + i, offset + j );
+      m_weightmatrix( i, j ) = weightmatrix( offset + i, offset + j );
     }
   }
 }
@@ -48,29 +48,29 @@ AlParameters::AlParameters( const Vector& parameters, const Covariance& covarian
 AlParameters::AlParameters( const TransformParameters& parameters, const TransformCovariance& covariance )
     : m_mask( NumPars ), m_parameters( 6 ), m_covariance( 6 ), m_weightmatrix( 6 ) {
   for ( unsigned int i = 0u; i < dim(); ++i ) {
-    m_parameters[i] = parameters[i];
-    for ( unsigned int j = 0u; j <= i; ++j ) m_covariance[i][j] = covariance[i][j];
+    m_parameters( i ) = parameters( i );
+    for ( unsigned int j = 0u; j <= i; ++j ) m_covariance( i, j ) = covariance( i, j );
   }
 }
 
 AlParameters::AlParameters( const double parameters[6], DofMask mask )
     : m_mask( mask ), m_parameters( dim() ), m_covariance( dim() ) {
-  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters[i] = parameters[mask.parIndex( i )];
+  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters( i ) = parameters[mask.parIndex( i )];
 }
 
 AlParameters::AlParameters( const TransformParameters& parameters, DofMask mask )
     : m_mask( mask ), m_parameters( dim() ), m_covariance( dim() ) {
-  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters[i] = parameters[mask.parIndex( i )];
+  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters( i ) = parameters( mask.parIndex( i ) );
 }
 
 AlParameters::AlParameters( const ROOT::Math::Transform3D& transform, DofMask mask )
     : m_mask( mask ), m_parameters( dim() ), m_covariance( dim() ) {
   TransformParameters parameters = transformParameters( transform );
-  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters[i] = parameters[mask.parIndex( i )];
+  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters( i ) = parameters( mask.parIndex( i ) );
 }
 
 void AlParameters::setParameters( const TransformParameters& parameters ) {
-  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters[i] = parameters[m_mask.parIndex( i )];
+  for ( unsigned int i = 0u; i < dim(); ++i ) m_parameters( i ) = parameters( m_mask.parIndex( i ) );
 }
 
 std::string AlParameters::parName( int parindex ) {
@@ -106,30 +106,30 @@ double AlParameters::signedSqrt( double root ) {
 
 std::ostream& AlParameters::fillStream( std::ostream& os ) const {
   for ( unsigned int iactive = 0u; iactive < dim(); ++iactive ) {
-    os << std::setw( 6 ) << parName( m_mask.parIndex( iactive ) ) << ": " << std::setw( 12 ) << m_parameters[iactive]
-       << " +/- " << std::setw( 12 ) << signedSqrt( m_covariance[iactive][iactive] ) << std::endl;
+    os << std::setw( 6 ) << parName( m_mask.parIndex( iactive ) ) << ": " << std::setw( 12 ) << m_parameters( iactive )
+       << " +/- " << std::setw( 12 ) << signedSqrt( m_covariance( iactive, iactive ) ) << std::endl;
   }
   return os;
 }
 
 std::vector<double> AlParameters::translation() const {
   std::vector<double> rc( 3, 0.0 );
-  rc[Tx] = m_mask.isActive( Tx ) ? m_parameters[m_mask.activeParIndex( Tx )] : 0;
-  rc[Ty] = m_mask.isActive( Ty ) ? m_parameters[m_mask.activeParIndex( Ty )] : 0;
-  rc[Tz] = m_mask.isActive( Tz ) ? m_parameters[m_mask.activeParIndex( Tz )] : 0;
+  rc[Tx] = m_mask.isActive( Tx ) ? m_parameters( m_mask.activeParIndex( Tx ) ) : 0;
+  rc[Ty] = m_mask.isActive( Ty ) ? m_parameters( m_mask.activeParIndex( Ty ) ) : 0;
+  rc[Tz] = m_mask.isActive( Tz ) ? m_parameters( m_mask.activeParIndex( Tz ) ) : 0;
   return rc;
 }
 
 std::vector<double> AlParameters::errTranslation() const {
   std::vector<double> errT( 3, 0.0 );
   errT[Tx] = m_mask.isActive( Tx )
-                 ? signedSqrt( m_covariance[m_mask.activeParIndex( Tx )][m_mask.activeParIndex( Tx )] )
+                 ? signedSqrt( m_covariance( m_mask.activeParIndex( Tx ), m_mask.activeParIndex( Tx ) ) )
                  : 0.0;
   errT[Ty] = m_mask.isActive( Ty )
-                 ? signedSqrt( m_covariance[m_mask.activeParIndex( Ty )][m_mask.activeParIndex( Ty )] )
+                 ? signedSqrt( m_covariance( m_mask.activeParIndex( Ty ), m_mask.activeParIndex( Ty ) ) )
                  : 0.0;
   errT[Tz] = m_mask.isActive( Tz )
-                 ? signedSqrt( m_covariance[m_mask.activeParIndex( Tz )][m_mask.activeParIndex( Tz )] )
+                 ? signedSqrt( m_covariance( m_mask.activeParIndex( Tz ), m_mask.activeParIndex( Tz ) ) )
                  : 0.0;
   return errT;
 }
@@ -145,13 +145,13 @@ std::vector<double> AlParameters::rotation() const {
 std::vector<double> AlParameters::errRotation() const {
   std::vector<double> errR( 3, 0.0 );
   errR[Rx - 3] = m_mask.isActive( Rx )
-                     ? signedSqrt( m_covariance[m_mask.activeParIndex( Rx )][m_mask.activeParIndex( Rx )] )
+                     ? signedSqrt( m_covariance( m_mask.activeParIndex( Rx ), m_mask.activeParIndex( Rx ) ) )
                      : 0.0;
   errR[Ry - 3] = m_mask.isActive( Ry )
-                     ? signedSqrt( m_covariance[m_mask.activeParIndex( Ry )][m_mask.activeParIndex( Ry )] )
+                     ? signedSqrt( m_covariance( m_mask.activeParIndex( Ry ), m_mask.activeParIndex( Ry ) ) )
                      : 0.0;
   errR[Rz - 3] = m_mask.isActive( Rz )
-                     ? signedSqrt( m_covariance[m_mask.activeParIndex( Rz )][m_mask.activeParIndex( Rz )] )
+                     ? signedSqrt( m_covariance( m_mask.activeParIndex( Rz ), m_mask.activeParIndex( Rz ) ) )
                      : 0.0;
   return errR;
 }
@@ -322,7 +322,7 @@ AlParameters::Matrix6x6 AlParameters::jacobianNumeric( const ROOT::Math::Transfo
 }
 
 double AlParameters::globalCorrelationCoefficient( int iactive ) const {
-  double varweight = m_covariance[iactive][iactive] * m_weightmatrix[iactive][iactive];
+  double varweight = m_covariance( iactive, iactive ) * m_weightmatrix( iactive, iactive );
   return varweight > 1 ? std::sqrt( 1 - 1 / varweight ) : 0;
 }
 
@@ -330,6 +330,6 @@ double AlParameters::measurementCoordinateSigma( double weightR ) const {
   double sum( 0 );
   for ( size_t iactive = 0; iactive < dim(); ++iactive )
     for ( size_t jactive = 0; jactive < dim(); ++jactive )
-      sum += m_covariance[iactive][jactive] * m_weightmatrix[iactive][jactive];
+      sum += m_covariance( iactive, jactive ) * m_weightmatrix( iactive, jactive );
   return ( sum / weightR ) > 0 ? std::sqrt( sum / weightR ) : 0;
 }
diff --git a/Alignment/TAlignment/src/AlignAlgorithm.cpp b/Alignment/TAlignment/src/AlignAlgorithm.cpp
index 98256ce32fd7ebfcf5f426c4af391c0611afd8df..e38e6e76ab7a3442a010f9aee304d8caefeb9ebc 100755
--- a/Alignment/TAlignment/src/AlignAlgorithm.cpp
+++ b/Alignment/TAlignment/src/AlignAlgorithm.cpp
@@ -96,53 +96,13 @@ public:
 };
 
 AlignAlgorithm::AlignAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
-    : GaudiHistoAlg( name, pSvcLocator )
-    , m_iteration( 0u )
-    , m_nIterations( 0u )
-    , m_nTracks( 0u )
-    , m_covFailure( 0u )
-    , m_align( 0 )
-    , m_projSelector( 0 )
-    , m_trackresidualtool( "Al::TrackResidualTool" )
-    , m_vertexresidualtool( "Al::VertexResidualTool" )
-    , m_updatetool( "Al::AlignUpdateTool" )
-    , m_vertextrackselector( "TrackSelector", this )
-    , m_xmlWritersTool( "WriteMultiAlignmentConditionsTool" )
-    , m_fireRunChange( false )
-    , m_equations( 0 )
-    , m_resetHistos( false ) {
+    : GaudiHistoAlg( name, pSvcLocator ) {
   m_HistoUpdater = new HistoUpdater();
-  declareProperty( "NumberOfIterations", m_nIterations = 10u );
-  declareProperty( "TracksLocation", m_tracksLocation = TrackLocation::Default );
-  declareProperty( "VertexLocation", m_vertexLocation = "" );
-  declareProperty( "DimuonLocation", m_dimuonLocation = "" );
-  declareProperty( "ParticleLocation", m_particleLocation = "" );
-  declareProperty( "ProjectorSelector", m_projSelectorName = "TrackProjectorSelector" );
-  declareProperty( "UseCorrelations", m_correlation = true );
-  declareProperty( "UpdateInFinalize", m_updateInFinalize = false );
-  declareProperty( "OutputDataFile", m_outputDataFileName = "" );
-  declareProperty( "InputDataFiles", m_inputDataFileNames );
-  declareProperty( "Chi2Outlier", m_chi2Outlier = 10000 );
-  declareProperty( "UpdateTool", m_updatetool );
-  declareProperty( "TrackResidualTool", m_trackresidualtool );
-  declareProperty( "VertexResidualTool", m_vertexresidualtool );
-  declareProperty( "XmlWritersTool", m_xmlWritersTool );
-  declareProperty( "MaxTracksPerVertex", m_maxTracksPerVertex = 8 );
-  declareProperty( "MinTracksPerVertex", m_minTracksPerVertex = 2 );
-
-  declareProperty( "AlignSummaryDataSvc", m_alignSummaryDataSvc = "DetectorDataSvc" );
-  //"HistogramDataSvc" ) ;
-  declareProperty( "AlignSummaryLocation", m_alignSummaryLocation = "AlignDerivativeData" );
-  declareProperty( "FillHistos", m_fillHistos = false );
-  declareProperty( "ForcedInitialTime", m_forcedInitTime = 0 );
-  declareProperty( "OnlineMode", m_Online = false );
+
   //  declareProperty("XmlWriters",m_xmlWriterNames) ;
   //  For Online Running
   declareProperty( "PartitionName", m_HistoUpdater->m_PartitionName = "LHCbA" );
   declareProperty( "ReferenceFile", m_HistoUpdater->m_RefFileName = "" );
-  declareProperty( "RunList", m_RunList );
-
-  m_runnr = 0;
 }
 
 AlignAlgorithm::~AlignAlgorithm() { delete m_HistoUpdater; }
@@ -162,23 +122,11 @@ StatusCode AlignAlgorithm::initialize() {
   incSvc->addListener( this, "DAQ_PAUSE" );
 
   /// Get tool to align detector
-  m_align = tool<IGetElementsToBeAligned>( "GetElementsToBeAligned" );
-  if ( !m_align ) return Error( "==> Failed to retrieve detector selector tool!", StatusCode::FAILURE );
-
-  sc = m_trackresidualtool.retrieve();
-  if ( sc.isFailure() ) return sc;
-
-  sc = m_vertexresidualtool.retrieve();
-  if ( sc.isFailure() ) return sc;
-
-  sc = m_updatetool.retrieve();
-  if ( sc.isFailure() ) return sc;
-
-  sc = m_vertextrackselector.retrieve();
-  if ( sc.isFailure() ) return sc;
+  //  m_elementtool = tool<IGetElementsToBeAligned>( "GetElementsToBeAligned" );
+  // if ( !m_elementtool ) return Error( "==> Failed to retrieve detector selector tool!", StatusCode::FAILURE );
 
   /// Get range  detector elements
-  const Elements& elements = m_align->elements();
+  const Elements& elements = m_elementtool->elements();
 
   if ( printDebug() ) {
     debug() << "==> Got " << elements.size() << " elements to align!" << endmsg;
@@ -205,10 +153,6 @@ StatusCode AlignAlgorithm::initialize() {
   if ( !sc.isSuccess() ) { error() << "cannot register object. statuscode = " << sc << endmsg; }
   m_equations = &( m_summaryData->equations() );
 
-  /// Get projector selector tool
-  m_projSelector = tool<ITrackProjectorSelector>( m_projSelectorName, "Projector", this );
-  if ( !m_projSelector ) return Error( "==> Failed to retrieve projector selector tool", StatusCode::FAILURE );
-
   /// Monitoring
   /// Book residual histograms
   /// Residuals
@@ -235,9 +179,6 @@ StatusCode AlignAlgorithm::finalize() {
   for ( std::vector<AlElementHistos*>::iterator ielem = m_elemHistos.begin(); ielem != m_elemHistos.end(); ++ielem )
     delete *ielem;
 
-  m_trackresidualtool.release().ignore();
-  m_vertexresidualtool.release().ignore();
-  m_updatetool.release().ignore();
   if ( m_Online ) { m_HistoUpdater->m_MonSvc = 0; }
   return GaudiHistoAlg::finalize();
 }
@@ -247,7 +188,7 @@ StatusCode AlignAlgorithm::stop() {
     if ( m_RunList.size() > 0 ) {
       if ( m_RunList[0] != "*" ) { m_HistoUpdater->Update( ::atoi( m_RunList[0].c_str() ) ); }
     }
-    if ( !m_outputDataFileName.empty() ) m_equations->writeToFile( m_outputDataFileName.c_str() );
+    if ( !m_outputDataFileName.empty() ) m_equations->writeToFile( m_outputDataFileName.value().c_str() );
     m_fireRunChange = true;
   }
   return StatusCode::SUCCESS;
@@ -281,8 +222,8 @@ StatusCode AlignAlgorithm::execute() {
   if ( m_resetHistos ) resetHistos();
 
   // Make sure that the alignment frames are properly initialized on the first event
-  if ( m_equations->initTime() != 0 && m_equations->initTime() != m_align->initTime() ) {
-    error() << "Mismatch in init time: " << m_equations->initTime() << " " << m_align->initTime() << ". Aborting."
+  if ( m_equations->initTime() != 0 && m_equations->initTime() != m_elementtool->initTime() ) {
+    error() << "Mismatch in init time: " << m_equations->initTime() << " " << m_elementtool->initTime() << ". Aborting."
             << endmsg;
     return StatusCode::FAILURE;
   }
@@ -296,10 +237,10 @@ StatusCode AlignAlgorithm::execute() {
 
   if ( m_equations->initTime() == 0 ) {
     if ( m_forcedInitTime )
-      m_align->initAlignmentFrame( m_forcedInitTime ).ignore();
+      m_elementtool->initAlignmentFrame( m_forcedInitTime.value() ).ignore();
     else
-      m_align->initAlignmentFrame( eventtime ).ignore();
-    m_align->initEquations( *m_equations );
+      m_elementtool->initAlignmentFrame( eventtime ).ignore();
+    m_elementtool->initEquations( *m_equations );
   }
 
   // Get tracks. Copy them into a vector, because that's what we need for dealing with vertices.
@@ -375,7 +316,7 @@ StatusCode AlignAlgorithm::execute() {
   if ( !m_particleLocation.empty() ) {
     LHCb::Particle::Range particles = get<LHCb::Particle::Range>( m_particleLocation );
     for ( const LHCb::Particle* p : particles ) {
-      const Al::MultiTrackResiduals* res = m_vertexresidualtool->get( *p );
+      const auto res = m_vertexresidualtool->get( *p );
       if ( res && accumulate( *res ) ) {
         m_equations->addVertexChi2Summary( res->vertexChi2(), res->vertexNDoF() );
         ++numuseddimuons;
@@ -393,7 +334,7 @@ StatusCode AlignAlgorithm::execute() {
         // rebuild this vertex from tracks in the selected track list
         const LHCb::RecVertex* clone = cloneVertex( **ivertex, selectedtracks );
         if ( clone ) {
-          const Al::MultiTrackResiduals* res = m_vertexresidualtool->get( *clone );
+          const auto res = m_vertexresidualtool->get( *clone );
           if ( res && accumulate( *res ) ) {
             m_equations->addVertexChi2Summary( res->vertexChi2(), res->vertexNDoF() );
             ++numuseddimuons;
@@ -417,7 +358,7 @@ StatusCode AlignAlgorithm::execute() {
         VertexContainer splitvertices;
         splitVertex( **ivertex, selectedtracks, splitvertices );
         for ( VertexContainer::iterator isubver = splitvertices.begin(); isubver != splitvertices.end(); ++isubver ) {
-          const Al::MultiTrackResiduals* res = m_vertexresidualtool->get( *isubver );
+          const auto res = m_vertexresidualtool->get( *isubver );
           if ( res && accumulate( *res ) ) {
             m_equations->addVertexChi2Summary( res->vertexChi2(), res->vertexNDoF() );
             ++numusedvertices;
@@ -611,14 +552,14 @@ void AlignAlgorithm::update() {
         warning() << "Adding derivatives from input file: " << *ifile << " " << tmp.numHits() << " "
                   << tmp.totalChiSquare() << " " << m_equations->totalChiSquare() << endmsg;
       }
-      if ( m_align->initTime() == 0 ) m_align->initAlignmentFrame( m_equations->initTime() ).ignore();
+      if ( m_elementtool->initTime() == 0 ) m_elementtool->initAlignmentFrame( m_equations->initTime() ).ignore();
     }
     update( *m_equations );
   }
 }
 
 void AlignAlgorithm::update( const Al::Equations& equations ) {
-  if ( !m_outputDataFileName.empty() ) m_equations->writeToFile( m_outputDataFileName.c_str() );
+  if ( !m_outputDataFileName.empty() ) m_equations->writeToFile( m_outputDataFileName.value().c_str() );
   m_updatetool->process( equations, m_iteration, m_nIterations ).ignore();
   // write the xml
   m_xmlWritersTool->write().ignore();
diff --git a/Alignment/TAlignment/src/AlignAlgorithm.h b/Alignment/TAlignment/src/AlignAlgorithm.h
index 9b3c0ffc14400b6b98f48ae051af8a747918e6ab..272b9f98bc97bc59df81db4cb337bf47c3557386 100755
--- a/Alignment/TAlignment/src/AlignAlgorithm.h
+++ b/Alignment/TAlignment/src/AlignAlgorithm.h
@@ -8,13 +8,10 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// $Id: AlignAlgorithm.h,v 1.39 2010-04-17 16:21:39 wouter Exp $
-#ifndef TALIGNMENT_ALIGNALGORITHM_H
-#define TALIGNMENT_ALIGNALGORITHM_H 1
+#pragma once
 
 // Include files
 // from std
-#include <map>
 #include <string>
 #include <utility>
 #include <vector>
@@ -75,7 +72,6 @@ namespace Al {
  *  @date   2007-03-05
  */
 
-class IAlignWork;
 class HistoUpdater;
 
 class AlignAlgorithm : public GaudiHistoAlg, virtual public IIncidentListener {
@@ -109,14 +105,6 @@ public:
 
   void reset();
 
-  /** Method to get alignment constants, posXYZ and rotXYZ for a given set
-   * of detector elements
-   * @param elements flat vector of detector elements, i.e. std::vector<DetectorElements>
-   * @param alignConstants reference to a flat vector of alignment constants, i.e. std::vector<double>
-   */
-  void                     getAlignmentConstants( const Elements& elements, AlignConstants& alignConstants ) const;
-  std::vector<std::string> m_RunList;
-
 protected:
   bool printDebug() const { return msgLevel( MSG::DEBUG ); };
   bool printVerbose() const { return msgLevel( MSG::VERBOSE ); };
@@ -133,50 +121,54 @@ protected:
   LHCb::RecVertex* cloneVertex( const LHCb::RecVertex& vertex, const TrackContainer& selectedtracks ) const;
   bool             testNodes( const LHCb::Track& track ) const;
 
-  HistoUpdater* m_HistoUpdater;
+private:
+  // properties
+  Gaudi::Property<size_t> m_nIterations{this, "NumberOfIterations", 10u, "Number of iterations used on histogram axes"};
+  PublicToolHandle<IGetElementsToBeAligned> m_elementtool{
+      this, "AlignmentElements", "GetElementsToBeAligned"}; ///< Pointer to tool to align detector
+  Gaudi::Property<std::string>              m_tracksLocation{this, "TracksLocation", LHCb::TrackLocation::Default};
+  Gaudi::Property<std::string>              m_vertexLocation{this, "VertexLocation"}; ///< Vertices for alignment
+  Gaudi::Property<std::string>              m_dimuonLocation{this, "DimuonLocation"}; ///< J/psi vertcies for alignment
+  Gaudi::Property<std::string>              m_particleLocation{this,
+                                                  "ParticleLocation"}; ///< particles with mass constraint for alignment
+  ToolHandle<ITrackProjectorSelector>       m_projSelector{this, "ProjectorSelector",
+                                                     "TrackProjectorSelector"}; ///< Pointer to projector selector tool
+  PublicToolHandle<Al::ITrackResidualTool>  m_trackresidualtool{this, "TrackResidualTool", "Al::TrackResidualTool"};
+  PublicToolHandle<Al::IVertexResidualTool> m_vertexresidualtool{this, "VertexResidualTool", "Al::VertexResidualTool"};
+  PublicToolHandle<Al::IAlignUpdateTool>    m_updatetool{this, "UpdateTool", "Al::AlignUpdateTool"};
+  ToolHandle<ITrackSelector>                m_vertextrackselector{this, "VertexTrackSelector", "TrackSelector"};
+  PublicToolHandle<IWriteAlignmentConditionsTool> m_xmlWritersTool{this, "XmlWritersTool",
+                                                                   "WriteMultiAlignmentConditionsTool"};
+  Gaudi::Property<std::string>                    m_alignSummaryDataSvc{this, "AlignSummaryDataSvc", "DetectorDataSvc"};
+  Gaudi::Property<std::string> m_alignSummaryLocation{this, "AlignSummaryLocation", "AlignDerivativeData"};
+  Gaudi::Property<bool>        m_fillHistos{this, "FillHistos", false};
+
+  Gaudi::Property<bool>        m_correlation{this, "UseCorrelations",
+                                      true}; ///< Do we take into account correlations between residuals?
+  Gaudi::Property<bool>        m_updateInFinalize{this, "UpdateInFinalize", false}; ///< Call update from finalize
+  Gaudi::Property<double>      m_chi2Outlier{this, "Chi2Outlier", 1e4}; ///< Chi2 threshold for outlier rejection
+  Gaudi::Property<size_t>      m_minTracksPerVertex{this, "MinTracksPerVertex", 2};
+  Gaudi::Property<size_t>      m_maxTracksPerVertex{this, "MaxTracksPerVertex", 8};
+  Gaudi::Property<std::string> m_outputDataFileName{this, "OutputDataFile"};
+  Gaudi::Property<std::vector<std::string>> m_inputDataFileNames{this, "InputDataFiles"};
+  Gaudi::Property<long long>                m_forcedInitTime{
+      this, "ForcedInitialTime", 0,
+      "force the alignment geometry to initialize with this time (rather than first event)"};
+  Gaudi::Property<bool>                     m_Online{this, "OnlineMode", false};
+  Gaudi::Property<std::vector<std::string>> m_RunList{this, "RunList"};
 
 private:
-  size_t                                    m_iteration;        ///< Iteration counter
-  size_t                                    m_nIterations;      ///< Number of iterations
-  size_t                                    m_nTracks;          ///< Number of tracks used
-  size_t                                    m_covFailure;       ///< Number of covariance calculation failures
-  IGetElementsToBeAligned*                  m_align;            ///< Pointer to tool to align detector
-  std::string                               m_tracksLocation;   ///< Tracks for alignment
-  std::string                               m_vertexLocation;   ///< Vertices for alignment
-  std::string                               m_dimuonLocation;   ///< J/psi vertcies for alignment
-  std::string                               m_particleLocation; ///< particles with mass constraint for alignment
-  std::string                               m_projSelectorName; ///< Name of projector selector tool
-  ITrackProjectorSelector*                  m_projSelector;     ///< Pointer to projector selector tool
-  ToolHandle<Al::ITrackResidualTool>        m_trackresidualtool;
-  ToolHandle<Al::IVertexResidualTool>       m_vertexresidualtool;
-  ToolHandle<Al::IAlignUpdateTool>          m_updatetool;
-  ToolHandle<ITrackSelector>                m_vertextrackselector;
-  ToolHandle<IWriteAlignmentConditionsTool> m_xmlWritersTool;
-  //  std::vector<std::string>          m_xmlWriterNames ;
-  //  std::vector<IWriteAlignmentConditionsTool*> m_xmlWriters ;
-  std::string m_alignSummaryDataSvc;
-  std::string m_alignSummaryLocation;
-  bool        m_fillHistos;
-  bool        m_fireRunChange;
-
-  Al::Equations*           m_equations;          ///< Equations to solve
-  bool                     m_correlation;        ///< Do we take into account correlations between residuals?
-  bool                     m_updateInFinalize;   ///< Call update from finalize
-  double                   m_chi2Outlier;        ///< Chi2 threshold for outlier rejection
-  bool                     m_usePreconditioning; ///< Precondition the system of equations before calling solver
-  size_t                   m_minTracksPerVertex;
-  size_t                   m_maxTracksPerVertex;
-  std::string              m_outputDataFileName;
-  std::vector<std::string> m_inputDataFileNames;
-  unsigned int             m_runnr;
+  // state (some of these can be changed in to counters)
+  size_t         m_iteration{0u};      ///< Iteration counter
+  size_t         m_nTracks{0u};        ///< Number of tracks used
+  size_t         m_covFailure{0u};     ///< Number of covariance calculation failures
+  Al::Equations* m_equations{nullptr}; ///< Equations to solve
+  bool           m_fireRunChange{false};
+  unsigned int   m_runnr{0};
+  bool           m_resetHistos{false}; // reset histos on next event processing
+  HistoUpdater*  m_HistoUpdater{nullptr};
 
   /// Monitoring
   // @todo: Move this to a monitoring tool
   std::vector<AlElementHistos*> m_elemHistos;
-  bool                          m_resetHistos; // reset histos on next event processing
-  long long   m_forcedInitTime; // force the alignment geometry to initialize with this time (rather than first event)
-  bool        m_Online;
-  IAlignWork* m_IAlwork;
 };
-
-#endif // TALIGNMENT_ALIGNALGORITHM_H
diff --git a/Alignment/TAlignment/src/AlignChisqConstraintTool.cpp b/Alignment/TAlignment/src/AlignChisqConstraintTool.cpp
index 60b00943f5859b2dc6dacb74db75ca5e420cd2bf..f65033066b96c57687cc4e3a0ba067ebd37622a9 100644
--- a/Alignment/TAlignment/src/AlignChisqConstraintTool.cpp
+++ b/Alignment/TAlignment/src/AlignChisqConstraintTool.cpp
@@ -40,10 +40,9 @@ namespace Al {
     double         pivot[3];
   };
 
-  class AlignChisqConstraintTool : public GaudiTool, virtual public IAlignChisqConstraintTool {
+  class AlignChisqConstraintTool : public extends<GaudiTool, IAlignChisqConstraintTool> {
   public:
-    AlignChisqConstraintTool( const std::string& type, const std::string& name, const IInterface* parent );
-    ~AlignChisqConstraintTool();
+    using extends::extends;
     StatusCode          initialize() override;
     LHCb::ChiSquare     addConstraints( const Elements& elements, AlVec& halfDChi2DAlpha, AlSymMat& halfD2Chi2DAlpha2,
                                         std::ostream& stream ) const override;
@@ -59,9 +58,9 @@ namespace Al {
     const Gaudi::Vector6* findXmlUncertainty( const std::string& name ) const;
 
   private:
-    std::vector<std::string>                                m_constraintNames;
-    std::vector<std::string>                                m_xmlFiles;
-    std::vector<std::string>                                m_xmlUncertainties;
+    Gaudi::Property<std::vector<std::string>>               m_constraintNames{this, "Constraints"};
+    Gaudi::Property<std::vector<std::string>>               m_xmlFiles{this, "XmlFiles"};
+    Gaudi::Property<std::vector<std::string>>               m_xmlUncertainties{this, "XmlUncertainties"};
     typedef std::map<std::string, XmlSurveyData>            XmlData;
     XmlData                                                 m_xmldata;
     typedef std::vector<ConfiguredSurveyData>               ConstraintData;
@@ -74,18 +73,6 @@ namespace Al {
 
   DECLARE_COMPONENT( AlignChisqConstraintTool )
 
-  AlignChisqConstraintTool::~AlignChisqConstraintTool() {}
-
-  AlignChisqConstraintTool::AlignChisqConstraintTool( const std::string& type, const std::string& name,
-                                                      const IInterface* parent )
-      : GaudiTool( type, name, parent ) {
-    // interfaces
-    declareInterface<IAlignChisqConstraintTool>( this );
-    declareProperty( "Constraints", m_constraintNames );
-    declareProperty( "XmlFiles", m_xmlFiles );
-    declareProperty( "XmlUncertainties", m_xmlUncertainties );
-  }
-
   StatusCode AlignChisqConstraintTool::initialize() {
     StatusCode sc = GaudiTool::initialize();
     for ( std::vector<std::string>::const_iterator ifile = m_constraintNames.begin();
diff --git a/Alignment/TAlignment/src/AlignConstraintTool.cpp b/Alignment/TAlignment/src/AlignConstraintTool.cpp
index 841d76ac6166886ebb70724e50a79335a3b53dc1..2a522ce3cb64f3cb77f4aaf6da5450ae65192986 100755
--- a/Alignment/TAlignment/src/AlignConstraintTool.cpp
+++ b/Alignment/TAlignment/src/AlignConstraintTool.cpp
@@ -91,8 +91,8 @@ namespace Al {
   ConstraintDerivatives::ConstraintDerivatives( size_t dim, const std::vector<std::string>& activeconstraints,
                                                 const std::string& nameprefix, int offset )
       : m_dofmask( size_t( NumConstraints ) )
-      , m_derivatives( NumConstraints, dim )
-      , m_residuals( NumConstraints )
+      , m_derivatives{size_t( NumConstraints ), dim}
+      , m_residuals{size_t( NumConstraints )}
       , m_nameprefix( nameprefix )
       , m_activeParOffset( offset ) {
     std::vector<bool> active( NumConstraints, false );
@@ -107,11 +107,12 @@ namespace Al {
       boost::assign::list_of( "Tx" )( "Ty" )( "Tz" )( "Rx" )( "Ry" )( "Rz" )( "Szx" )( "Szy" )( "Szz" )( "Sxx" )(
           "SRz" )( "Trx" )( "Try" )( "Trtx" )( "Trty" )( "Trcur" )( "PVx" )( "PVy" )( "PVz" )( "Sz2x" )( "Sz2y" );
 
-  class AlignConstraintTool : public GaudiTool, virtual public IAlignConstraintTool {
+  class AlignConstraintTool : public extends<GaudiTool, IAlignConstraintTool> {
   public:
     typedef IGetElementsToBeAligned::Elements       Elements;
     typedef std::vector<Al::ConstraintDerivatives*> DerivativeContainer;
-    AlignConstraintTool( const std::string& type, const std::string& name, const IInterface* parent );
+
+    using extends::extends;
     ~AlignConstraintTool();
     StatusCode initialize() override;
 
@@ -153,26 +154,16 @@ namespace Al {
     };
 
   private:
-    std::vector<std::string>          m_constraintNames;
-    std::vector<std::string>          m_chiSquareConstraintNames;
-    std::vector<ConstraintDefinition> m_definitions;
-    mutable DerivativeContainer       m_derivatives;
-    bool                              m_useWeightedAverage;
-    bool                              m_fixRedundantMotherDofs;
-    const IGetElementsToBeAligned*    m_elementtool;
+    Gaudi::Property<std::vector<std::string>> m_constraintNames{this, "Constraints"};
+    Gaudi::Property<bool>                     m_useWeightedAverage{this, "UseWeightedAverage", false};
+    Gaudi::Property<bool>                     m_fixRedundantMotherDofs{this, "FixRedundantMotherDofs", false};
+    PublicToolHandle<IGetElementsToBeAligned> m_elementtool{this, "ElementTool", "GetElementsToBeAligned"};
+    std::vector<ConstraintDefinition>         m_definitions;
+    mutable DerivativeContainer               m_derivatives;
   };
 
   DECLARE_COMPONENT( AlignConstraintTool )
 
-  AlignConstraintTool::AlignConstraintTool( const std::string& type, const std::string& name, const IInterface* parent )
-      : GaudiTool( type, name, parent ), m_derivatives( 0 ) {
-    // interfaces
-    declareInterface<IAlignConstraintTool>( this );
-    declareProperty( "Constraints", m_constraintNames );
-    declareProperty( "UseWeightedAverage", m_useWeightedAverage = false );
-    declareProperty( "FixRedundantMotherDofs", m_fixRedundantMotherDofs = false );
-  }
-
   AlignConstraintTool::~AlignConstraintTool() { clearConstraintDerivatives(); }
 
 #include <string>
@@ -203,8 +194,6 @@ namespace Al {
     // check that constraints exist
     StatusCode sc = GaudiTool::initialize();
 
-    m_elementtool = tool<IGetElementsToBeAligned>( "GetElementsToBeAligned" );
-
     if ( sc.isSuccess() ) {
       // now we need to decode the string with constraints
       ConstraintDefinition common( "" );
@@ -480,6 +469,8 @@ namespace Al {
       AlVec    halfDChi2DAlphaNew( dim );
       AlSymMat halfD2Chi2DAlpha2New( dim );
 
+      debug() << "In AlignConstraintTool: before vec=" << halfDChi2DAlpha << endmsg;
+
       // copy the old matrices in there
       for ( size_t irow = 0; irow < numpars; ++irow ) {
         halfDChi2DAlphaNew( irow ) = halfDChi2DAlpha( irow );
@@ -490,6 +481,7 @@ namespace Al {
       // now add the constraints, only to the 2nd derivative (residuals are zero for now)
       for ( DerivativeContainer::const_iterator ic = m_derivatives.begin(); ic != m_derivatives.end(); ++ic )
         if ( ( *ic )->nActive() > 0 ) {
+          debug() << "residuals: " << ( *ic )->residuals() << endmsg;
           for ( size_t irow = 0; irow < Al::ConstraintDerivatives::NumConstraints; ++irow ) {
             int iactive = ( *ic )->activeParIndex( irow );
             if ( 0 <= iactive ) {
@@ -501,14 +493,17 @@ namespace Al {
 
           for ( size_t irow = 0; irow < Al::ConstraintDerivatives::NumConstraints; ++irow ) {
             int iactive = ( *ic )->activeParIndex( irow );
-            if ( 0 <= iactive )
+            if ( 0 <= iactive ) {
               halfDChi2DAlphaNew( ( *ic )->activeParOffset() + iactive ) = ( *ic )->residuals()( irow );
+              debug() << "constraint residual: " << ( *ic )->residuals()( irow ) << endmsg;
+            }
           }
         }
 
       // copy the result back
       halfDChi2DAlpha   = halfDChi2DAlphaNew;
       halfD2Chi2DAlpha2 = halfD2Chi2DAlpha2New;
+      debug() << "In AlignConstraintTool: after vec=" << halfDChi2DAlpha << endmsg;
     }
 
     return numactive;
@@ -527,11 +522,12 @@ namespace Al {
         totalmask.push_back( ( *ic )->dofMask() );
 
       // first extract the part concerning the lagrange multipliers
-      AlVec    lambda( numConstraintDerivatives );
-      AlSymMat covlambda( numConstraintDerivatives );
+      AlVec lambda{numConstraintDerivatives};
+      AlMat covlambda{numConstraintDerivatives, numConstraintDerivatives};
       for ( size_t i = 0u; i < numConstraintDerivatives; ++i ) {
-        lambda[i] = parameters[numPars + i];
-        for ( size_t j = 0u; j <= i; ++j ) covlambda[i][j] = covariance[numPars + i][numPars + j];
+        lambda( i ) = parameters[numPars + i];
+        for ( size_t j = 0u; j < numConstraintDerivatives; ++j )
+          covlambda( i, j ) = covariance( numPars + i, numPars + j );
       }
 
       // For a lagrage constraint defined as delta-chisqyare = 2 * lambda * constraint, the solution for lambda is
@@ -543,11 +539,10 @@ namespace Al {
       //   chisquare = - lambda * constraint
       // Note that this all needs to work for vectors.
 
-      AlSymMat V = -1 * covlambda; // Al$%$%^&$%&&*&^
-      int      ierr;
-      V.invert( ierr );
-      AlVec  x         = ( V * lambda ); // This might need a minus sign ...
-      double chisquare = ( lambda * V * lambda );
+      const auto   minusV    = covlambda.inverse();
+      const auto   V         = -minusV;
+      const auto   x         = V * lambda; // This might need a minus sign ...
+      const double chisquare = ( lambda.transpose() * V * lambda );
       logmessage << "Canonical constraint values: " << std::endl;
       for ( size_t iactive = 0u; iactive < numConstraintDerivatives; ++iactive ) {
         size_t parindex = totalmask.parIndex( iactive );
@@ -555,23 +550,23 @@ namespace Al {
                    << m_derivatives[parindex / Al::ConstraintDerivatives::NumConstraints]->name(
                           parindex % Al::ConstraintDerivatives::NumConstraints )
                    << std::setw( 12 ) << x( iactive ) << " "
-                   << " +/- " << std::setw( 12 ) << AlParameters::signedSqrt( V.fast( iactive, iactive ) )
-                   << " gcc^2: " << std::setw( 12 )
-                   << 1 + 1 / ( V.fast( iactive, iactive ) * covlambda.fast( iactive, iactive ) ) << std::endl;
+                   << " +/- " << std::setw( 12 ) << AlParameters::signedSqrt( V( iactive, iactive ) )
+                   << " gcc^2: " << std::setw( 12 ) << 1 + 1 / ( V( iactive, iactive ) * covlambda( iactive, iactive ) )
+                   << std::endl;
       }
       logmessage << "Canonical constraint chisquare: " << chisquare << std::endl;
 
       // Now the inactive constraints. Shrink the parameter and covariance matrix to the parameters only part
-      AlVec    subparameters( numPars );
-      AlSymMat subcovariance( numPars );
+      AlVec subparameters{numPars};
+      AlMat subcovariance{numPars, numPars};
       for ( size_t irow = 0; irow < numPars; ++irow ) {
         subparameters[irow] = parameters[irow];
-        for ( size_t icol = 0; icol <= irow; ++icol ) subcovariance.fast( irow, icol ) = covariance.fast( irow, icol );
+        for ( size_t icol = 0; icol < numPars; ++icol ) subcovariance( irow, icol ) = covariance( irow, icol );
       }
       // Calculate the delta
-      AlVec constraintdelta = m_derivatives.front()->derivatives() * subparameters;
-      AlMat constraintcov =
-          m_derivatives.front()->derivatives() * subcovariance * m_derivatives.front()->derivatives().T();
+      const auto derivatives     = m_derivatives.front()->derivatives();
+      const auto constraintdelta = derivatives * subparameters;
+      const auto constraintcov   = derivatives * subcovariance * derivatives.transpose();
 
       logmessage << "Values of constraint equations after solution (X=active,O=inactive): " << std::endl;
       for ( size_t i = 0; i < Al::ConstraintDerivatives::NumConstraints; ++i ) {
diff --git a/Alignment/TAlignment/src/AlignUpdateTool.cpp b/Alignment/TAlignment/src/AlignUpdateTool.cpp
index 911a55e7f1222fbaac2486b38ca660ae404a21ea..c30fb7a3572cfe1aa08802ab61a31c90a6a24dde 100755
--- a/Alignment/TAlignment/src/AlignUpdateTool.cpp
+++ b/Alignment/TAlignment/src/AlignUpdateTool.cpp
@@ -31,14 +31,16 @@
 
 namespace Al {
 
-  class AlignUpdateTool : public GaudiHistoTool, virtual public IAlignUpdateTool {
+  class AlignUpdateTool : public extends<GaudiHistoTool, IAlignUpdateTool> {
   public:
-    typedef IGetElementsToBeAligned::Elements Elements;
-    typedef std::vector<double>               AlignConstants;
-    AlignUpdateTool( const std::string& type, const std::string& name, const IInterface* parent );
-    ~AlignUpdateTool();
+    /// Typedefs etc.
+    using Elements       = IGetElementsToBeAligned::Elements;
+    using AlignConstants = std::vector<double>;
+
+    /// Standard constructor
+    using extends::extends;
+
     StatusCode initialize() override;
-    StatusCode finalize() override;
     StatusCode process( const Al::Equations& equations, size_t iter, size_t maxiter ) const override;
     StatusCode process( const Al::Equations& equations, ConvergenceStatus& convergencestatus ) const override;
     StatusCode process( const Al::Equations& equations, ConvergenceStatus& convergencestatus, size_t iter,
@@ -64,81 +66,45 @@ namespace Al {
     static double computeLookElsewhereChi2Cut( double chi2, double n );
 
   private:
-    std::string                           m_matrixSolverToolName; ///< Name of linear algebra solver tool
-    IAlignSolvTool*                       m_matrixSolverTool;     ///< Pointer to linear algebra solver tool
-    IGetElementsToBeAligned*              m_elementProvider;
-    ToolHandle<IAlignConstraintTool>      m_lagrangeconstrainttool;
-    ToolHandle<IAlignChisqConstraintTool> m_chisqconstrainttool;
-    size_t                                m_minNumberOfHits; ///< Minimum number of hits for an Alignable to be aligned
-    bool                       m_usePreconditioning; ///< Precondition the system of equations before calling solver
-    double                     m_maxDeltaChi2PDofForConvergence;
-    double                     m_maxModeDeltaChi2ForConvergence;
-    std::string                m_logFileName;
-    mutable std::ostringstream m_logMessage;
-    mutable unsigned int       m_iteration;
+    PublicToolHandle<IAlignSolvTool>          m_matrixSolverTool{this, "MatrixSolverTool", "EigenDiagSolvTool",
+                                                        "Linear algebra solver tool"};
+    PublicToolHandle<IGetElementsToBeAligned> m_elementProvider{this, "ElementProvider", "GetElementsToBeAligned"};
+    ToolHandle<IAlignConstraintTool>          m_lagrangeconstrainttool{this, "LagrangeConstraintTool",
+                                                              "Al::AlignConstraintTool"};
+    ToolHandle<IAlignChisqConstraintTool>     m_chisqconstrainttool{this, "SurveyConstraintTool",
+                                                                "Al::AlignChisqConstraintTool"};
+    Gaudi::Property<size_t>                   m_minNumberOfHits{this, "MinNumberOfHits", 100u,
+                                              "Minimum number of hits for an Alignable to be aligned"};
+    Gaudi::Property<bool>                     m_usePreconditioning{this, "UsePreconditioning", true,
+                                               "Precondition the system of equations before calling solver"};
+    Gaudi::Property<double>      m_maxDeltaChi2PDofForConvergence{this, "MaxDeltaChi2PDofForConvergence", 4};
+    Gaudi::Property<double>      m_maxModeDeltaChi2ForConvergence{this, "MaxModeDeltaChi2ForConvergence", 25};
+    Gaudi::Property<std::string> m_logFileName{this, "LogFile", "alignlog.txt"};
+    Gaudi::Property<bool> m_skipGeometryUpdate{this, "SkipGeometryUpdate", false, "Skip the update of the geometry"};
+    mutable std::ostringstream            m_logMessage;
+    mutable unsigned int                  m_iteration{0};
     mutable std::map<std::string, double> m_initConsts;
     mutable std::map<std::string, double> m_finalConsts;
   };
 
   DECLARE_COMPONENT( AlignUpdateTool )
 
-  AlignUpdateTool::AlignUpdateTool( const std::string& type, const std::string& name, const IInterface* parent )
-      : GaudiHistoTool( type, name, parent )
-      , m_lagrangeconstrainttool( "Al::AlignConstraintTool", this )
-      , m_chisqconstrainttool( "Al::AlignChisqConstraintTool", this )
-      , m_iteration( 0 ) {
-    // interfaces
-    declareInterface<IAlignUpdateTool>( this );
-    declareProperty( "MatrixSolverTool", m_matrixSolverToolName = "SpmInvTool" );
-    declareProperty( "MinNumberOfHits", m_minNumberOfHits = 100u );
-    declareProperty( "UsePreconditioning", m_usePreconditioning = true );
-    declareProperty( "LogFile", m_logFileName = "alignlog.txt" );
-    declareProperty( "SurveyConstraintTool", m_chisqconstrainttool );
-    declareProperty( "LagrangeConstraintTool", m_lagrangeconstrainttool );
-    declareProperty( "MaxDeltaChi2PDofForConvergence", m_maxDeltaChi2PDofForConvergence = 4 );
-    declareProperty( "MaxModeDeltaChi2ForConvergence", m_maxModeDeltaChi2ForConvergence = 25 );
-  }
-
-  AlignUpdateTool::~AlignUpdateTool() {}
-
   StatusCode AlignUpdateTool::initialize() {
     // check that constraints exist
     StatusCode sc = GaudiHistoTool::initialize();
     if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm
-    setHistoTopDir( "" );
-    setHistoDir( "Alignment" );
-
-    // Get tool to align detector, from the tool service
-    m_elementProvider = tool<IGetElementsToBeAligned>( "GetElementsToBeAligned" );
-    if ( !m_elementProvider ) return Error( "==> Failed to retrieve detector selector tool!", StatusCode::FAILURE );
-
-    // Get the constraint tool, also from the toolsvc
-    sc = m_lagrangeconstrainttool.retrieve();
-    if ( !sc.isSuccess() ) return Error( "==> Failed to retrieve lagrange constraint tool!", StatusCode::FAILURE );
-
-    // Get the constraint tool, also from the toolsvc
-    sc = m_chisqconstrainttool.retrieve();
-    if ( !sc.isSuccess() ) return Error( "==> Failed to retrieve chisq constraint tool!", StatusCode::FAILURE );
-
-    // Get matrix solver tool
-    // m_matrixSolverTool = tool<IAlignSolvTool>(m_matrixSolverToolName, "MatrixSolver", this);
-    m_matrixSolverTool = tool<IAlignSolvTool>( m_matrixSolverToolName );
-    if ( !m_matrixSolverTool ) return Error( "==> Failed to retrieve matrix solver tool", StatusCode::FAILURE );
-
+    if ( name() == std::string( "ToolSvc.AlignUpdateTool" ) ) {
+      setHistoTopDir( "" );
+      setHistoDir( "Alignment" );
+    }
     return sc;
   }
 
-  StatusCode AlignUpdateTool::finalize() {
-    m_lagrangeconstrainttool.release().ignore();
-    m_chisqconstrainttool.release().ignore();
-    return GaudiHistoTool::finalize();
-  }
-
   void AlignUpdateTool::preCondition( const Elements& elements, const Al::Equations& equations, AlVec& halfDChi2DAlpha,
                                       AlSymMat& halfD2Chi2DAlpha2, AlVec& scale ) const {
     // This is just not sufficiently fool proof!
-    size_t size = halfDChi2DAlpha.size();
-    scale.reSize( size );
+    size_t size = halfDChi2DAlpha.rows();
+    scale       = AlVec{size};
     size_t ipar( 0 );
     // initialize all scales with 1
     for ( ipar = 0u; ipar < size; ++ipar ) scale[ipar] = 1;
@@ -151,7 +117,7 @@ namespace Al {
         size_t N    = std::max( equations.element( iElem ).numHits(), size_t( 1 ) );
         for ( ipar = offset; ipar < offset + ndof; ++ipar ) {
           assert( ipar < size );
-          if ( halfD2Chi2DAlpha2[ipar][ipar] > 0 ) scale[ipar] = std::sqrt( N / halfD2Chi2DAlpha2[ipar][ipar] );
+          if ( halfD2Chi2DAlpha2( ipar, ipar ) > 0 ) scale[ipar] = std::sqrt( N / halfD2Chi2DAlpha2( ipar, ipar ) );
         }
       }
     }
@@ -177,25 +143,25 @@ namespace Al {
       // into account the scales of the parameters)
       double norm2( 0 );
       for ( size_t jpar = 0; jpar < numParameters; ++jpar ) {
-        double derivative = halfD2Chi2DAlpha2[ipar][jpar] * scale[jpar];
+        double derivative = halfD2Chi2DAlpha2( ipar, jpar ) * scale( jpar );
         norm2 += derivative * derivative;
       }
       // now set the scale
-      if ( norm2 > 0 ) scale[ipar] = defaultnorm / std::sqrt( norm2 ) * ( ipar - numParameters + 1 );
+      if ( norm2 > 0 ) scale( ipar ) = defaultnorm / std::sqrt( norm2 ) * ( ipar - numParameters + 1 );
     }
 
     // now apply the scales
     for ( size_t i = 0u, iEnd = size; i < iEnd; ++i ) {
-      halfDChi2DAlpha[i] *= scale[i];
-      for ( size_t j = 0u; j <= i; ++j ) halfD2Chi2DAlpha2[i][j] *= scale[i] * scale[j];
+      halfDChi2DAlpha( i ) *= scale( i );
+      for ( size_t j = 0u; j <= i; ++j ) halfD2Chi2DAlpha2( i, j ) *= scale( i ) * scale( j );
     }
   }
 
   void AlignUpdateTool::postCondition( AlVec& halfDChi2DAlpha, AlSymMat& halfD2Chi2DAlpha2, const AlVec& scale ) const {
     size_t size = halfDChi2DAlpha.size();
     for ( size_t i = 0u, iEnd = size; i < iEnd; ++i ) {
-      halfDChi2DAlpha[i] *= scale[i];
-      for ( size_t j = 0u; j <= i; ++j ) halfD2Chi2DAlpha2[i][j] *= scale[i] * scale[j];
+      halfDChi2DAlpha( i ) *= scale( i );
+      for ( size_t j = 0u; j <= i; ++j ) halfD2Chi2DAlpha2( i, j ) *= scale( i ) * scale( j );
     }
   }
 
@@ -359,9 +325,15 @@ namespace Al {
 
   bool AlignUpdateTool::checkGeometry( const Al::Equations& equations ) const {
     // test that the alignment constants in AlEquations actually correspond to what is in the geometry
-    const double    maxmag2     = 1e-10; // could be finetuned a bit
-    bool            checkpassed = true;
-    const Elements& elements    = m_elementProvider->elements();
+    const Elements& elements = m_elementProvider->elements();
+    if ( elements.size() != equations.nElem() ) {
+      error() << "Number of elements in elementprovider and equations do not match:" << elements.size() << " "
+              << equations.nElem() << endmsg;
+      return false;
+    }
+
+    const double maxmag2     = 1e-10; // could be finetuned a bit
+    bool         checkpassed = true;
     for ( auto ielem : elements ) {
       bool thisBad = false;
       // compare the current delta
@@ -403,7 +375,8 @@ namespace Al {
     if ( m_elementProvider->initTime() != equations.initTime() || !checkGeometry( constequations ) ) {
       warning() << "Geometry does not match AlEquations: " << m_elementProvider->initTime().ns() << " "
                 << equations.initTime().ns() << ". Will reinitalize alignment frame." << endmsg;
-      sc = m_elementProvider->initAlignmentFrame( equations.initTime() );
+      auto nonconstelementprovider = const_cast<IGetElementsToBeAligned*>( &( *m_elementProvider ) );
+      sc                           = nonconstelementprovider->initAlignmentFrame( equations.initTime() );
       if ( !sc.isSuccess() ) return sc;
     }
 
@@ -418,7 +391,6 @@ namespace Al {
       return sc;
     }
 
-    info() << "\n";
     debug() << "==> iteration " << iteration << " : Initial alignment conditions  : [";
     const Elements& elements = m_elementProvider->elements();
     // Store constants before the update
@@ -552,6 +524,17 @@ namespace Al {
         info() << "AlSymMat Matrix = " << halfD2Chi2dX2 << endmsg;
       } else {
         info() << "Matrices too big to dump to std" << endmsg;
+        // check that second derivative looks okay:
+        // 1. check diagonal elements:
+        for ( size_t i = 0; i < numParameters; ++i )
+          if ( halfD2Chi2dX2( i, i ) <= 0 )
+            info() << "Negative diagonal element: " << i << " " << halfD2Chi2dX2( i, i ) << endmsg;
+        for ( size_t i = 0; i < numParameters; ++i )
+          for ( size_t j = 0; j < i; ++j ) {
+            const auto eta = halfD2Chi2dX2( i, j ) / std::sqrt( halfD2Chi2dX2( i, i ) * halfD2Chi2dX2( j, j ) );
+            if ( eta < -1 || eta > 1 )
+              info() << "Off-diagonal element out of range: i, j, eta:" << i << "," << j << "," << eta << endmsg;
+          }
       }
 
       // Tool returns H^-1 and alignment constants. Need to copy the 2nd derivative because we still need it.
@@ -564,17 +547,26 @@ namespace Al {
       }
       info() << "Calling solver tool" << endmsg;
       IAlignSolvTool::SolutionInfo solinfo;
-      sc = m_matrixSolverTool->compute( covmatrix, solution, solinfo );
+      using clock   = std::chrono::high_resolution_clock;
+      const auto t1 = clock::now();
+      sc            = m_matrixSolverTool->compute( covmatrix, solution, solinfo );
+      const auto t2 = clock::now();
+      logmessage << "Time to compute solution [ms]: "
+                 << std::chrono::duration<double, std::nano>( t2 - t1 ).count() * 1.0e-6 << std::endl;
       if ( sc.isSuccess() ) {
-
         // undo the scaling
         if ( m_usePreconditioning ) {
           info() << "Applying post-conditioning" << endmsg;
           postCondition( solution, covmatrix, scale );
         }
 
+        // test the numerical accuracy of the solution
+        const AlVec  errorvec = halfD2Chi2dX2 * solution - halfDChi2dX;
+        const double error2   = errorvec.dot( errorvec );
+        logmessage << "Error2: " << error2 << std::endl;
+
         info() << "computing delta-chi2" << endmsg;
-        double deltaChi2 = solution * halfDChi2dX; // somewhere we have been a bit sloppy with two minus signs!
+        double deltaChi2 = solution.dot( halfDChi2dX ); // somewhere we have been a bit sloppy with two minus signs!
         if ( deltaChi2 < 0 ) {
           error() << "Serious problem in update: delta-chi2 is negative: " << deltaChi2 << endmsg;
           //<< "Will recopute solution without scaling to see what that does! " << endmsg ;
@@ -656,8 +648,9 @@ namespace Al {
                          << " curtot= " << std::setw( 12 ) << reftotaldelta.parameters()[iactive]
                          << " cur= " << std::setw( 12 ) << refdelta.parameters()[iactive]
                          << " delta= " << std::setw( 12 ) << delta.parameters()[iactive] << " +/- " << std::setw( 12 )
-                         << AlParameters::signedSqrt( delta.covariance()[iactive][iactive] ) << " [ " << std::setw( 12 )
-                         << AlParameters::signedSqrt( 1 / delta.weightMatrix()[iactive][iactive] ) << " ] "
+                         << AlParameters::signedSqrt( delta.covariance()( iactive, iactive ) ) << " [ "
+                         << std::setw( 12 ) << AlParameters::signedSqrt( 1 / delta.weightMatrix()( iactive, iactive ) )
+                         << " ] "
                          << " gcc= " << delta.globalCorrelationCoefficient( iactive ) << std::endl;
             double contributionToCoordinateError = delta.measurementCoordinateSigma( elemdata.weightR() );
             double coordinateError               = std::sqrt( elemdata.numHits() / elemdata.weightV() );
@@ -676,8 +669,10 @@ namespace Al {
             totalLocalDeltaChi2 += thisLocalDeltaChi2;
 
             // need const_cast because loki range givess access only to const values
-            StatusCode sc = ( const_cast<AlignmentElement*>( *it ) )->updateGeometry( delta );
-            if ( !sc.isSuccess() ) error() << "Failed to set alignment condition for " << ( *it )->name() << endmsg;
+            if ( !m_skipGeometryUpdate ) {
+              StatusCode sc = ( const_cast<AlignmentElement*>( *it ) )->updateGeometry( delta );
+              if ( !sc.isSuccess() ) error() << "Failed to set alignment condition for " << ( *it )->name() << endmsg;
+            }
 
             std::string name    = ( *it )->name();
             std::string dirname = "element" + boost::lexical_cast<std::string>( ( *it )->index() ) + "/"; // name + "/"
@@ -768,7 +763,7 @@ namespace Al {
 
     // FIXME: we don't want to do this on every update! Yet, we cannot wait for finalize in online.
     if ( !m_logFileName.empty() ) {
-      std::ofstream logfile( m_logFileName.c_str() );
+      std::ofstream logfile( m_logFileName.value().c_str() );
       logfile << m_logMessage.str() << std::endl;
     }
     return sc;
diff --git a/Alignment/TAlignment/src/CountingPrescaler.cpp b/Alignment/TAlignment/src/CountingPrescaler.cpp
index 4dc4b00142c936b130e4a1a924944e127bd24384..9803d7f13a0c0e382bf5ae8ecf2284d74ae1eb9a 100644
--- a/Alignment/TAlignment/src/CountingPrescaler.cpp
+++ b/Alignment/TAlignment/src/CountingPrescaler.cpp
@@ -16,27 +16,19 @@
 class CountingPrescaler : public GaudiAlgorithm {
 
 public:
-  // Constructors and destructor
-  CountingPrescaler( const std::string& name, ISvcLocator* pSvcLocator );
+  using GaudiAlgorithm::GaudiAlgorithm;
   StatusCode initialize() override;
   StatusCode execute() override;
 
 private:
-  size_t m_interval;
-  size_t m_offset;
-  size_t m_printfreq;
-  size_t m_counter;
+  Gaudi::Property<size_t> m_interval{this, "Interval", 1};
+  Gaudi::Property<size_t> m_offset{this, "Offset", 0};
+  Gaudi::Property<size_t> m_printfreq{this, "PrintFreq", 0};
+  size_t                  m_counter{0};
 };
 
 DECLARE_COMPONENT( CountingPrescaler )
 
-CountingPrescaler::CountingPrescaler( const std::string& name, ISvcLocator* pSvcLocator )
-    : GaudiAlgorithm( name, pSvcLocator ), m_counter( 0 ) {
-  declareProperty( "Interval", m_interval = 1 );
-  declareProperty( "Offset", m_offset = 0 );
-  declareProperty( "PrintFreq", m_printfreq = 0 );
-}
-
 StatusCode CountingPrescaler::initialize() {
   info() << "Interval, offset = " << m_interval << ", " << m_offset << endmsg;
   m_counter = 0;
diff --git a/Alignment/TAlignment/src/GetElementsToBeAligned.cpp b/Alignment/TAlignment/src/GetElementsToBeAligned.cpp
index e96584e94b260e64fe3c5df5953c2d061d4e959e..23091e87c6eca006eaaf122f163cb67ffa740c8e 100755
--- a/Alignment/TAlignment/src/GetElementsToBeAligned.cpp
+++ b/Alignment/TAlignment/src/GetElementsToBeAligned.cpp
@@ -46,16 +46,6 @@
 // Declaration of the Tool Factory
 DECLARE_COMPONENT( GetElementsToBeAligned )
 
-GetElementsToBeAligned::GetElementsToBeAligned( const std::string& type, const std::string& name,
-                                                const IInterface* parent )
-    : GaudiTool( type, name, parent ), m_useLocalFrame( true ), m_elemsToBeAligned(), m_elementMap(), m_initTime( 0 ) {
-  declareInterface<IGetElementsToBeAligned>( this );
-  declareProperty( "Elements", m_elemsToBeAligned );
-  declareProperty( "UseLocalFrame", m_useLocalFrame );
-}
-
-GetElementsToBeAligned::~GetElementsToBeAligned() {}
-
 StatusCode GetElementsToBeAligned::initialize() {
 
   StatusCode sc = GaudiTool::initialize();
diff --git a/Alignment/TAlignment/src/GetElementsToBeAligned.h b/Alignment/TAlignment/src/GetElementsToBeAligned.h
index d868fb3b21d9d13a0c6958498b4db2bb102072dc..c1dadd1f8cfa026b2dbb1c761e688bbc3fb9d84c 100755
--- a/Alignment/TAlignment/src/GetElementsToBeAligned.h
+++ b/Alignment/TAlignment/src/GetElementsToBeAligned.h
@@ -8,9 +8,7 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// $Id: GetElementsToBeAligned.h,v 1.17 2010-02-19 08:54:36 rlambert Exp $
-#ifndef GETELEMENTSTOBEALIGNED_H
-#define GETELEMENTSTOBEALIGNED_H 1
+#pragma once
 
 // Include files
 // from STL
@@ -37,8 +35,7 @@
  *  @date   2007-10-08
  */
 
-class GetElementsToBeAligned : public GaudiTool, virtual public IGetElementsToBeAligned {
-
+class GetElementsToBeAligned : public extends<GaudiTool, IGetElementsToBeAligned> {
 public:
   typedef IDetectorElement::IDEContainer::const_iterator IDetIter;  ///< IDetector element iterator
   typedef boost::char_separator<char>                    Separator; ///< Char separator
@@ -46,9 +43,7 @@ public:
   typedef std::list<boost::regex>                        RegExs;    ///< List of regular expressions
 
   /// Standard constructor
-  GetElementsToBeAligned( const std::string& type, const std::string& name, const IInterface* parent );
-
-  ~GetElementsToBeAligned(); ///< Destructor
+  using extends::extends;
 
   StatusCode initialize() override;
   StatusCode finalize() override;
@@ -134,12 +129,10 @@ private:
   };
 
 private:
-  bool                                      m_useLocalFrame;    ///< Use local frame as alignmentframe
-  std::vector<std::string>                  m_elemsToBeAligned; ///< Elemenst : Path to elements
-  mutable IGetElementsToBeAligned::Elements m_elements;         ///< Flat vector of alignment elements
-  typedef std::map<const DetectorElement*, const AlignmentElement*> ElementMap;
+  Gaudi::Property<bool> m_useLocalFrame{this, "UseLocalFrame", true};             ///< Use local frame as alignmentframe
+  Gaudi::Property<std::vector<std::string>> m_elemsToBeAligned{this, "Elements"}; ///< Elemenst : Path to elements
+  mutable IGetElementsToBeAligned::Elements m_elements;                           ///< Flat vector of alignment elements
+  using ElementMap = std::map<const DetectorElement*, const AlignmentElement*>;
   ElementMap  m_elementMap; ///< Map of detector elements to alignment element
-  Gaudi::Time m_initTime;
+  Gaudi::Time m_initTime{0};
 };
-
-#endif // GETELEMENTSTOBEALIGNED_H
diff --git a/Alignment/TAlignment/src/IAlignChisqConstraintTool.h b/Alignment/TAlignment/src/IAlignChisqConstraintTool.h
index 6433ef2dc11eaaba7592d9ad895b5618a1c8cc52..ace5c906de6e6562a649447106f04492f7935ee7 100644
--- a/Alignment/TAlignment/src/IAlignChisqConstraintTool.h
+++ b/Alignment/TAlignment/src/IAlignChisqConstraintTool.h
@@ -8,36 +8,27 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-#ifndef TALIGNMENT_IALIGNCHISQCONSTRAINTTOOL_H
-#  define TALIGNMENT_IALIGNCHISQCONSTRAINTTOOL_H
+#pragma once
 
-#  include "AlignKernel/AlEquations.h"
-#  include "AlignKernel/AlSymMat.h"
-#  include "AlignKernel/AlVec.h"
-#  include "Event/ChiSquare.h"
-#  include "GaudiKernel/IAlgTool.h"
-#  include "IGetElementsToBeAligned.h"
+#include "AlignKernel/AlEquations.h"
+#include "AlignKernel/AlSymMat.h"
+#include "AlignKernel/AlVec.h"
+#include "Event/ChiSquare.h"
+#include "GaudiKernel/IAlgTool.h"
+#include "IGetElementsToBeAligned.h"
 
 namespace Al {
-  /// Static ID object
-  static const InterfaceID IID_IAlignChisqConstraintTool( "Al::IAlignChisqConstraintTool", 0, 0 );
+  struct IAlignChisqConstraintTool : public extend_interfaces<IAlgTool> {
+    DeclareInterfaceID( IAlignChisqConstraintTool, 2, 0 );
 
-  class IAlignChisqConstraintTool : virtual public IAlgTool {
-  public:
     typedef IGetElementsToBeAligned::Elements Elements;
 
-    // Retrieve interface ID
-    static const InterfaceID& interfaceID() { return IID_IAlignChisqConstraintTool; }
-    virtual LHCb::ChiSquare   addConstraints( const Elements& elements, AlVec& halfDChi2DAlpha,
-                                              AlSymMat& halfD2Chi2DAlpha2, std::ostream& logmessage ) const = 0;
-    virtual LHCb::ChiSquare   addConstraints( const Elements& inputelements, Al::Equations& equations,
-                                              std::ostream& logmessage ) const                              = 0;
-    virtual LHCb::ChiSquare   chiSquare( const AlignmentElement& element, bool activeonly = true ) const    = 0;
+    virtual LHCb::ChiSquare addConstraints( const Elements& elements, AlVec& halfDChi2DAlpha,
+                                            AlSymMat& halfD2Chi2DAlpha2, std::ostream& logmessage ) const = 0;
+    virtual LHCb::ChiSquare addConstraints( const Elements& inputelements, Al::Equations& equations,
+                                            std::ostream& logmessage ) const                              = 0;
+    virtual LHCb::ChiSquare chiSquare( const AlignmentElement& element, bool activeonly = true ) const    = 0;
     // this returns the survey in the AlignmentFrame of the element, taking correlations into account.
     virtual const AlParameters* surveyParameters( const AlignmentElement& element ) const = 0;
   };
 } // namespace Al
-
-#endif
-
-//  LocalWords:  TALIGNMENT
diff --git a/Alignment/TAlignment/src/IAlignConstraintTool.h b/Alignment/TAlignment/src/IAlignConstraintTool.h
index e8342a046e9ddfc76091143cc527d17f3058453d..5cd9949f41bbda9e002223a2f066cb9d8b46576a 100755
--- a/Alignment/TAlignment/src/IAlignConstraintTool.h
+++ b/Alignment/TAlignment/src/IAlignConstraintTool.h
@@ -8,8 +8,7 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-#ifndef TALIGNMENT_IALIGNCONSTRAINTTOOL_H
-#define TALIGNMENT_IALIGNCONSTRAINTTOOL_H
+#pragma once
 
 #include "AlignKernel/AlEquations.h"
 #include "AlignKernel/AlSymMat.h"
@@ -18,16 +17,11 @@
 #include "IGetElementsToBeAligned.h"
 
 namespace Al {
-  /// Static ID object
-  static const InterfaceID IID_IAlignConstraintTool( "Al::IAlignConstraintTool", 0, 0 );
+  struct IAlignConstraintTool : public extend_interfaces<IAlgTool> {
+    DeclareInterfaceID( IAlignConstraintTool, 2, 0 );
 
-  class IAlignConstraintTool : virtual public IAlgTool {
-  public:
     typedef IGetElementsToBeAligned::Elements Elements;
 
-    // Retrieve interface ID
-    static const InterfaceID& interfaceID() { return IID_IAlignConstraintTool; }
-
     virtual size_t addConstraints( const Elements& elements, const Al::Equations& equations, AlVec& halfDChi2DAlpha,
                                    AlSymMat& halfD2Chi2DAlpha2 ) const = 0;
 
@@ -35,5 +29,3 @@ namespace Al {
                                    std::ostream& logmessage ) const = 0;
   };
 } // namespace Al
-
-#endif
diff --git a/Alignment/TAlignment/src/IGetElementsToBeAligned.h b/Alignment/TAlignment/src/IGetElementsToBeAligned.h
index 2d09e3771dc49b42bf8d7c5c838362175b0b2348..26e608b5609051cd15c34469055d75ba8be21223 100755
--- a/Alignment/TAlignment/src/IGetElementsToBeAligned.h
+++ b/Alignment/TAlignment/src/IGetElementsToBeAligned.h
@@ -30,8 +30,6 @@
 /// Local
 #include "AlignmentElement.h"
 
-static const InterfaceID IID_IGetElementsToBeAligned( "IGetElementsToBeAligned", 1, 0 );
-
 /** @class IGetElementsToBeAligned IGetElementsToBeAligned.h
  *
  *
@@ -52,13 +50,13 @@ namespace Al {
   class Equations;
 }
 
-class IGetElementsToBeAligned : virtual public IAlgTool {
+class IGetElementsToBeAligned : public extend_interfaces<IAlgTool> {
 
 public:
   typedef std::vector<const AlignmentElement*> Elements;
 
   // Return the interface ID
-  static const InterfaceID& interfaceID() { return IID_IGetElementsToBeAligned; };
+  DeclareInterfaceID( IGetElementsToBeAligned, 2, 0 );
 
   // Return pair of forward begin iter and forward end iter
   virtual const Elements& elements() const = 0;
diff --git a/Alignment/TAlignment/src/ITrackResidualTool.h b/Alignment/TAlignment/src/ITrackResidualTool.h
index 98b62452b0c173c1877a209789e66e5b03de3d51..51d8b4df3ac8e6e9cc0799eeae44470da61627f1 100755
--- a/Alignment/TAlignment/src/ITrackResidualTool.h
+++ b/Alignment/TAlignment/src/ITrackResidualTool.h
@@ -17,16 +17,12 @@
 namespace LHCb {}
 
 namespace Al {
-  /// Static ID object
-  static const InterfaceID IID_ITrackResidualTool( "Al::ITrackResidualTool", 0, 0 );
-
-  class ITrackResidualTool : virtual public IAlgTool {
-  public:
-    // Retrieve interface ID
-    static const InterfaceID& interfaceID() { return IID_ITrackResidualTool; }
-
+  struct ITrackResidualTool : public extend_interfaces<IAlgTool> {
+    DeclareInterfaceID( ITrackResidualTool, 2, 0 );
     // the only method
     virtual const Al::TrackResiduals* get( const LHCb::Track& track ) const = 0;
+    // and just another one, temporarily
+    virtual void clearCache() const = 0;
   };
 } // namespace Al
 
diff --git a/Alignment/TAlignment/src/IVertexResidualTool.h b/Alignment/TAlignment/src/IVertexResidualTool.h
index 72cc16b3ab90495dffcefe82aa26bc9fec6fa536..1a9895258226bef85fca45cac35135e5e321a9a8 100755
--- a/Alignment/TAlignment/src/IVertexResidualTool.h
+++ b/Alignment/TAlignment/src/IVertexResidualTool.h
@@ -8,8 +8,7 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-#ifndef TALIGNMENT_IVERTEXRESIDUALTOOL_H
-#define TALIGNMENT_IVERTEXRESIDUALTOOL_H
+#pragma once
 
 #include "AlResiduals.h"
 #include "Event/Track.h"
@@ -20,21 +19,15 @@ namespace LHCb {
 } // namespace LHCb
 
 namespace Al {
-  /// Static ID object
-  static const InterfaceID IID_IVertexResidualTool( "Al::IVertexResidualTool", 0, 0 );
 
-  class IVertexResidualTool : virtual public IAlgTool {
-  public:
-    // Retrieve interface ID
-    static const InterfaceID& interfaceID() { return IID_IVertexResidualTool; }
+  struct IVertexResidualTool : public extend_interfaces<IAlgTool> {
+    DeclareInterfaceID( IVertexResidualTool, 2, 0 );
 
     // the only method
-    typedef std::vector<const LHCb::Track*> TrackContainer;
+    using ReturnType = std::unique_ptr<const Al::MultiTrackResiduals>;
     // process a vertex (primary vertex of twoprongvertex)
-    virtual const Al::MultiTrackResiduals* get( const LHCb::RecVertex& vertex ) const = 0;
+    virtual ReturnType get( const LHCb::RecVertex& vertex ) const = 0;
     // process a particle. this applies a mass constraint.
-    virtual const Al::MultiTrackResiduals* get( const LHCb::Particle& p ) const = 0;
+    virtual ReturnType get( const LHCb::Particle& p ) const = 0;
   };
 } // namespace Al
-
-#endif
diff --git a/Alignment/TAlignment/src/TrackResidualTool.cpp b/Alignment/TAlignment/src/TrackResidualTool.cpp
index 1ccbafb5c5709e4b22ddc87d966672fc90848260..81939639498f7193ed2c73dadc4b054a6576d2d9 100755
--- a/Alignment/TAlignment/src/TrackResidualTool.cpp
+++ b/Alignment/TAlignment/src/TrackResidualTool.cpp
@@ -22,31 +22,33 @@
 
 namespace Al {
 
-  class TrackResidualTool : public GaudiTool, virtual public ITrackResidualTool, virtual public IIncidentListener {
+  class TrackResidualTool : public extends<GaudiTool, ITrackResidualTool>, virtual public IIncidentListener {
   public:
     // constructor
-    TrackResidualTool( const std::string& type, const std::string& name, const IInterface* parent );
-    // destructor
-    ~TrackResidualTool(){};
+    using extends::extends;
     // initialisation
     StatusCode initialize() override;
-    // finalize
-    StatusCode finalize() override;
     // incident service handle
     void handle( const Incident& incident ) override;
+
+    // clear the cache
+    void clearCache() const override { m_residuals.clear(); }
+
     // get the residuals for this track
     const Al::TrackResiduals* get( const LHCb::Track& track ) const override;
 
+    std::unique_ptr<Al::TrackResiduals> compute( const LHCb::Track& track ) const;
+
   private:
-    const Al::TrackResiduals* compute( const LHCb::Track& track ) const;
-    Al::TrackResiduals*       create( const LHCb::Track& track, const std::vector<const LHCb::FitNode*>& nodes,
-                                      std::vector<size_t>& residualnodeindices, size_t& refnodeindex ) const;
+    std::unique_ptr<Al::TrackResiduals> create( const LHCb::Track&                       track,
+                                                const std::vector<const LHCb::FitNode*>& nodes,
+                                                std::vector<size_t>& residualnodeindices, size_t& refnodeindex ) const;
 
   private:
-    typedef std::map<const LHCb::Track*, const Al::TrackResiduals*> ResidualMap;
-    mutable ResidualMap                                             m_residuals;
-    bool                                                            m_testPosDef;
-    ToolHandle<IGetElementsToBeAligned>                             m_elementTool;
+    using ResidualMap = std::map<const LHCb::Track*, std::unique_ptr<Al::TrackResiduals>>;
+    mutable ResidualMap                       m_residuals;
+    Gaudi::Property<bool>                     m_testPosDef{this, "TestPosDef", false};
+    PublicToolHandle<IGetElementsToBeAligned> m_elementTool{this, "ElementTool", "GetElementsToBeAligned"};
   };
 
 } // namespace Al
@@ -61,82 +63,62 @@ namespace Al {
 
   DECLARE_COMPONENT( TrackResidualTool )
 
-  TrackResidualTool::TrackResidualTool( const std::string& type, const std::string& name, const IInterface* parent )
-      : GaudiTool( type, name, parent ), m_elementTool( "GetElementsToBeAligned" ) {
-    // interfaces
-    declareInterface<ITrackResidualTool>( this );
-    declareProperty( "TestPosDef", m_testPosDef = false );
-  }
-
   StatusCode TrackResidualTool::initialize() {
     StatusCode sc = GaudiTool::initialize();
-    if ( sc.isFailure() ) return Error( "Failed to initialize", sc );
-    sc = m_elementTool.retrieve();
     incSvc()->addListener( this, IncidentType::EndEvent );
     return sc;
   }
 
-  StatusCode TrackResidualTool::finalize() {
-    m_elementTool.release().ignore();
-    return GaudiTool::finalize();
-  }
-
   void TrackResidualTool::handle( const Incident& incident ) {
-    if ( IncidentType::EndEvent == incident.type() ) {
-      for ( ResidualMap::iterator it = m_residuals.begin(); it != m_residuals.end(); ++it ) delete it->second;
-      m_residuals.clear();
-    }
+    if ( IncidentType::EndEvent == incident.type() ) clearCache();
   }
 
   const Al::TrackResiduals* TrackResidualTool::get( const LHCb::Track& track ) const {
-    const Al::TrackResiduals*   rc( 0 );
-    ResidualMap::const_iterator it = m_residuals.find( &track );
-    if ( it != m_residuals.end() )
-      rc = it->second;
-    else {
-      rc                  = compute( track );
-      m_residuals[&track] = rc;
-    }
-    return rc;
+    // is this the most efficient way to create a cache?
+    auto entry = m_residuals.insert( {&track, std::unique_ptr<Al::TrackResiduals>{}} );
+    if ( entry.second ) entry.first->second = compute( track );
+    return entry.first->second.get();
   }
 
-  template <class Matrix>
-  Matrix correlationMatrix( const Matrix& M ) {
-    Matrix N;
-    for ( int i = 0; i < Matrix::kCols; ++i ) {
-      N( i, i ) = 1;
-      for ( int j = 0; j < i; ++j ) N( i, j ) = M( i, j ) / std::sqrt( M( i, i ) * M( j, j ) );
+  namespace {
+    template <class Matrix>
+    Matrix correlationMatrix( const Matrix& M ) {
+      Matrix N;
+      for ( int i = 0; i < Matrix::kCols; ++i ) {
+        N( i, i ) = 1;
+        for ( int j = 0; j < i; ++j ) N( i, j ) = M( i, j ) / std::sqrt( M( i, i ) * M( j, j ) );
+      }
+      return N;
     }
-    return N;
-  }
 
-  template <class Matrix>
-  bool testPosDef( const Matrix& M ) {
-    Matrix N = correlationMatrix( M );
-    double det;
-    /*bool success =*/N.Det( det );
-    const double tolerance = 1e-9;
-    return /*success &&*/ det + tolerance > 0;
-  }
+    template <class Matrix>
+    bool testPosDef( const Matrix& M ) {
+      Matrix N = correlationMatrix( M );
+      double det;
+      /*bool success =*/N.Det( det );
+      const double tolerance = 1e-9;
+      return /*success &&*/ det + tolerance > 0;
+    }
 
-  template <int N>
-  ROOT::Math::SMatrix<double, 2 * N, 2 * N, ROOT::Math::MatRepSym<double, 2 * N>>
-  constructNxN( const Gaudi::SymMatrix5x5& MAA, const Gaudi::SymMatrix5x5& MBB, const Gaudi::Matrix5x5& MAB ) {
-    ROOT::Math::SMatrix<double, 2 * N, 2 * N, ROOT::Math::MatRepSym<double, 2 * N>> M;
-    for ( int i = 0; i < N; ++i ) {
-      for ( int j = 0; j <= i; ++j ) {
-        M( i, j )         = MAA( i, j );
-        M( i + N, j + N ) = MBB( i, j );
+    template <int N>
+    ROOT::Math::SMatrix<double, 2 * N, 2 * N, ROOT::Math::MatRepSym<double, 2 * N>>
+    constructNxN( const Gaudi::SymMatrix5x5& MAA, const Gaudi::SymMatrix5x5& MBB, const Gaudi::Matrix5x5& MAB ) {
+      ROOT::Math::SMatrix<double, 2 * N, 2 * N, ROOT::Math::MatRepSym<double, 2 * N>> M;
+      for ( int i = 0; i < N; ++i ) {
+        for ( int j = 0; j <= i; ++j ) {
+          M( i, j )         = MAA( i, j );
+          M( i + N, j + N ) = MBB( i, j );
+        }
+        for ( int j = 0; j < N; ++j ) { M( i, j + N ) = MAB( i, j ); }
       }
-      for ( int j = 0; j < N; ++j ) { M( i, j + N ) = MAB( i, j ); }
+      return M;
     }
-    return M;
-  }
+  } // namespace
 
-  Al::TrackResiduals* TrackResidualTool::create( const LHCb::Track&                       track,
-                                                 const std::vector<const LHCb::FitNode*>& nodes,
-                                                 std::vector<size_t>&                     residualnodeindices,
-                                                 size_t&                                  refnodeindex ) const {
+  std::unique_ptr<Al::TrackResiduals> TrackResidualTool::create( const LHCb::Track&                       track,
+                                                                 const std::vector<const LHCb::FitNode*>& nodes,
+                                                                 std::vector<size_t>& residualnodeindices,
+                                                                 size_t&              refnodeindex ) const {
     // first select nodes with a measurement and equip them with an index in the original list
     typedef std::pair<const LHCb::FitNode*, size_t> NodeWithIndex;
     std::vector<NodeWithIndex>                      nodeswithindex;
@@ -158,7 +140,7 @@ namespace Al {
     // now select the subset of nodes associated to an alignable object
     residualnodeindices.clear();
     residualnodeindices.reserve( nodeswithindex.size() );
-    Al::TrackResiduals* rc = new Al::TrackResiduals( track );
+    auto rc = std::unique_ptr<Al::TrackResiduals>{new Al::TrackResiduals{track}};
     rc->m_residuals.reserve( nodeswithindex.size() );
     rc->m_state = nodeswithindex.front().first->classicalSmoothedState();
     for ( std::vector<NodeWithIndex>::const_iterator it = nodeswithindex.begin(); it != nodeswithindex.end(); ++it ) {
@@ -187,7 +169,7 @@ namespace Al {
     return *offdiagcov[l][k];
   }
 
-  const Al::TrackResiduals* TrackResidualTool::compute( const LHCb::Track& track ) const {
+  std::unique_ptr<Al::TrackResiduals> TrackResidualTool::compute( const LHCb::Track& track ) const {
     debug() << "In TrackResidualTool::Compute" << endmsg;
 
     // this is not stricktly necessary, but let's do it anyway
@@ -276,7 +258,7 @@ namespace Al {
     // this is also where things become really slow.
     if ( !error && ( error = fr->inError() ) ) warning() << "Error in KalmanFitResult: " << fr->getError() << endmsg;
 
-    Al::TrackResiduals* residuals( 0 );
+    std::unique_ptr<Al::TrackResiduals> residuals;
 
     if ( !error ) {
 
@@ -338,17 +320,14 @@ namespace Al {
           warning() << "Track type = " << track.type() << " " << track.history() << " " << track.flag() << endmsg;
         }
       }
-      if ( error ) {
-        delete residuals;
-        residuals = 0;
-      }
+      if ( error ) residuals.reset();
     }
 
     // let's clean up:
     for ( size_t irow = 0; irow < numnodes; ++irow )
       for ( size_t icol = 0; icol < irow; ++icol ) delete offdiagcov[irow][icol];
 
-    debug() << "End of TrackResidualTool::Compute " << residuals << endmsg;
+    debug() << "End of TrackResidualTool::Compute " << residuals.get() << endmsg;
     counter( "Fraction of failures" ) += bool( residuals == 0 );
     return residuals;
   }
diff --git a/Alignment/TAlignment/src/VertexResidualTool.cpp b/Alignment/TAlignment/src/VertexResidualTool.cpp
index 25cd2e49241810ff5f5e56941b441391fa5e2c0b..6b65a740c71bba983fdbd8c04bfc9207124f3218 100755
--- a/Alignment/TAlignment/src/VertexResidualTool.cpp
+++ b/Alignment/TAlignment/src/VertexResidualTool.cpp
@@ -10,7 +10,7 @@
 \*****************************************************************************/
 #include "Event/FitNode.h"
 #include "GaudiAlg/GaudiTool.h"
-#include "GaudiKernel/IIncidentListener.h"
+#include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 #include "IVertexResidualTool.h"
 #include "Kernel/IParticlePropertySvc.h"
@@ -21,7 +21,7 @@
 // TAlignment
 #include "ITrackResidualTool.h"
 
-class ITrackExtrapolator;
+struct ITrackExtrapolator;
 namespace LHCb {
   class RecVertex;
 }
@@ -36,53 +36,41 @@ namespace {
 } // namespace
 
 namespace Al {
-  class ITrackResidualTool;
+  struct ITrackResidualTool;
   struct TrackContribution;
 
-  class VertexResidualTool : public GaudiTool, virtual public IVertexResidualTool, virtual public IIncidentListener {
+  class VertexResidualTool : public extends<GaudiTool, IVertexResidualTool> {
   public:
     //
     typedef std::vector<const Al::TrackResiduals*> TrackResidualContainer;
     // constructor
-    VertexResidualTool( const std::string& type, const std::string& name, const IInterface* parent );
-    // destructor
-    virtual ~VertexResidualTool(){};
-    // initialize
-    StatusCode initialize() override;
-    // finalize
-    StatusCode finalize() override;
-    // incident service handle
-    void handle( const Incident& incident ) override;
+    using extends::extends;
     // process a vertex (primary vertex of twoprongvertex)
-    const Al::MultiTrackResiduals* get( const LHCb::RecVertex& vertex ) const override;
+    ReturnType get( const LHCb::RecVertex& vertex ) const override;
     // process a particle. this applies a mass constraint.
-    const Al::MultiTrackResiduals* get( const LHCb::Particle& particle ) const override;
+    ReturnType get( const LHCb::Particle& particle ) const override;
 
   private:
     // create a new MultiTrackResiduals
-    const Al::MultiTrackResiduals* compute( const TrackResidualContainer& tracks, const Gaudi::XYZPoint& vertexestimate,
-                                            const MassConstraint* massconstraint ) const;
+    ReturnType compute( const TrackResidualContainer& tracks, const Gaudi::XYZPoint& vertexestimate,
+                        const MassConstraint* massconstraint = nullptr ) const;
     // extrapolate the state in trackresiduals to position z
     StatusCode extrapolate( const Al::TrackResiduals& trackin, double z, TrackContribution& trackout ) const;
 
   private:
-    ToolHandle<ITrackResidualTool>                      m_trackresidualtool;
-    ToolHandle<ITrackExtrapolator>                      m_extrapolator;
-    LHCb::IParticlePropertySvc*                         m_propertysvc;
-    double                                              m_chiSquarePerDofCut;
-    double                                              m_maxMassConstraintChi2;
-    bool                                                m_computeCorrelations;
-    size_t                                              m_maxHitsPerTrackForCorrelations;
-    typedef std::vector<const Al::MultiTrackResiduals*> ResidualContainer;
-    mutable ResidualContainer                           m_residuals;
-    bool                                                m_debugLevel;
+    PublicToolHandle<ITrackResidualTool>      m_trackresidualtool{this, "TrackResidualTool", "Al::TrackResidualTool"};
+    PublicToolHandle<ITrackExtrapolator>      m_extrapolator{this, "Extrapolator", "TrackMasterExtrapolator"};
+    ServiceHandle<LHCb::IParticlePropertySvc> m_propertysvc{this, "ParticlePropertyService",
+                                                            "LHCb::ParticlePropertySvc"};
+    Gaudi::Property<double>                   m_chiSquarePerDofCut{this, "MaxVertexChi2PerDoF", 10};
+    Gaudi::Property<double>                   m_maxMassConstraintChi2{this, "MaxMassConstraintChi2", 16};
+    Gaudi::Property<int> m_maxHitsPerTrackForCorrelations{this, "MaxHitsPerTrackForCorrelations", -1};
   };
 
 } // namespace Al
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-#include "GaudiKernel/IIncidentSvc.h"
 #include <algorithm>
 #include <iostream>
 
@@ -100,54 +88,11 @@ namespace Al {
 
   DECLARE_COMPONENT( VertexResidualTool )
 
-  VertexResidualTool::VertexResidualTool( const std::string& type, const std::string& name, const IInterface* parent )
-      : GaudiTool( type, name, parent )
-      , m_trackresidualtool( "Al::TrackResidualTool" )
-      , // important: use the toolsvc, because of caching!
-      m_extrapolator( "TrackMasterExtrapolator" )
-      , m_propertysvc( 0 )
-      , m_maxHitsPerTrackForCorrelations( 9999 ) {
-    // interfaces
-    declareInterface<IVertexResidualTool>( this );
-    declareProperty( "TrackResidualTool", m_trackresidualtool );
-    declareProperty( "Extrapolator", m_extrapolator );
-    declareProperty( "MaxHitsPerTrackForCorrelations", m_maxHitsPerTrackForCorrelations );
-    declareProperty( "MaxVertexChi2PerDoF", m_chiSquarePerDofCut = 10 );
-    declareProperty( "MaxMassConstraintChi2", m_maxMassConstraintChi2 = 16 );
-  }
-
-  StatusCode VertexResidualTool::initialize() {
-    StatusCode sc = GaudiTool::initialize();
-    if ( sc.isFailure() ) { return Error( "Failed to initialize", sc ); }
-    m_trackresidualtool.retrieve().ignore();
-    m_extrapolator.retrieve().ignore();
-    incSvc()->addListener( this, IncidentType::EndEvent );
-    m_propertysvc = svc<LHCb::IParticlePropertySvc>( "LHCb::ParticlePropertySvc", true );
-    m_debugLevel  = msgLevel( MSG::DEBUG );
-    return sc;
-  }
-
-  StatusCode VertexResidualTool::finalize() {
-    bool success = m_trackresidualtool.release().isSuccess() && m_extrapolator.release().isSuccess() &&
-                   GaudiTool::finalize().isSuccess();
-
-    return success ? StatusCode::SUCCESS : StatusCode::FAILURE;
-  }
-
-  void VertexResidualTool::handle( const Incident& incident ) {
-    if ( IncidentType::EndEvent == incident.type() ) {
-      for ( ResidualContainer::iterator it = m_residuals.begin(); it != m_residuals.end(); ++it ) delete *it;
-      m_residuals.clear();
-    }
-  }
-
-  const Al::MultiTrackResiduals* VertexResidualTool::get( const LHCb::RecVertex& vertex ) const {
+  VertexResidualTool::ReturnType VertexResidualTool::get( const LHCb::RecVertex& vertex ) const {
     // loop over the list of vertices, collect tracks in the vertex
-    const Al::MultiTrackResiduals* rc( 0 );
-    TrackResidualContainer         trackresiduals;
-    for ( SmartRefVector<LHCb::Track>::const_iterator itrack = vertex.tracks().begin(); itrack != vertex.tracks().end();
-          ++itrack ) {
-      const Al::TrackResiduals* trackres = m_trackresidualtool->get( **itrack );
+    TrackResidualContainer trackresiduals;
+    for ( const auto& track : vertex.tracks() ) {
+      const Al::TrackResiduals* trackres = m_trackresidualtool->get( *track );
       if ( trackres ) {
         trackresiduals.push_back( trackres );
       } else {
@@ -155,20 +100,14 @@ namespace Al {
         assert( 0 );
       }
     }
-
-    const MassConstraint* mconstraint( 0 );
-    rc = compute( trackresiduals, vertex.position(), mconstraint );
-    if ( rc ) m_residuals.push_back( rc );
-
-    delete mconstraint;
-    return rc;
+    return std::unique_ptr<const Al::MultiTrackResiduals>( compute( trackresiduals, vertex.position() ) );
   }
 
-  const Al::MultiTrackResiduals* VertexResidualTool::get( const LHCb::Particle& p ) const {
+  VertexResidualTool::ReturnType VertexResidualTool::get( const LHCb::Particle& p ) const {
     // loop over the list of vertices, collect tracks in the vertex
-    const Al::MultiTrackResiduals* rc( 0 );
-    TrackResidualContainer         trackresiduals;
-    MassConstraint                 mconstraint;
+    ReturnType             rc;
+    TrackResidualContainer trackresiduals;
+    MassConstraint         mconstraint;
     mconstraint.mothermass  = m_propertysvc->find( p.particleID() )->mass();
     mconstraint.motherwidth = m_propertysvc->find( p.particleID() )->width();
     //    info() << "Mothermass: " << mconstraint.mothermass << "\t width: " << mconstraint.motherwidth << endmsg ;
@@ -200,10 +139,7 @@ namespace Al {
       }
     }
 
-    if ( success ) {
-      rc = compute( trackresiduals, p.referencePoint(), &mconstraint );
-      if ( rc ) m_residuals.push_back( rc );
-    }
+    if ( success ) rc = compute( trackresiduals, p.referencePoint(), &mconstraint );
     return rc;
   }
 
@@ -217,11 +153,12 @@ namespace Al {
     size_t           offset;
   };
 
-  const Al::MultiTrackResiduals* VertexResidualTool::compute( const TrackResidualContainer& tracks,
+  VertexResidualTool::ReturnType VertexResidualTool::compute( const TrackResidualContainer& tracks,
                                                               const Gaudi::XYZPoint&        vertexestimate,
                                                               const MassConstraint*         mconstraint ) const {
-    Al::MultiTrackResiduals* rc( 0 );
-    bool                     success = true;
+    Al::MultiTrackResiduals* rc{nullptr};
+    bool                     success      = true;
+    bool                     m_debugLevel = msgLevel( MSG::DEBUG );
 
     // first we need to propagate all tracks to the vertex and keep
     // track of the correlation between the state at the vertex and
@@ -397,11 +334,12 @@ namespace Al {
           if ( m_maxHitsPerTrackForCorrelations > 0 && !computationerror )
             for ( size_t j = 0; j < i && !computationerror; ++j ) {
               size_t joffset = states[j].offset;
-              size_t maxirow = std::min( states[i].trackresiduals->size(), m_maxHitsPerTrackForCorrelations );
+              size_t maxirow = std::min( states[i].trackresiduals->size(), size_t( m_maxHitsPerTrackForCorrelations ) );
               for ( size_t irow = 0; irow < maxirow; ++irow ) {
                 // store this intermediate matrix too save some time
                 Gaudi::TrackProjectionMatrix A = states[i].dResidualdState[irow] * vertex.stateCovariance( i, j );
-                size_t maxjcol = std::min( states[j].trackresiduals->size(), m_maxHitsPerTrackForCorrelations );
+                size_t                       maxjcol =
+                    std::min( states[j].trackresiduals->size(), size_t( m_maxHitsPerTrackForCorrelations ) );
                 for ( size_t jcol = 0; jcol < maxjcol; ++jcol ) {
                   double deltaHCH = ( A * ROOT::Math::Transpose( states[j].dResidualdState[jcol] ) )( 0, 0 );
                   rc->m_HCHElements.push_back( Al::CovarianceElement( irow + ioffset, jcol + joffset, deltaHCH ) );
@@ -419,7 +357,7 @@ namespace Al {
 
         if ( computationerror ) {
           delete rc;
-          rc = 0;
+          rc = nullptr;
           warning() << "VertexResidualTool::compute failed" << endmsg;
         }
       } else {
@@ -429,7 +367,7 @@ namespace Al {
     } else {
       warning() << "not enough tracks for vertex anymore" << endmsg;
     }
-    return rc;
+    return ReturnType{rc};
   }
 
   StatusCode VertexResidualTool::extrapolate( const Al::TrackResiduals& track, double z, TrackContribution& tc ) const {
diff --git a/Alignment/VeloAlignment/src/PVHisto.cpp b/Alignment/VeloAlignment/src/PVHisto.cpp
index 800e2a46ae490cc5536072acece67a5fd2da372b..f2b55e95d5f173565c973df5dbdf77c283f5e627 100755
--- a/Alignment/VeloAlignment/src/PVHisto.cpp
+++ b/Alignment/VeloAlignment/src/PVHisto.cpp
@@ -29,7 +29,6 @@ PVHisto::PVHisto() {}
 
 PVHisto::PVHisto( double min, double max, double width )
     : m_Min( min )
-    , m_Max( max )
     , m_BinWidth( width )
     , m_Bins( int( 0.99 + ( max - min ) / width ) )
     , m_Histo( m_Bins, 0 )
@@ -37,12 +36,7 @@ PVHisto::PVHisto( double min, double max, double width )
   m_MaxBin = m_Histo.begin();
 }
 PVHisto::PVHisto( double min, double max, int bins )
-    : m_Min( min )
-    , m_Max( max )
-    , m_BinWidth( ( max - min ) / bins )
-    , m_Bins( bins )
-    , m_Histo( bins, 0 )
-    , m_MaxVal( 0 ) {
+    : m_Min( min ), m_BinWidth( ( max - min ) / bins ), m_Bins( bins ), m_Histo( bins, 0 ), m_MaxVal( 0 ) {
   m_MaxBin = m_Histo.begin();
 }
 //=============================================================================
diff --git a/Alignment/VeloAlignment/src/PVHisto.h b/Alignment/VeloAlignment/src/PVHisto.h
index 46a0d7f5a3d0621bf56d405f6b46503f3a808287..fb6619fc252e3654a5ae01be1e0d0053faa2b534 100755
--- a/Alignment/VeloAlignment/src/PVHisto.h
+++ b/Alignment/VeloAlignment/src/PVHisto.h
@@ -48,7 +48,7 @@ public:
 
 protected:
 private:
-  double            m_Min, m_Max;
+  double            m_Min;
   double            m_BinWidth;
   int               m_Bins;
   std::vector<int>  m_Histo;
diff --git a/Alignment/VeloAlignment/src/VAlign.h b/Alignment/VeloAlignment/src/VAlign.h
index 4514d5aad75b09c88a5f55fbe584ed473222f34c..23101af01e54010536ab61eeac1cff22228fb5b6 100755
--- a/Alignment/VeloAlignment/src/VAlign.h
+++ b/Alignment/VeloAlignment/src/VAlign.h
@@ -104,8 +104,6 @@ public:
 
 protected:
 private:
-  const LHCb::RecVertices* pvcontainer;
-
   // TrackStore Variables
 
   MilleConfig*               my_Config;
@@ -173,15 +171,10 @@ private:
   std::vector<double> m_sigmab;
   std::vector<bool>   m_constrainb;
   std::vector<double> m_residual_cutb;
-  double              m_z_range;
   unsigned int        m_PV_trackmin;
-  double              m_z_sigma;
-  double              m_IPmax;
-  double              m_TrIPmax;
 
   double       m_starfactr;
   unsigned int m_maxtrack;
-  double       m_maxChi2;
   bool         m_moni_constants;
   bool         m_moni_PV;
   bool         m_moni_overlaps;
@@ -198,12 +191,8 @@ private:
   std::vector<double> mis_pull;
 
   // VELO geometry info
-
   DeVelo* m_velo;
 
-  const DeVeloRType*   rDet;
-  const DeVeloPhiType* phiDet;
-
   double VELOmap[42];
   double zmoy_R, zmoy_L, szmoy_R, szmoy_L;
 
diff --git a/Calibration/Pi0Calibration/Pi0Calibration/MMapVector.h b/Calibration/Pi0Calibration/Pi0Calibration/MMapVector.h
index 90112d16719768ecb9471406946bd2b287037f5e..98abfd714d3176a4da304899c6166503e29fdd96 100644
--- a/Calibration/Pi0Calibration/Pi0Calibration/MMapVector.h
+++ b/Calibration/Pi0Calibration/Pi0Calibration/MMapVector.h
@@ -553,7 +553,7 @@ public:
   /// clear the vector
   void clear() noexcept( noexcept( destroy_range( begin(), end() ) ) ) {
     destroy_range( begin(), end() );
-    m_size -= m_size;
+    m_size = 0;
   }
 
   /// resize the vector (default-construct new elements if needed)
diff --git a/Calibration/Pi0Calibration/src/Pi0MassFitter.cpp b/Calibration/Pi0Calibration/src/Pi0MassFitter.cpp
index b58edc11aeb1e3295e92cd7d3ce7134fb89fd0c9..1e53dc5a0f19f7ccc8767d7b0bf76dac3ceee1af 100644
--- a/Calibration/Pi0Calibration/src/Pi0MassFitter.cpp
+++ b/Calibration/Pi0Calibration/src/Pi0MassFitter.cpp
@@ -62,13 +62,13 @@ using namespace boost::filesystem;
 using namespace RooFit;
 using namespace Calibration::Pi0Calibration;
 
-const unsigned int BitsCol   = 6;
-const unsigned int BitsRow   = 6;
-const unsigned int BitsArea  = 2;
-const unsigned int ShiftCol  = 0;
-const unsigned int ShiftRow  = ShiftCol + BitsCol;
-const unsigned int ShiftArea = ShiftRow + BitsRow;
-const unsigned int MaskArea  = ( ( ( (unsigned int)1 ) << BitsArea ) - 1 ) << ShiftArea;
+// const unsigned int BitsCol   = 6;
+// const unsigned int BitsRow   = 6;
+// const unsigned int BitsArea  = 2;
+// const unsigned int ShiftCol  = 0;
+// const unsigned int ShiftRow  = ShiftCol + BitsCol;
+// const unsigned int ShiftArea = ShiftRow + BitsRow;
+// const unsigned int MaskArea  = ( ( ( (unsigned int)1 ) << BitsArea ) - 1 ) << ShiftArea;
 
 Double_t Pi0MassFitter::polyn( Double_t* x, Double_t* par ) { return par[0] + par[1] * x[0] + par[2] * x[0] * x[0]; }
 Double_t Pi0MassFitter::polynSB( Double_t* x, Double_t* par ) {