diff --git a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h
index efedc93345fd25b4546f3054dd414b185163e158..1dd81aec07c856d196b555865de1cacf35b519f9 100755
--- a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h
+++ b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h
@@ -1,6 +1,6 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
+   Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+ */
 
 /////////////////////////////////////////////////////////////////////////////////
 //  Header file for class  RungeKuttaPropagator, (c) ATLAS Detector software
@@ -22,53 +22,53 @@
 
 namespace Trk {
 
-  class Surface                  ;
-  class MagneticFieldProperties  ;
-  class CylinderBounds           ;
-  class CylinderSurface          ;
-  class PatternTrackParameters   ;
+class Surface                  ;
+class MagneticFieldProperties  ;
+class CylinderBounds           ;
+class CylinderSurface          ;
+class PatternTrackParameters   ;
 
-  /**
+/**
   @class RungeKuttaPropagator
-  
+
   Trk::RungeKuttaPropagator is algorithm for track parameters propagation through
   magnetic field with or without jacobian of transformation. This algorithm
   contains three steps.
 
   1.The first step of the algorithm is track parameters transformation from
-    local presentation for given start surface to global Runge Kutta coordinates.
+  local presentation for given start surface to global Runge Kutta coordinates.
 
   2.The second step is propagation through magnetic field with or without jacobian.
 
   3.Third step is transformation from global Runge Kutta presentation to local
-    presentation of given output surface.
-   
-
-    AtaPlane    AtaStraightLine      AtaDisc       AtaCylinder      Perigee
-       |               |               |               |              |
-       |               |               |               |              |
-       V               V               V               V              V 
-       ----------------------------------------------------------------- 
-                                       |              Local->Global transformation
-                                       V
-                    Global position (Runge Kutta presentation)
-                                       |
-                                       |
-                 Propagation to next surface with or without jacobian
-                           using Nystroem algorithm 
-               (See Handbook Net. Bur. of Standards, procedure 25.5.20)
-                                       |
-                                       V              Global->Local transformation
-       ----------------------------------------------------------------
-       |               |               |               |              |
-       |               |               |               |              |
-       V               V               V               V              V
-   PlaneSurface StraightLineSurface DiscSurface CylinderSurface PerigeeSurface 
+  presentation of given output surface.
+
+
+  AtaPlane    AtaStraightLine      AtaDisc       AtaCylinder      Perigee
+  |               |               |               |              |
+  |               |               |               |              |
+  V               V               V               V              V 
+  ----------------------------------------------------------------- 
+  |              Local->Global transformation
+  V
+  Global position (Runge Kutta presentation)
+  |
+  |
+  Propagation to next surface with or without jacobian
+  using Nystroem algorithm 
+  (See Handbook Net. Bur. of Standards, procedure 25.5.20)
+  |
+  V              Global->Local transformation
+  ----------------------------------------------------------------
+  |               |               |               |              |
+  |               |               |               |              |
+  V               V               V               V              V
+  PlaneSurface StraightLineSurface DiscSurface CylinderSurface PerigeeSurface 
 
   For propagation using Runge Kutta method we use global coordinate, direction,
   inverse momentum and Jacobian of transformation. All this parameters we save 
   in array P[42].
-                   /dL0    /dL1    /dPhi   /dThe   /dCM
+  /dL0    /dL1    /dPhi   /dThe   /dCM
   X  ->P[0]  dX /   P[ 7]   P[14]   P[21]   P[28]   P[35]  
   Y  ->P[1]  dY /   P[ 8]   P[15]   P[22]   P[29]   P[36]  
   Z  ->P[2]  dZ /   P[ 9]   P[16]   P[23]   P[30]   P[37]   
@@ -76,393 +76,404 @@ namespace Trk {
   Ay ->P[4]  dAy/   P[11]   P[18]   P[25]   P[32]   P[39]  
   Az ->P[5]  dAz/   P[12]   P[19]   P[26]   P[33]   P[40]  
   CM ->P[6]  dCM/   P[13]   P[20]   P[27]   P[34]   P[41] 
- 
+
   where 
-       in case local presentation 
+  in case local presentation 
 
-       L0  - first  local coordinate  (surface dependent)
-       L1  - second local coordinate  (surface dependent)
-       Phi - Azimuthal angle
-       The - Polar     angle
-       CM  - charge/momentum
+  L0  - first  local coordinate  (surface dependent)
+  L1  - second local coordinate  (surface dependent)
+  Phi - Azimuthal angle
+  The - Polar     angle
+  CM  - charge/momentum
 
-       in case global presentation
+  in case global presentation
 
-       X   - global x-coordinate        = surface dependent
-       Y   - global y-coordinate        = surface dependent
-       Z   - global z-coordinate        = sutface dependent
-       Ax  - direction cosine to x-axis = Sin(The)*Cos(Phi)
-       Ay  - direction cosine to y-axis = Sin(The)*Sin(Phi)
-       Az  - direction cosine to z-axis = Cos(The)
-       CM  - charge/momentum            = local CM
+  X   - global x-coordinate        = surface dependent
+  Y   - global y-coordinate        = surface dependent
+  Z   - global z-coordinate        = sutface dependent
+  Ax  - direction cosine to x-axis = Sin(The)*Cos(Phi)
+  Ay  - direction cosine to y-axis = Sin(The)*Sin(Phi)
+  Az  - direction cosine to z-axis = Cos(The)
+  CM  - charge/momentum            = local CM
 
-  Comment: 
-       if pointer to const *  = 0 algorithm will propagate track 
-       parameters and jacobian of transformation according straight line model
+Comment: 
+if pointer to const *  = 0 algorithm will propagate track 
+parameters and jacobian of transformation according straight line model
 
 
-  @author Igor.Gavrilenko@cern.ch     
+@author Igor.Gavrilenko@cern.ch     
   */
 
   class RungeKuttaPropagator : public AthAlgTool, virtual public IPropagator,
-                               virtual public IPatternParametersPropagator
-    {
-      /////////////////////////////////////////////////////////////////////////////////
-      // Public methods:
-      /////////////////////////////////////////////////////////////////////////////////
-      
-    public:
-      
-      RungeKuttaPropagator(const std::string&,const std::string&,const IInterface*);
-
-      virtual ~RungeKuttaPropagator ();
-
-      /** AlgTool initailize method.*/
-      StatusCode initialize();
-
-      /** AlgTool finalize method */
-      StatusCode finalize();
-
-      /** Main propagation mehtod NeutralParameters */
-      
-      const NeutralParameters* propagate
-	(const NeutralParameters        &,
-	 const Surface                  &,
-	 PropDirection                   ,
-	 BoundaryCheck                   ,
-	 bool                            ) const;
-
-      /** Main propagation mehtod without transport jacobian production*/
-
-      const TrackParameters*           propagate
-	(const TrackParameters          &,
-	 const Surface                  &,
-	 const PropDirection             ,
-	 BoundaryCheck                   ,
-	 const MagneticFieldProperties  &, 
-	 ParticleHypothesis              ,
-	 bool                            ,
-	 const TrackingVolume*           ) const;
-
-      /** Main propagation mehtod with transport jacobian production*/
-      
-      const TrackParameters*           propagate
-	(const TrackParameters          &,
-	 const Surface                  &,
-	 const PropDirection             ,
-	 BoundaryCheck                   ,
-	 const MagneticFieldProperties  &, 
-         TransportJacobian             *&,
-	 double                         &,
-	 ParticleHypothesis              ,
-	 bool                            ,
-	 const TrackingVolume*            ) const;
-
-      /** The propagation method finds the closest surface */
-
-      const TrackParameters*           propagate
-	(const TrackParameters         &,
-	 std::vector<DestSurf>         &,
-	 PropDirection                  ,
-	 const MagneticFieldProperties &,
-	 ParticleHypothesis             ,
-	 std::vector<unsigned int>     &,
-	 double                        &,
-	 bool                           ,
-	 bool                           ,
-	 const TrackingVolume*          ) const;
-
-      /** Main propagation mehtod for parameters only without transport jacobian productio*/
-
-      const TrackParameters*           propagateParameters
-	(const TrackParameters          &,
-	 const Surface                  &,
-	 const PropDirection             ,
-	 BoundaryCheck                   ,
-	 const MagneticFieldProperties  &, 
-	 ParticleHypothesis              ,
-	 bool                            ,
-	 const TrackingVolume*          ) const;
-       
- 
-      /** Main propagation mehtod for parameters only with transport jacobian productio*/
-     
-      const TrackParameters*           propagateParameters
-	(const TrackParameters          &,
-	 const Surface                  &,
-	 const PropDirection             ,
-	 BoundaryCheck                   ,
-	 const MagneticFieldProperties  &, 
-         TransportJacobian             *&,
-	 ParticleHypothesis              ,
-	 bool                            ,
-	 const TrackingVolume*           ) const;
-
-      /** Global position together with direction of the trajectory on the surface */
-
-      const IntersectionSolution*      intersect
-	(const TrackParameters          &,
-	 const Surface                  &,
-	 const MagneticFieldProperties  &, 
-	 ParticleHypothesis particle=pion, 
-	 const TrackingVolume*   tvol=0  ) const;
-
-      /** GlobalPositions list interface:*/
-
-      void globalPositions
-	(std::list<Amg::Vector3D>       &,
-	 const TrackParameters          &,
-	 const MagneticFieldProperties  &,
-	 const CylinderBounds&           ,
-	 double                          ,
-	 ParticleHypothesis particle=pion,
-	 const TrackingVolume* tvol=0    ) const;
-
-      /** Test quality Jacobian calculation */
-
-      void JacobianTest
-	(const TrackParameters        &,
-	 const Surface                &,
-	 const MagneticFieldProperties&) const;
-
-      /////////////////////////////////////////////////////////////////////////////////
-      // Public methods for Trk::PatternTrackParameters (from IPattern'Propagator)
-      /////////////////////////////////////////////////////////////////////////////////
-
-      /** Main propagation method */
-
-      using IPropagator::propagate;
-      bool propagate
-	(PatternTrackParameters         &,
-	 const Surface                  &,
-	 PatternTrackParameters         &,
-	 PropDirection                   ,
-	 const MagneticFieldProperties  &, 
-	 ParticleHypothesis particle=pion) const;
-
-      /** Main propagation mehtod with step to surface calculation*/
-
-      bool propagate
-	(PatternTrackParameters         &,
-	 const Surface                  &,
-	 PatternTrackParameters         &,
-	 PropDirection                   ,
-	 const MagneticFieldProperties  &,
-	 double                         &,
-	 ParticleHypothesis particle=pion) const;
-      
-      /** Main propagation mehtod for parameters only */
-
-      bool propagateParameters
-	(PatternTrackParameters         &,
-	 const Surface                  &,
-	 PatternTrackParameters         &,
-	 PropDirection                   ,
-	 const MagneticFieldProperties  &,
-	 ParticleHypothesis particle=pion) const;
-      
-      /** Main propagation mehtod for parameters only with step to surface calculation*/
-
-      bool propagateParameters
-	(PatternTrackParameters         &,
-	 const Surface                  &,
-	 PatternTrackParameters         &,
-	 PropDirection                   ,
-	 const MagneticFieldProperties  &,
-	 double                         &,
-	 ParticleHypothesis particle=pion) const;
-
-      /** GlobalPositions list interface:*/
-
-      void globalPositions
-	(std::list<Amg::Vector3D>       &,
-	 const PatternTrackParameters   &,
-	 const MagneticFieldProperties  &,
-	 const CylinderBounds           &,
-	 double                          ,
-	 ParticleHypothesis particle=pion) const;
-
-      /** GlobalPostions and steps for set surfaces */
-      
-      void globalPositions
-	(const PatternTrackParameters                 &,
-	 std::list<const Surface*>                    &,
-	 std::list< std::pair<Amg::Vector3D,double> > &,
-	 const MagneticFieldProperties                &,
-	 ParticleHypothesis particle=pion              ) const;
-
-     /** a very simple propagation along a given path length */
-
-      virtual void propagateStep(const Amg::Vector3D& inputPosition, 
-				 const Amg::Vector3D& inputMomentum, 
-				 double charge, 
-				 double step,
-				 Amg::Vector3D& outputPosition, 
-				 Amg::Vector3D& outputMomentum,
-				 const MagneticFieldProperties& mprop);
-      
-    private:
-
-      /////////////////////////////////////////////////////////////////////////////////
-      // Private methods:
-      /////////////////////////////////////////////////////////////////////////////////
- 
-      /** Internal RungeKutta propagation method for charge track parameters*/   
-  
-      const TrackParameters*      propagateRungeKutta
-	(bool                          ,
-	 const TrackParameters        &,
-	 const Surface                &,
-	 const PropDirection           ,
-	 BoundaryCheck                 ,
-	 const MagneticFieldProperties&,
-	 double                       *,
-	 bool                returnCurv) const;
-
-      /** Internal RungeKutta propagation method for neutral track parameters*/   
-  
-      const NeutralParameters*    propagateStraightLine
-	(bool                          ,
-	 const NeutralParameters      &,
-	 const Surface                &,
-	 const PropDirection           ,
-	 BoundaryCheck                 ,
-	 double                       *,
-	 bool                returnCurv) const;
-
-      /** Internal RungeKutta propagation method */
-     
-      bool propagateRungeKutta
-	(bool                          ,
-	 PatternTrackParameters       &,
-	 const Surface                &,
-	 PatternTrackParameters       &,
-	 PropDirection                 ,
-	 const MagneticFieldProperties&,
-	 double                       &) const;
-
-      /** Internal RungeKutta propagation method for propation with jacobian*/     
-
-      bool propagateWithJacobian
-	(bool                          ,
-	 int                           ,
-	 double                       *,
-	 double                       *,
-	 double                       &) const;
-
-      /** Propagation methods runge kutta step*/
-
-      double rungeKuttaStep  
-	(bool                          ,
-	 double                        ,
-	 double                       *,
-	 bool                         &) const;
-
-      /** Propagation methods runge kutta step*/
-
-      double rungeKuttaStepWithGradient  
-	(double                        ,
-	 double                       *,
-	 bool                         &) const;
-
-      /** Propagation methods straight line step*/
-
-      double straightLineStep
-	(bool   ,     
-	 double ,
-	 double*) const;
-
-      /** Test new propagation to cylinder boundary */
-
-      bool newCrossPoint
-	(const CylinderSurface&,
-	 const double         *,
-	 const double         *) const;
-
-      /** Step estimator with directions correction */
-      
-      double stepEstimatorWithCurvature(int,double*,const double*,bool&) const;
-
-      /** Step reduction */
-      double stepReduction(const double*) const;
-
-      /** Build new track parameters without propagation */
-
-      const TrackParameters*  buildTrackParametersWithoutPropagation
-	(const TrackParameters &,double*) const;
-
-      const NeutralParameters*  buildTrackParametersWithoutPropagation
-	(const NeutralParameters&,double*) const;
-       
-      void globalOneSidePositions
-	(std::list<Amg::Vector3D>       &,
-	 const double                   *,
-	 const MagneticFieldProperties  &,
-	 const CylinderBounds           &,
-	 double                          ,
-	 ParticleHypothesis particle=pion) const;
-
-      void globalTwoSidePositions
-	(std::list<Amg::Vector3D>       &,
-	 const double                   *,
-	 const MagneticFieldProperties  &,
-	 const CylinderBounds           &,
-	 double                          ,
-	 ParticleHypothesis particle=pion) const;
-
-      const Trk::TrackParameters* crossPoint
-	(const TrackParameters    &,
-	 std::vector<DestSurf>    &,
-	 std::vector<unsigned int>&,
-	 double                   *,
-	 std::pair<double,int>    &) const;
-
-      void getField        (double*,double*        ) const;
-      void getFieldGradient(double*,double*,double*) const;
-
-      //placeholder for compatibility with new interface
-      const TrackSurfaceIntersection* intersectSurface(const Surface&,
-						       const TrackSurfaceIntersection*,
-						       const double,
-						       const MagneticFieldProperties&,
-						       ParticleHypothesis) const {return 0;}
-      
-      /////////////////////////////////////////////////////////////////////////////////
-      // Private data members: 
-      /////////////////////////////////////////////////////////////////////////////////
-
-      double m_dlt                                               ;  // accuracy parameter
-      double m_helixStep                                         ;  // max step whith helix model
-      double m_straightStep                                      ;  // max step whith srtaight line model
-      bool   m_usegradient                                       ;  // use magnetif field gradient
-      mutable double  m_direction                                ;
-      mutable double  m_step                                     ;
-      mutable double  m_maxPath                                  ;
-      mutable bool    m_maxPathLimit                             ;
-      mutable bool    m_mcondition                               ;
-      mutable bool    m_solenoid                                 ;
-      mutable bool    m_needgradient                             ;  
-      mutable bool    m_newfield                                 ;
-      mutable double  m_field[3]                                 ;
-      ServiceHandle<MagField::IMagFieldSvc>  m_fieldServiceHandle;
-      MagField::IMagFieldSvc*                m_fieldService      ;
-   };
+  virtual public IPatternParametersPropagator
+{
+  /////////////////////////////////////////////////////////////////////////////////
+  // Public methods:
+  /////////////////////////////////////////////////////////////////////////////////
+
+public:
+
+  RungeKuttaPropagator(const std::string&,const std::string&,const IInterface*);
+
+  virtual ~RungeKuttaPropagator ();
+
+  /** AlgTool initailize method.*/
+  StatusCode initialize();
+
+  /** AlgTool finalize method */
+  StatusCode finalize();
+
+  /** Main propagation mehtod NeutralParameters */
+
+  const NeutralParameters* propagate
+    (const NeutralParameters        &,
+     const Surface                  &,
+     PropDirection                   ,
+     BoundaryCheck                   ,
+     bool                            ) const;
+
+  /** Main propagation mehtod without transport jacobian production*/
+
+  const TrackParameters*           propagate
+    (const TrackParameters          &,
+     const Surface                  &,
+     const PropDirection             ,
+     BoundaryCheck                   ,
+     const MagneticFieldProperties  &, 
+     ParticleHypothesis              ,
+     bool                            ,
+     const TrackingVolume*           ) const;
+
+  /** Main propagation mehtod with transport jacobian production*/
+
+  const TrackParameters*           propagate
+    (const TrackParameters          &,
+     const Surface                  &,
+     const PropDirection             ,
+     BoundaryCheck                   ,
+     const MagneticFieldProperties  &, 
+     TransportJacobian             *&,
+     double                         &,
+     ParticleHypothesis              ,
+     bool                            ,
+     const TrackingVolume*            ) const;
+
+  /** The propagation method finds the closest surface */
+
+  const TrackParameters*           propagate
+    (const TrackParameters         &,
+     std::vector<DestSurf>         &,
+     PropDirection                  ,
+     const MagneticFieldProperties &,
+     ParticleHypothesis             ,
+     std::vector<unsigned int>     &,
+     double                        &,
+     bool                           ,
+     bool                           ,
+     const TrackingVolume*          ) const;
+
+  /** Main propagation mehtod for parameters only without transport jacobian productio*/
+
+  const TrackParameters*           propagateParameters
+    (const TrackParameters          &,
+     const Surface                  &,
+     const PropDirection             ,
+     BoundaryCheck                   ,
+     const MagneticFieldProperties  &, 
+     ParticleHypothesis              ,
+     bool                            ,
+     const TrackingVolume*          ) const;
+
+
+  /** Main propagation mehtod for parameters only with transport jacobian productio*/
+
+  const TrackParameters*           propagateParameters
+    (const TrackParameters          &,
+     const Surface                  &,
+     const PropDirection             ,
+     BoundaryCheck                   ,
+     const MagneticFieldProperties  &, 
+     TransportJacobian             *&,
+     ParticleHypothesis              ,
+     bool                            ,
+     const TrackingVolume*           ) const;
+
+  /** Global position together with direction of the trajectory on the surface */
+
+  const IntersectionSolution*      intersect
+    (const TrackParameters          &,
+     const Surface                  &,
+     const MagneticFieldProperties  &, 
+     ParticleHypothesis particle=pion, 
+     const TrackingVolume*   tvol=0  ) const;
+
+  /** GlobalPositions list interface:*/
+
+  void globalPositions
+    (std::list<Amg::Vector3D>       &,
+     const TrackParameters          &,
+     const MagneticFieldProperties  &,
+     const CylinderBounds&           ,
+     double                          ,
+     ParticleHypothesis particle=pion,
+     const TrackingVolume* tvol=0    ) const;
+
+  /** Test quality Jacobian calculation */
+
+  void JacobianTest
+    (const TrackParameters        &,
+     const Surface                &,
+     const MagneticFieldProperties&) const;
 
   /////////////////////////////////////////////////////////////////////////////////
-  // Inline methods for magnetic field information
+  // Public methods for Trk::PatternTrackParameters (from IPattern'Propagator)
   /////////////////////////////////////////////////////////////////////////////////
 
-  inline void RungeKuttaPropagator::getField(double* R,double* H) const
-  {
-    if(m_solenoid) return m_fieldService->getFieldZR(R,H);
-    return                m_fieldService->getField  (R,H);
-  }
-
-  inline void RungeKuttaPropagator::getFieldGradient(double* R,double* H,double* dH) const
-  {
-    if(m_solenoid) return m_fieldService->getFieldZR(R,H,dH);
-    return                m_fieldService->getField  (R,H,dH);
-  }
+  /** Main propagation method */
+
+  using IPropagator::propagate;
+  bool propagate
+    (PatternTrackParameters         &,
+     const Surface                  &,
+     PatternTrackParameters         &,
+     PropDirection                   ,
+     const MagneticFieldProperties  &, 
+     ParticleHypothesis particle=pion) const;
+
+  /** Main propagation mehtod with step to surface calculation*/
+
+  bool propagate
+    (PatternTrackParameters         &,
+     const Surface                  &,
+     PatternTrackParameters         &,
+     PropDirection                   ,
+     const MagneticFieldProperties  &,
+     double                         &,
+     ParticleHypothesis particle=pion) const;
+
+  /** Main propagation mehtod for parameters only */
+
+  bool propagateParameters
+    (PatternTrackParameters         &,
+     const Surface                  &,
+     PatternTrackParameters         &,
+     PropDirection                   ,
+     const MagneticFieldProperties  &,
+     ParticleHypothesis particle=pion) const;
+
+  /** Main propagation mehtod for parameters only with step to surface calculation*/
+
+  bool propagateParameters
+    (PatternTrackParameters         &,
+     const Surface                  &,
+     PatternTrackParameters         &,
+     PropDirection                   ,
+     const MagneticFieldProperties  &,
+     double                         &,
+     ParticleHypothesis particle=pion) const;
+
+  /** GlobalPositions list interface:*/
+
+  void globalPositions
+    (std::list<Amg::Vector3D>       &,
+     const PatternTrackParameters   &,
+     const MagneticFieldProperties  &,
+     const CylinderBounds           &,
+     double                          ,
+     ParticleHypothesis particle=pion) const;
+
+  /** GlobalPostions and steps for set surfaces */
+
+  void globalPositions
+    (const PatternTrackParameters                 &,
+     std::list<const Surface*>                    &,
+     std::list< std::pair<Amg::Vector3D,double> > &,
+     const MagneticFieldProperties                &,
+     ParticleHypothesis particle=pion              ) const;
+
+  /** a very simple propagation along a given path length */
+
+  virtual void propagateStep(const Amg::Vector3D& inputPosition, 
+                             const Amg::Vector3D& inputMomentum, 
+                             double charge, 
+                             double step,
+                             Amg::Vector3D& outputPosition, 
+                             Amg::Vector3D& outputMomentum,
+                             const MagneticFieldProperties& mprop);
+
+private:
+
+  struct Cache{
+    double  m_direction                                ;
+    double  m_step                                     ;
+    double  m_maxPath                                  ;
+    double  m_field[3]                                 ;
+    bool    m_maxPathLimit                       =false;
+    bool    m_mcondition                         =false;
+    bool    m_solenoid                            =true;
+    bool    m_needgradient                       =false;  
+    bool    m_newfield                            =true;
+  };
+
+  /////////////////////////////////////////////////////////////////////////////////
+  // Private methods:
+  /////////////////////////////////////////////////////////////////////////////////
+
+  /** Internal RungeKutta propagation method for charge track parameters*/   
+
+  const TrackParameters*      propagateRungeKutta
+    (Cache& cache                  ,
+     bool                          ,
+     const TrackParameters        &,
+     const Surface                &,
+     const PropDirection           ,
+     BoundaryCheck                 ,
+     const MagneticFieldProperties&,
+     double                       *,
+     bool                returnCurv) const;
+
+  /** Internal RungeKutta propagation method for neutral track parameters*/   
+
+  const NeutralParameters*    propagateStraightLine
+    (Cache& cache                  ,
+     bool                          ,
+     const NeutralParameters      &,
+     const Surface                &,
+     const PropDirection           ,
+     BoundaryCheck                 ,
+     double                       *,
+     bool                returnCurv) const;
+
+  /** Internal RungeKutta propagation method */
+
+  bool propagateRungeKutta
+    (Cache& cache                  ,
+     bool                          ,
+     PatternTrackParameters       &,
+     const Surface                &,
+     PatternTrackParameters       &,
+     PropDirection                 ,
+     const MagneticFieldProperties&,
+     double                       &) const;
+
+  /** Internal RungeKutta propagation method for propation with jacobian*/     
+
+  bool propagateWithJacobian
+    (Cache& cache                  , 
+     bool                          ,
+     int                           ,
+     double                       *,
+     double                       *,
+     double                       &) const;
+
+  /** Propagation methods runge kutta step*/
+
+  double rungeKuttaStep  
+    (Cache& cache,
+     bool                          ,
+     double                        ,
+     double                       *,
+     bool                         &) const;
+
+  /** Propagation methods runge kutta step*/
+
+  double rungeKuttaStepWithGradient  
+    (Cache& cache                  ,
+     double                        ,
+     double                       *,
+     bool                         &) const;
+
+  /** Propagation methods straight line step*/
+
+  double straightLineStep
+    (bool   ,     
+     double ,
+     double*) const;
+
+  /** Test new propagation to cylinder boundary */
+
+  bool newCrossPoint
+    (const CylinderSurface&,
+     const double         *,
+     const double         *) const;
+
+  /** Step estimator with directions correction */
+
+  double stepEstimatorWithCurvature(Cache& cache,int,double*,const double*,bool&) const;
+
+  /** Step reduction */
+  double stepReduction(const double*) const;
+
+  /** Build new track parameters without propagation */
+
+  const TrackParameters*  buildTrackParametersWithoutPropagation
+    (const TrackParameters &,double*) const;
+
+  const NeutralParameters*  buildTrackParametersWithoutPropagation
+    (const NeutralParameters&,double*) const;
+
+  void globalOneSidePositions
+    (Cache& cache                   ,
+     std::list<Amg::Vector3D>       &,
+     const double                   *,
+     const MagneticFieldProperties  &,
+     const CylinderBounds           &,
+     double                          ,
+     ParticleHypothesis particle=pion) const;
+
+  void globalTwoSidePositions
+    (Cache& cache                   ,
+     std::list<Amg::Vector3D>       &,
+     const double                   *,
+     const MagneticFieldProperties  &,
+     const CylinderBounds           &,
+     double                          ,
+     ParticleHypothesis particle=pion) const;
+
+  const Trk::TrackParameters* crossPoint
+    (const TrackParameters    &,
+     std::vector<DestSurf>    &,
+     std::vector<unsigned int>&,
+     double                   *,
+     std::pair<double,int>    &) const;
+
+  void getField        (Cache& cache, double*,double*        ) const;
+  void getFieldGradient(Cache& cache, double*,double*,double*) const;
+
+  //placeholder for compatibility with new interface
+  const TrackSurfaceIntersection* intersectSurface(const Surface&,
+                                                   const TrackSurfaceIntersection*,
+                                                   const double,
+                                                   const MagneticFieldProperties&,
+                                                   ParticleHypothesis) const {return 0;}
+
+  /////////////////////////////////////////////////////////////////////////////////
+  // Private data members: 
+  /////////////////////////////////////////////////////////////////////////////////
+
+  double m_dlt                                               ;  // accuracy parameter
+  double m_helixStep                                         ;  // max step whith helix model
+  double m_straightStep                                      ;  // max step whith srtaight line model
+  bool   m_usegradient                                       ;  // use magnetif field gradient
+  ServiceHandle<MagField::IMagFieldSvc>  m_fieldServiceHandle;
+  MagField::IMagFieldSvc*                m_fieldService      ;
+};
+
+/////////////////////////////////////////////////////////////////////////////////
+// Inline methods for magnetic field information
+/////////////////////////////////////////////////////////////////////////////////
+
+inline void RungeKuttaPropagator::getField(Cache& cache,double* R,double* H) const
+{
+  if(cache.m_solenoid) return m_fieldService->getFieldZR(R,H);
+  return                m_fieldService->getField  (R,H);
+}
+
+inline void RungeKuttaPropagator::getFieldGradient(Cache& cache,double* R,double* H,double* dH) const
+{
+  if(cache.m_solenoid) return m_fieldService->getFieldZR(R,H,dH);
+  return                m_fieldService->getField  (R,H,dH);
 }
- 
+}
+
 #endif // RungeKuttaPropagator_H
diff --git a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx
index 3e5a3db0c7f871cb08aff5abe4019f707611ea23..e489d75ffd0b0364679255d46858360ec370c0c6 100755
--- a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx
+++ b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx
@@ -33,8 +33,6 @@ Trk::RungeKuttaPropagator::RungeKuttaPropagator
   m_straightStep      = .01    ;
   m_usegradient       = false  ;
   m_fieldService      = 0      ;
-  m_solenoid          = true   ;
-  m_newfield          = true   ;
  
   declareInterface<Trk::IPropagator>(this);   
   declareInterface<Trk::IPatternParametersPropagator>(this);
@@ -90,7 +88,8 @@ const Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagate
  bool                          returnCurv) const
 {
   double J[25];
-  return propagateStraightLine(true,Tp,Su,D,B,J,returnCurv);
+  Cache cache{};
+  return propagateStraightLine(cache,true,Tp,Su,D,B,J,returnCurv);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -109,8 +108,9 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
  const TrackingVolume*           ) const 
 {
   double J[25];
-  m_maxPath = 10000.;
-  return propagateRungeKutta(true,Tp,Su,D,B,M,J,returnCurv);
+  Cache cache{};
+  cache.m_maxPath = 10000.;
+  return propagateRungeKutta(cache,true,Tp,Su,D,B,M,J,returnCurv);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -131,9 +131,10 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
  const TrackingVolume*             ) const 
 {
   double J[25];
-  pathLength < 0. ?  m_maxPath = 10000. : m_maxPath = pathLength; 
-  const Trk::TrackParameters* Tpn = propagateRungeKutta(true,Tp,Su,D,B,M,J,returnCurv);
-  pathLength = m_step;  
+  Cache cache{};
+  pathLength < 0. ?  cache.m_maxPath = 10000. : cache.m_maxPath = pathLength; 
+  const Trk::TrackParameters* Tpn = propagateRungeKutta(cache,true,Tp,Su,D,B,M,J,returnCurv);
+  pathLength = cache.m_step;  
   
   if(Tpn) { 
     J[24]=J[20]; J[23]=0.; J[22]=0.; J[21]=0.; J[20]=0.;
@@ -159,8 +160,10 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
  bool                               ,
  const TrackingVolume*              ) const
 {
+ 
+  Cache cache{};
   Sol.erase(Sol.begin(),Sol.end()); Path = 0.; if(DS.empty()) return 0;
-  m_direction               = D; 
+  cache.m_direction               = D; 
 
   // Test is it measured track parameters
   //
@@ -168,9 +171,9 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 
   // Magnetic field information preparation
   //
-  M.magneticFieldMode()==2  ? m_solenoid     = true : m_solenoid     = false;  
-  (useJac && m_usegradient) ? m_needgradient = true : m_needgradient = false; 
-  M.magneticFieldMode()!=0  ? m_mcondition   = true : m_mcondition   = false;
+  M.magneticFieldMode()==2  ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  (useJac && m_usegradient) ? cache.m_needgradient = true : cache.m_needgradient = false; 
+  M.magneticFieldMode()!=0  ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   // Transform to global presentation
   //
@@ -220,14 +223,14 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
   bool   reverted_P = false;
   //----------------------------------
 
-  m_newfield = true;
+  cache.m_newfield = true;
  
   while (fabs(W) < Wmax) {
 
     std::pair<double,int> SN;
     double                 S;
 
-    if(m_mcondition) {
+    if(cache.m_mcondition) {
       
       //----------------------------------Niels van Eldik patch
       if (reverted_P && St == last_St && InS == last_InS /*&& condition_fulfiled*/) {
@@ -238,8 +241,8 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
       last_InS = InS;
       //----------------------------------
 
-      if(!m_needgradient) S = rungeKuttaStep            (useJac,St,Pn,InS);
-      else                S = rungeKuttaStepWithGradient(       St,Pn,InS);
+      if(!cache.m_needgradient) S = rungeKuttaStep            (cache,useJac,St,Pn,InS);
+      else                S = rungeKuttaStepWithGradient(cache,St,Pn,InS);
     }
     else  {
 
@@ -261,7 +264,7 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
     bool next; SN=utils.stepEstimator(DS,DN,Po,Pn,W,m_straightStep,Nveto,next); 
 
     if(next) {for(int i=0; i!=45; ++i) Po[i]=Pn[i]; W+=S; Nveto=-1; }
-    else     {for(int i=0; i!=45; ++i) Pn[i]=Po[i]; reverted_P=true; m_newfield= true;}
+    else     {for(int i=0; i!=45; ++i) Pn[i]=Po[i]; reverted_P=true; cache.m_newfield= true;}
 
     if (fabs(S)+1. < fabs(St)) Sl=S; 
     InS ? St = 2.*S : St = S; 
@@ -299,8 +302,9 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
  const TrackingVolume*           ) const 
 {
   double J[25];
-  m_maxPath = 10000.;
-  return propagateRungeKutta(false,Tp,Su,D,B,M,J,returnCurv);
+  Cache cache;
+  cache.m_maxPath = 10000.;
+  return propagateRungeKutta(cache,false,Tp,Su,D,B,M,J,returnCurv);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -320,8 +324,9 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
  const TrackingVolume*              ) const 
 {
   double J[25];
-  m_maxPath = 10000.;
-  const Trk::TrackParameters* Tpn = propagateRungeKutta   (true,Tp,Su,D,B,M,J,returnCurv);
+  Cache cache{};
+  cache.m_maxPath = 10000.;
+  const Trk::TrackParameters* Tpn = propagateRungeKutta   (cache,true,Tp,Su,D,B,M,J,returnCurv);
   
   if(Tpn) {
     J[24]=J[20]; J[23]=0.; J[22]=0.; J[21]=0.; J[20]=0.;
@@ -336,7 +341,8 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
 /////////////////////////////////////////////////////////////////////////////////
 
 const Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
-(bool                           useJac,
+(Cache&                         cache ,
+ bool                           useJac,
  const Trk::NeutralParameters & Tp    ,
  const Trk::Surface           & Su    ,
  Trk::PropDirection             D     ,
@@ -347,8 +353,8 @@ const Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
   const Trk::Surface* su = &Su;
   if(su == &Tp.associatedSurface()) return buildTrackParametersWithoutPropagation(Tp,Jac);
 
-  m_direction               = D    ;
-  m_mcondition              = false;
+  cache.m_direction               = D    ;
+  cache.m_mcondition              = false;
 
 
   Trk::RungeKuttaUtils utils;
@@ -364,12 +370,12 @@ const Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
 
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(useJac,1,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,1,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Line     ) {
 
     double s[6] ={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(useJac,0,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,0,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Disc     ) {
 
@@ -377,37 +383,37 @@ const Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
 
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(useJac,1,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,1,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Cylinder ) {
 
     const Trk::CylinderSurface* cyl = static_cast<const Trk::CylinderSurface*>(su);
 
     double r0[3] = {P[0],P[1],P[2]};
-    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),m_direction,0.};
+    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),cache.m_direction,0.};
 
-    if(!propagateWithJacobian(useJac,2,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,2,s,P,Step)) return 0;
 
     // For cylinder we do test for next cross point
     //
     if(cyl->bounds().halfPhiSector() < 3.1 && newCrossPoint(*cyl,r0,P)) {
-      s[8] = 0.; if(!propagateWithJacobian(useJac,2,s,P,Step)) return 0;
+      s[8] = 0.; if(!propagateWithJacobian(cache,useJac,2,s,P,Step)) return 0;
     }
   }
   else if (ty == Trk::Surface::Perigee  ) {
 
     double s[6] ={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(useJac,0,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,0,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Cone     ) {
     
     double k     = static_cast<const Trk::ConeSurface*>(su)->bounds().tanAlpha(); k = k*k+1.;
-    double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,m_direction,0.};
-    if(!propagateWithJacobian(useJac,3,s,P,Step)) return 0;
+    double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,cache.m_direction,0.};
+    if(!propagateWithJacobian(cache,useJac,3,s,P,Step)) return 0;
   }
   else return 0;
 
-  if(m_direction!=0. && (m_direction*Step)<0.) return 0;
+  if(cache.m_direction!=0. && (cache.m_direction*Step)<0.) return 0;
 
   // Common transformation for all surfaces (angles and momentum)
   //
@@ -415,7 +421,7 @@ const Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
     double p=1./P[6]; P[35]*=p; P[36]*=p; P[37]*=p; P[38]*=p; P[39]*=p; P[40]*=p;
   }
 
-  if(m_maxPathLimit)  returnCurv = true;
+  if(cache.m_maxPathLimit)  returnCurv = true;
 
   bool uJ = useJac; if(returnCurv) uJ = false;
 
@@ -461,7 +467,8 @@ const Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
 /////////////////////////////////////////////////////////////////////////////////
 
 const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateRungeKutta
-(bool                           useJac,
+(Cache&                         cache ,
+ bool                           useJac,
  const Trk::TrackParameters   & Tp    ,
  const Trk::Surface           & Su    ,
  Trk::PropDirection             D     ,
@@ -472,11 +479,11 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateRungeKutta
 { 
   const Trk::Surface* su = &Su;
 
-  m_direction               = D ; 
+  cache.m_direction               = D ; 
 
-  M.magneticFieldMode()==2 ? m_solenoid     = true : m_solenoid     = false;  
-  (useJac && m_usegradient)? m_needgradient = true : m_needgradient = false; 
-  M.magneticFieldMode()!=0 ? m_mcondition   = true : m_mcondition   = false;
+  M.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  (useJac && m_usegradient)? cache.m_needgradient = true : cache.m_needgradient = false; 
+  M.magneticFieldMode()!=0 ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   if(su == &Tp.associatedSurface()) return buildTrackParametersWithoutPropagation(Tp,Jac);
 
@@ -493,49 +500,49 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateRungeKutta
 
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(useJac,1,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,1,s,P,Step)) return 0;
 
   }
   else if (ty == Trk::Surface::Line     ) {
 
     double s[6] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(useJac,0,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,0,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Disc     ) {
 
     double s[4], d  = T(0,3)*T(0,2)+T(1,3)*T(1,2)+T(2,3)*T(2,2);
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(useJac,1,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,1,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Cylinder ) {
 
     const Trk::CylinderSurface* cyl = static_cast<const Trk::CylinderSurface*>(su);
 
     double r0[3] = {P[0],P[1],P[2]};
-    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),m_direction,0.};
-    if(!propagateWithJacobian(useJac,2,s,P,Step)) return 0;
+    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),cache.m_direction,0.};
+    if(!propagateWithJacobian(cache,useJac,2,s,P,Step)) return 0;
 
     // For cylinder we do test for next cross point
     //
     if(cyl->bounds().halfPhiSector() < 3.1 && newCrossPoint(*cyl,r0,P)) {
-      s[8] = 0.; if(!propagateWithJacobian(useJac,2,s,P,Step)) return 0;
+      s[8] = 0.; if(!propagateWithJacobian(cache,useJac,2,s,P,Step)) return 0;
     }
   }
   else if (ty == Trk::Surface::Perigee  ) {
 
     double s[6] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(useJac,0,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,useJac,0,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Cone     ) {
     
     double k    =  static_cast<const Trk::ConeSurface*>(su)->bounds().tanAlpha(); k = k*k+1.;
-    double s[9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,m_direction,0.};
-    if(!propagateWithJacobian(useJac,3,s,P,Step)) return 0;
+    double s[9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,cache.m_direction,0.};
+    if(!propagateWithJacobian(cache,useJac,3,s,P,Step)) return 0;
   }
   else return 0;
 
-  if(m_direction && (m_direction*Step)<0.) {return 0;} m_step = Step;
+  if(cache.m_direction && (cache.m_direction*Step)<0.) {return 0;} cache.m_step = Step;
 
   // Common transformation for all surfaces (angles and momentum)
   //
@@ -543,7 +550,7 @@ const Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateRungeKutta
     double p=1./P[6]; P[35]*=p; P[36]*=p; P[37]*=p; P[38]*=p; P[39]*=p; P[40]*=p;
   }
 
-  if(m_maxPathLimit)  returnCurv = true;
+  if(cache.m_maxPathLimit)  returnCurv = true;
 
   bool uJ = useJac; if(returnCurv) uJ = false;
   double p[5]; utils.transformGlobalToLocal(su,uJ,P,p,Jac);
@@ -598,10 +605,10 @@ void Trk::RungeKuttaPropagator::globalPositions
 {
   Trk::RungeKuttaUtils utils;
   double P[45]; if(!utils.transformLocalToGlobal(false,Tp,P)) return;
-
-  m_direction = fabs(mS);
-  if(mS > 0.) globalOneSidePositions(GP,P,M,CB, mS);
-  else        globalTwoSidePositions(GP,P,M,CB,-mS);
+  Cache cache{};
+  cache.m_direction = fabs(mS);
+  if(mS > 0.) globalOneSidePositions(cache,GP,P,M,CB, mS);
+  else        globalTwoSidePositions(cache,GP,P,M,CB,-mS);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -617,11 +624,12 @@ const Trk::IntersectionSolution* Trk::RungeKuttaPropagator::intersect
 {
   bool nJ = false;
   const Trk::Surface* su = &Su;
-  m_direction            = 0. ;
+  Cache cache{};
+  cache.m_direction            = 0. ;
 
-  m_needgradient = false; 
-  M.magneticFieldMode()==2 ? m_solenoid     = true : m_solenoid     = false;  
-  M.magneticFieldMode()!=0 ? m_mcondition   = true : m_mcondition   = false;
+  cache.m_needgradient = false; 
+  M.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  M.magneticFieldMode()!=0 ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   Trk::RungeKuttaUtils utils;
 
@@ -637,12 +645,12 @@ const Trk::IntersectionSolution* Trk::RungeKuttaPropagator::intersect
 
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(nJ,1,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,nJ,1,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Line     ) {
 
     double s[6] ={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(nJ,0,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,nJ,0,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Disc     ) {
 
@@ -650,37 +658,37 @@ const Trk::IntersectionSolution* Trk::RungeKuttaPropagator::intersect
 
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(nJ,1,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,nJ,1,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Cylinder ) {
 
     const Trk::CylinderSurface* cyl = static_cast<const Trk::CylinderSurface*>(su);
 
     double r0[3] = {P[0],P[1],P[2]};
-    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),m_direction,0.};
+    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),cache.m_direction,0.};
 
-    if(!propagateWithJacobian(nJ,2,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,nJ,2,s,P,Step)) return 0;
 
     // For cylinder we do test for next cross point
     //
     if(cyl->bounds().halfPhiSector() < 3.1 && newCrossPoint(*cyl,r0,P)) {
-      s[8] = 0.; if(!propagateWithJacobian(nJ,2,s,P,Step)) return 0;
+      s[8] = 0.; if(!propagateWithJacobian(cache,nJ,2,s,P,Step)) return 0;
     }
   }
   else if (ty == Trk::Surface::Perigee  ) {
 
     double s[6] ={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(nJ,0,s,P,Step)) return 0;
+    if(!propagateWithJacobian(cache,nJ,0,s,P,Step)) return 0;
   }
   else if (ty == Trk::Surface::Cone     ) {
     
     double k     = static_cast<const Trk::ConeSurface*>(su)->bounds().tanAlpha(); k = k*k+1.;
-    double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,m_direction,0.};
-    if(!propagateWithJacobian(nJ,3,s,P,Step)) return 0;
+    double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,cache.m_direction,0.};
+    if(!propagateWithJacobian(cache,nJ,3,s,P,Step)) return 0;
   }
   else return 0;
 
-  if(m_maxPathLimit) return 0;
+  if(cache.m_maxPathLimit) return 0;
 
   Amg::Vector3D Glo(P[0],P[1],P[2]);
   Amg::Vector3D Dir(P[3],P[4],P[5]);
@@ -694,21 +702,22 @@ const Trk::IntersectionSolution* Trk::RungeKuttaPropagator::intersect
 /////////////////////////////////////////////////////////////////////////////////
 
 bool Trk::RungeKuttaPropagator::propagateWithJacobian   
-(bool Jac                         ,
+(Cache& cache                     ,                    
+ bool Jac                         ,
  int kind                         ,
  double                       * Su,
  double                       * P ,
  double                       & W ) const
 {
   const double Smax   = 1000.     ;  // max. step allowed
-  double       Wmax   = m_maxPath ;  // Max way allowed
+  double       Wmax   = cache.m_maxPath ;  // Max way allowed
   double       Wwrong = 500.      ;  // Max way with wrong direction
   double*      R      = &P[ 0]    ;  // Start coordinates
   double*      A      = &P[ 3]    ;  // Start directions
   double*      SA     = &P[42]    ; SA[0]=SA[1]=SA[2]=0.;
-  m_maxPathLimit      = false     ;  
+  cache.m_maxPathLimit      = false     ;  
 
-  if(m_mcondition && fabs(P[6]) > .1) return false; 
+  if(cache.m_mcondition && fabs(P[6]) > .1) return false; 
 
   // Step estimation until surface
   //
@@ -716,7 +725,7 @@ bool Trk::RungeKuttaPropagator::propagateWithJacobian
   bool Q; double S, Step=utils.stepEstimator(kind,Su,P,Q); if(!Q) return false;
 
   bool dir = true;
-  if(m_mcondition && m_direction && m_direction*Step < 0.)  {
+  if(cache.m_mcondition && cache.m_direction && cache.m_direction*Step < 0.)  {
     Step = -Step; dir = false;
   }
 
@@ -728,24 +737,24 @@ bool Trk::RungeKuttaPropagator::propagateWithJacobian
   // Rkuta extrapolation
   //
   int niter = 0;
-  m_newfield = true;
+  cache.m_newfield = true;
   while(fabs(Step) > m_straightStep) {
 
     if(++niter > 10000) return false;
 
-    if(m_mcondition) {
+    if(cache.m_mcondition) {
 
-      if(!m_needgradient) W+=(S=rungeKuttaStep            (Jac,S,P,InS));
-      else                W+=(S=rungeKuttaStepWithGradient(    S,P,InS));
+      if(!cache.m_needgradient) W+=(S=rungeKuttaStep            (cache,Jac,S,P,InS));
+      else                W+=(S=rungeKuttaStepWithGradient(cache,S,P,InS));
     }
     else  {
       W+=(S=straightLineStep(Jac,S,P));
     }
 
-    Step = stepEstimatorWithCurvature(kind,Su,P,Q); if(!Q) return false;
+    Step = stepEstimatorWithCurvature(cache,kind,Su,P,Q); if(!Q) return false;
 
     if(!dir) {
-      if(m_direction && m_direction*Step < 0.)  Step = -Step;
+      if(cache.m_direction && cache.m_direction*Step < 0.)  Step = -Step;
       else                                      dir  =  true;
     }
     
@@ -759,7 +768,7 @@ bool Trk::RungeKuttaPropagator::propagateWithJacobian
 
     if(iS > 10 || (iS>3 && fabs(S)>=So)) {if(!kind) break; return false;}
     double dW =  Wmax-fabs(W);
-    if(fabs(S) > dW) {S > 0. ? S = dW : S = -dW; Step = S; m_maxPathLimit = true;}
+    if(fabs(S) > dW) {S > 0. ? S = dW : S = -dW; Step = S; cache.m_maxPathLimit = true;}
     So=fabs(S);
   }
   
@@ -786,7 +795,8 @@ bool Trk::RungeKuttaPropagator::propagateWithJacobian
 /////////////////////////////////////////////////////////////////////////////////
 
 double Trk::RungeKuttaPropagator::rungeKuttaStep
-  (bool                           Jac,
+  (Cache&                         cache,
+   bool                           Jac,
    double                         S  , 
    double                       * P  ,
    bool                         & InS) const
@@ -798,7 +808,7 @@ double Trk::RungeKuttaPropagator::rungeKuttaStep
   double  dltm = m_dlt*.03      ;
 
   double f0[3],f[3]; 
-  if(m_newfield) getField(R,f0); else {f0[0]=m_field[0]; f0[1]=m_field[1]; f0[2]=m_field[2];}
+  if(cache.m_newfield) getField(cache,R,f0); else {f0[0]=cache.m_field[0]; f0[1]=cache.m_field[1]; f0[2]=cache.m_field[2];}
 
   bool Helix = false; if(fabs(S) < m_helixStep) Helix = true; 
   while(S != 0.) {
@@ -822,7 +832,7 @@ double Trk::RungeKuttaPropagator::rungeKuttaStep
     //
     if(!Helix) {
       double gP[3]={R[0]+A1*S4, R[1]+B1*S4, R[2]+C1*S4};
-      getField(gP,f);
+      getField(cache,gP,f);
     }
     else       {f[0]=f0[0]; f[1]=f0[1]; f[2]=f0[2];}
 
@@ -841,7 +851,7 @@ double Trk::RungeKuttaPropagator::rungeKuttaStep
     //
     if(!Helix) {
       double gP[3]={R[0]+S*A4, R[1]+S*B4, R[2]+S*C4};    
-      getField(gP,f);
+      getField(cache,gP,f);
     }
     else       {f[0]=f0[0]; f[1]=f0[1]; f[2]=f0[2];} 
 
@@ -886,7 +896,7 @@ double Trk::RungeKuttaPropagator::rungeKuttaStep
     sA[1] = B6*Sl       ;
     sA[2] = C6*Sl       ; 
 
-    m_field[0]=f[0]; m_field[1]=f[1]; m_field[2]=f[2]; m_newfield = false;
+    cache.m_field[0]=f[0]; cache.m_field[1]=f[1]; cache.m_field[2]=f[2]; cache.m_newfield = false;
 
     if(!Jac) return S;
 
@@ -993,7 +1003,8 @@ double Trk::RungeKuttaPropagator::rungeKuttaStep
 /////////////////////////////////////////////////////////////////////////////////
 
 double Trk::RungeKuttaPropagator::rungeKuttaStepWithGradient
-(double                         S  , 
+(Cache&                       cache,                 
+ double                         S  , 
  double                       * P  ,
  bool                         & InS) const
 {
@@ -1005,7 +1016,7 @@ double Trk::RungeKuttaPropagator::rungeKuttaStepWithGradient
   double  dltm = m_dlt*.03      ;
 
   double f0[3],f1[3],f2[3],g0[9],g1[9],g2[9],H0[12],H1[12],H2[12];
-  getFieldGradient(R,f0,g0);
+  getFieldGradient(cache,R,f0,g0);
 
   while(S != 0.) {
  
@@ -1028,7 +1039,7 @@ double Trk::RungeKuttaPropagator::rungeKuttaStepWithGradient
     // Second point
     //
     double gP1[3]={R[0]+A1*S4, R[1]+B1*S4, R[2]+C1*S4};
-    getFieldGradient(gP1,f1,g1);
+    getFieldGradient(cache,gP1,f1,g1);
 
     H1[0] = f1[0]*PS2; H1[1] = f1[1]*PS2; H1[2] = f1[2]*PS2; 
     double A3    = B2*H1[2]-C2*H1[1]+A[0]         ; 
@@ -1044,7 +1055,7 @@ double Trk::RungeKuttaPropagator::rungeKuttaStepWithGradient
     // Last point
     //
     double gP2[3]={R[0]+S*A4, R[1]+S*B4, R[2]+S*C4};    
-    getFieldGradient(gP2,f2,g2);
+    getFieldGradient(cache,gP2,f2,g2);
 
     H2[0] = f2[0]*PS2; H2[1] = f2[1]*PS2; H2[2] = f2[2]*PS2; 
     double A6    = B5*H2[2]-C5*H2[1]              ;
@@ -1199,8 +1210,9 @@ bool Trk::RungeKuttaPropagator::propagate
  ParticleHypothesis               ) const 
 {
   double S;
-  m_maxPath = 10000.;
-  return propagateRungeKutta(true,Ta,Su,Tb,D,M,S);
+  Cache cache{};
+  cache.m_maxPath = 10000.;
+  return propagateRungeKutta(cache,true,Ta,Su,Tb,D,M,S);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -1217,8 +1229,9 @@ bool Trk::RungeKuttaPropagator::propagate
  double                       & S , 
  ParticleHypothesis               ) const 
 {
-  m_maxPath = 10000.;
-  return propagateRungeKutta(true,Ta,Su,Tb,D,M,S);
+  Cache cache{};
+  cache.m_maxPath = 10000.; 
+  return propagateRungeKutta(cache,true,Ta,Su,Tb,D,M,S);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -1235,8 +1248,9 @@ bool Trk::RungeKuttaPropagator::propagateParameters
  ParticleHypothesis               ) const 
 {
   double S;
-  m_maxPath = 10000.;
-  return propagateRungeKutta(false,Ta,Su,Tb,D,M,S);
+  Cache cache{};
+  cache.m_maxPath = 10000.; 
+  return propagateRungeKutta(cache,false,Ta,Su,Tb,D,M,S);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -1253,8 +1267,9 @@ bool Trk::RungeKuttaPropagator::propagateParameters
  double                       & S , 
  ParticleHypothesis               ) const 
 {
-  m_maxPath = 10000.;
-  return propagateRungeKutta(false,Ta,Su,Tb,D,M,S);
+  Cache cache{};
+  cache.m_maxPath = 10000.;
+  return propagateRungeKutta(cache,false,Ta,Su,Tb,D,M,S);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -1274,9 +1289,10 @@ void Trk::RungeKuttaPropagator::globalPositions
   Trk::RungeKuttaUtils utils;
   double P[45]; if(!utils.transformLocalToGlobal(false,Tp,P)) return;
 
-  m_direction = fabs(mS);
-  if(mS > 0.) globalOneSidePositions(GP,P,M,CB, mS);
-  else        globalTwoSidePositions(GP,P,M,CB,-mS);
+  Cache cache{};
+  cache.m_direction = fabs(mS);
+  if(mS > 0.) globalOneSidePositions(cache,GP,P,M,CB, mS);
+  else        globalTwoSidePositions(cache,GP,P,M,CB,-mS);
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -1284,18 +1300,20 @@ void Trk::RungeKuttaPropagator::globalPositions
 /////////////////////////////////////////////////////////////////////////////////
 
 void Trk::RungeKuttaPropagator::globalPositions
-(const PatternTrackParameters                 & Tp,
+(
+ const PatternTrackParameters                 & Tp,
  std::list<const Trk::Surface*>               & SU,
  std::list< std::pair<Amg::Vector3D,double> > & GP,
  const Trk::MagneticFieldProperties           & M ,
  ParticleHypothesis                               ) const
 {
-  m_direction               = 0.    ;
-  m_mcondition              = false ;
-  m_maxPath                 = 10000.;
-  m_needgradient = false;
-  M.magneticFieldMode()==2 ? m_solenoid     = true : m_solenoid     = false;  
-  M.magneticFieldMode()!=0 ? m_mcondition   = true : m_mcondition   = false;
+  Cache cache{};
+  cache.m_direction               = 0.    ;
+  cache.m_mcondition              = false ;
+  cache.m_maxPath                 = 10000.;
+  cache.m_needgradient = false;
+  M.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  M.magneticFieldMode()!=0 ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   Trk::RungeKuttaUtils utils;
 
@@ -1317,48 +1335,48 @@ void Trk::RungeKuttaPropagator::globalPositions
 
       if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
       else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-      if(!propagateWithJacobian(false,1,s,P,Step)) return;
+      if(!propagateWithJacobian(cache,false,1,s,P,Step)) return;
     }
     else if(ty == Trk::Surface::Line ) {
 
       double s[6]={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-      if(!propagateWithJacobian(false,0,s,P,Step)) return;
+      if(!propagateWithJacobian(cache,false,0,s,P,Step)) return;
     }
     else if (ty == Trk::Surface::Disc     ) {
 
       double s[4],d  = T(0,3)*T(0,2)+T(1,3)*T(1,2)+T(2,3)*T(2,2);
       if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
       else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-      if(!propagateWithJacobian(false,1,s,P,Step)) return;
+      if(!propagateWithJacobian(cache,false,1,s,P,Step)) return;
     }
     else if (ty == Trk::Surface::Cylinder ) {
 
       const Trk::CylinderSurface* cyl = static_cast<const Trk::CylinderSurface*>(*su);
       double r0[3] = {P[0],P[1],P[2]};
-      double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),m_direction,0.};
+      double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),cache.m_direction,0.};
 
-      if(!propagateWithJacobian(false,2,s,P,Step)) return;
+      if(!propagateWithJacobian(cache,false,2,s,P,Step)) return;
 
       // For cylinder we do test for next cross point
       //
       if(cyl->bounds().halfPhiSector() < 3.1 && newCrossPoint(*cyl,r0,P)) {
-	s[8] = 0.; if(!propagateWithJacobian(false,2,s,P,Step)) return;
+	s[8] = 0.; if(!propagateWithJacobian(cache,false,2,s,P,Step)) return;
       }
     }
     else if (ty == Trk::Surface::Perigee  ) {
 
       double s[6]={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-      if(!propagateWithJacobian(false,0,s,P,Step)) return ;
+      if(!propagateWithJacobian(cache,false,0,s,P,Step)) return ;
     }
     else if (ty == Trk::Surface::Cone     ) {
     
       double k     = static_cast<const Trk::ConeSurface*>(*su)->bounds().tanAlpha(); k = k*k+1.;
-      double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,m_direction,0.};
-      if(!propagateWithJacobian(false,3,s,P,Step)) return;
+      double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,cache.m_direction,0.};
+      if(!propagateWithJacobian(cache,false,3,s,P,Step)) return;
     }
     else return;
 
-    if(m_maxPathLimit) return;
+    if(cache.m_maxPathLimit) return;
 
     Amg::Vector3D gp(P[0],P[1],P[2]); GP.push_back(std::make_pair(gp,Step));
   }
@@ -1370,7 +1388,8 @@ void Trk::RungeKuttaPropagator::globalPositions
 /////////////////////////////////////////////////////////////////////////////////
 
 bool Trk::RungeKuttaPropagator::propagateRungeKutta
-(bool                           useJac,
+(Cache&                         cache,
+ bool                           useJac,
  Trk::PatternTrackParameters  & Ta    ,
  const Trk::Surface           & Su    ,
  Trk::PatternTrackParameters  & Tb    ,
@@ -1381,13 +1400,13 @@ bool Trk::RungeKuttaPropagator::propagateRungeKutta
   const Trk::Surface* su = &Su; if(!su) return false;
   if(su == Ta.associatedSurface()) {Tb = Ta; return true;}
 
-  m_direction               = D ; 
+  cache.m_direction               = D ; 
 
   if(useJac && !Ta.iscovariance()) useJac = false;
 
-  M.magneticFieldMode()==2  ? m_solenoid     = true : m_solenoid     = false;  
-  (useJac && m_usegradient) ? m_needgradient = true : m_needgradient = false; 
-  M.magneticFieldMode()!=0  ? m_mcondition   = true : m_mcondition   = false;
+  M.magneticFieldMode()==2  ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  (useJac && m_usegradient) ? cache.m_needgradient = true : cache.m_needgradient = false; 
+  M.magneticFieldMode()!=0  ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   Trk::RungeKuttaUtils utils;
 
@@ -1402,12 +1421,12 @@ bool Trk::RungeKuttaPropagator::propagateRungeKutta
 
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(useJac,1,s,P,Step)) return false;
+    if(!propagateWithJacobian(cache,useJac,1,s,P,Step)) return false;
   }
     else if (ty == Trk::Surface::Line     ) {
 
     double s[6] ={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(useJac,0,s,P,Step)) return false;
+    if(!propagateWithJacobian(cache,useJac,0,s,P,Step)) return false;
   }
   else if (ty == Trk::Surface::Disc     ) {
 
@@ -1415,37 +1434,37 @@ bool Trk::RungeKuttaPropagator::propagateRungeKutta
 
     if(d>=0.) {s[0]= T(0,2); s[1]= T(1,2); s[2]= T(2,2); s[3]= d;}
     else      {s[0]=-T(0,2); s[1]=-T(1,2); s[2]=-T(2,2); s[3]=-d;}
-    if(!propagateWithJacobian(useJac,1,s,P,Step)) return false;
+    if(!propagateWithJacobian(cache,useJac,1,s,P,Step)) return false;
   }
   else if (ty == Trk::Surface::Cylinder ) {
 
     const Trk::CylinderSurface* cyl = static_cast<const Trk::CylinderSurface*>(su);
 
     double r0[3] = {P[0],P[1],P[2]};
-    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),m_direction,0.};
+    double s [9] = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),cyl->bounds().r(),cache.m_direction,0.};
 
-    if(!propagateWithJacobian(useJac,2,s,P,Step)) return false;
+    if(!propagateWithJacobian(cache,useJac,2,s,P,Step)) return false;
 
     // For cylinder we do test for next cross point
     //
     if(cyl->bounds().halfPhiSector() < 3.1 && newCrossPoint(*cyl,r0,P)) {
-      s[8] = 0.; if(!propagateWithJacobian(useJac,2,s,P,Step)) return false;
+      s[8] = 0.; if(!propagateWithJacobian(cache,useJac,2,s,P,Step)) return false;
     }
   }
   else if (ty == Trk::Surface::Perigee  ) {
 
     double s[6] ={T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2)};
-    if(!propagateWithJacobian(useJac,0,s,P,Step)) return false;
+    if(!propagateWithJacobian(cache,useJac,0,s,P,Step)) return false;
   }
   else if (ty == Trk::Surface::Cone     ) {
     
     double k     = static_cast<const Trk::ConeSurface*>(su)->bounds().tanAlpha(); k = k*k+1.;
-    double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,m_direction,0.};
-    if(!propagateWithJacobian(useJac,3,s,P,Step)) return false;
+    double s[9]  = {T(0,3),T(1,3),T(2,3),T(0,2),T(1,2),T(2,2),k,cache.m_direction,0.};
+    if(!propagateWithJacobian(cache,useJac,3,s,P,Step)) return false;
   }
   else return false;
 
-  if(m_maxPathLimit || (m_direction && (m_direction*Step)<0.)) return false;
+  if(cache.m_maxPathLimit || (cache.m_direction && (cache.m_direction*Step)<0.)) return false;
 
   // Common transformation for all surfaces (angles and momentum)
   //
@@ -1530,14 +1549,14 @@ const Trk::NeutralParameters* Trk::RungeKuttaPropagator::buildTrackParametersWit
 /////////////////////////////////////////////////////////////////////////////////
 
 double Trk::RungeKuttaPropagator::stepEstimatorWithCurvature
-(int kind,double* Su,const double* P,bool& Q) const
+(Cache& cache, int kind,double* Su,const double* P,bool& Q) const
 {
   // Straight step estimation
   //
   Trk::RungeKuttaUtils utils;
   double  Step = utils.stepEstimator(kind,Su,P,Q); if(!Q) return 0.; 
   double AStep = fabs(Step);
-  if( kind || AStep < m_straightStep || !m_mcondition ) return Step;
+  if( kind || AStep < m_straightStep || !cache.m_mcondition ) return Step;
 
   const double* SA = &P[42]; // Start direction
   double S = .5*Step;
@@ -1560,15 +1579,16 @@ double Trk::RungeKuttaPropagator::stepEstimatorWithCurvature
 /////////////////////////////////////////////////////////////////////////////////
 
 void Trk::RungeKuttaPropagator::globalOneSidePositions 
-(std::list<Amg::Vector3D>      & GP,
+(Cache &                         cache,  
+ std::list<Amg::Vector3D>      & GP,
  const double                  * P,
  const MagneticFieldProperties & M ,
  const CylinderBounds          & CB,
  double                          mS,
  ParticleHypothesis                ) const
 {
-  M.magneticFieldMode()==2 ? m_solenoid   = true : m_solenoid  = false;  
-  M.magneticFieldMode()!=0 ? m_mcondition = true : m_mcondition = false;
+  M.magneticFieldMode()==2 ? cache.m_solenoid   = true : cache.m_solenoid  = false;  
+  M.magneticFieldMode()!=0 ? cache.m_mcondition = true : cache.m_mcondition = false;
 
   double Pm[45]; for(int i=0; i!=7; ++i) Pm[i]=P[i];
 
@@ -1580,7 +1600,7 @@ void Trk::RungeKuttaPropagator::globalOneSidePositions
   double       S     = mS                 ; // max step allowed
   double       R2m   = R2                 ;
 
-  if(m_mcondition && fabs(P[6]) > .1) return; 
+  if(cache.m_mcondition && fabs(P[6]) > .1) return; 
 
   // Test position of the track  
   //
@@ -1595,15 +1615,15 @@ void Trk::RungeKuttaPropagator::globalOneSidePositions
   int sm    = 1;
   for(int s = 0; s!=2; ++s) {
 
-    m_newfield = true;
+    cache.m_newfield = true;
 
     if(s) {if(per) break; S = -S;}
     double p[45]; for(int i=0; i!=7; ++i) p[i]=P[i]; p[42]=p[43]=p[44]=0.;
 
     while(W<100000. && ++niter < 1000) {
       
-      if(m_mcondition) {
-	W+=(S=rungeKuttaStep  (0,S,p,InS)); 
+      if(cache.m_mcondition) {
+	W+=(S=rungeKuttaStep  (cache,0,S,p,InS)); 
       }
       else {
 	W+=(S=straightLineStep(0,    S,p)); 
@@ -1642,14 +1662,14 @@ void Trk::RungeKuttaPropagator::globalOneSidePositions
 
   for(int s = 0; s!=3; ++s) {
 
-    m_newfield = true;
+    cache.m_newfield = true;
 
     double A = (1.-Pm[5])*(1.+Pm[5]); if(A==0.) break;
     S        = -(Pm[0]*Pm[3]+Pm[1]*Pm[4])/A;
     if(fabs(S) < 1. || ++niter > 1000) break;
 
-    if(m_mcondition) {
-      W+=rungeKuttaStep(0,S,Pm,InS); 
+    if(cache.m_mcondition) {
+      W+=rungeKuttaStep(cache,0,S,Pm,InS); 
     }
     else {
       W+=straightLineStep(0,S,Pm); 
@@ -1678,15 +1698,16 @@ void Trk::RungeKuttaPropagator::globalOneSidePositions
 /////////////////////////////////////////////////////////////////////////////////
 
 void Trk::RungeKuttaPropagator::globalTwoSidePositions 
-(std::list<Amg::Vector3D>      & GP,
+(Cache&                        cache,
+ std::list<Amg::Vector3D>      & GP,
  const double                  * P,
  const MagneticFieldProperties & M ,
  const CylinderBounds          & CB,
  double                          mS,
  ParticleHypothesis                ) const
 {
-  M.magneticFieldMode()==2 ? m_solenoid   = true : m_solenoid   = false;  
-  M.magneticFieldMode()!=0 ? m_mcondition = true : m_mcondition = false;
+  M.magneticFieldMode()==2 ? cache.m_solenoid   = true : cache.m_solenoid   = false;  
+  M.magneticFieldMode()!=0 ? cache.m_mcondition = true : cache.m_mcondition = false;
 
   double       W     = 0.                 ; // way
   double       R2max = CB.r()*CB.r()      ; // max. radius**2 of region
@@ -1694,7 +1715,7 @@ void Trk::RungeKuttaPropagator::globalTwoSidePositions
   double       R2    = P[0]*P[0]+P[1]*P[1]; // Start radius**2
   double       S     = mS                 ; // max step allowed
 
-  if(m_mcondition && fabs(P[6]) > .1) return; 
+  if(cache.m_mcondition && fabs(P[6]) > .1) return; 
 
   // Test position of the track  
   //
@@ -1707,15 +1728,15 @@ void Trk::RungeKuttaPropagator::globalTwoSidePositions
   int niter = 0;
   for(int s = 0; s!=2; ++s) {
 
-    m_newfield = true;
+    cache.m_newfield = true;
     
     if(s) {S = -S;}
     double p[45]; for(int i=0; i!=7; ++i) p[i]=P[i]; p[42]=p[43]=p[44]=0.;
 
     while(W<100000. && ++niter < 1000) {
       
-      if(m_mcondition) {
-	W+=(S=rungeKuttaStep  (0,S,p,InS)); 
+      if(cache.m_mcondition) {
+	W+=(S=rungeKuttaStep  (cache,0,S,p,InS)); 
       }
       else {
 	W+=(S=straightLineStep(0,    S,p)); 
@@ -1817,16 +1838,17 @@ double Trk::RungeKuttaPropagator::stepReduction(const double* E) const
 /////////////////////////////////////////////////////////////////////////////////
 
 void Trk::RungeKuttaPropagator::propagateStep
-(const Amg::Vector3D& Ri,const  Amg::Vector3D& Pi,
+( const Amg::Vector3D& Ri,const  Amg::Vector3D& Pi,
  double Charge,double Step,
  Amg::Vector3D& Ro, Amg::Vector3D& Po, 
  const MagneticFieldProperties& Mag)
 {
 
+  Cache cache{};
   // Magnetic field information preparation
   //
-  Mag.magneticFieldMode()==2 ? m_solenoid   = true : m_solenoid   = false;  
-  Mag.magneticFieldMode()!=0 ? m_mcondition = true : m_mcondition = false;
+  Mag.magneticFieldMode()==2 ? cache.m_solenoid   = true : cache.m_solenoid   = false;  
+  Mag.magneticFieldMode()!=0 ? cache.m_mcondition = true : cache.m_mcondition = false;
 
   double M  = sqrt(Pi[0]*Pi[0]+Pi[1]*Pi[1]+Pi[2]*Pi[2]); if(M < .00001) {Ro = Ri; Po = Pi; return;}
   double Mi = 1./M;
@@ -1839,11 +1861,11 @@ void Trk::RungeKuttaPropagator::propagateStep
   double S = Step ;
   double W = 0.   ;
 
-  m_newfield = true;
+  cache.m_newfield = true;
 
   while (true) {
 
-    if(m_mcondition) {W+=(S=rungeKuttaStep  (false,S,P,In));}
+    if(cache.m_mcondition) {W+=(S=rungeKuttaStep  (cache,false,S,P,In));}
     else             {W+=(S=straightLineStep(false,S,P   ));}
 
     double ws  = Step-W  ;