diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/CMakeLists.txt b/Trigger/TrigAlgorithms/TrigL2MuonSA/CMakeLists.txt
index e565d1558255b6e9adf2aab811dfd5bf93a377f2..4f206331aecbf43d7557a8707b5c2c719c8dffcd 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/CMakeLists.txt
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/CMakeLists.txt
@@ -14,7 +14,7 @@ atlas_add_library( TrigL2MuonSALib
                    src/*.cxx
                    PUBLIC_HEADERS TrigL2MuonSA
                    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${GSL_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringKernelLib ByteStreamCnvSvcBaseLib CscClusterizationLib GaudiKernel GeoPrimitives Identifier MdtCalibSvcLib MuonCablingData MuonCnvToolInterfacesLib MuonIdHelpersLib MuonPrepRawData MuonRDO MuonRecToolInterfaces MuonTGC_CablingLib RPC_CondCablingLib RegionSelectorLib StoreGateLib TrigInterfacesLib TrigMuonToolInterfaces TrigSteeringEvent TrigT1Interfaces TrigT1RPCRecRoiSvcLib TrigTimeAlgsLib xAODEventInfo xAODTrigMuon xAODTrigger
+                   LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaBaseComps AthenaMonitoringKernelLib ByteStreamCnvSvcBaseLib CscClusterizationLib GaudiKernel GeoPrimitives Identifier MdtCalibSvcLib MuonCablingData MuonCnvToolInterfacesLib MuonIdHelpersLib MuonPrepRawData MuonRDO MuonRecToolInterfaces MuonTGC_CablingLib RPC_CondCablingLib RegionSelectorLib StoreGateLib TrigInterfacesLib TrigMuonToolInterfaces TrigSteeringEvent TrigT1Interfaces TrkExInterfaces TrigT1RPCRecRoiSvcLib TrigTimeAlgsLib xAODEventInfo xAODTrigMuon xAODTrigger xAODTracking
                    PRIVATE_LINK_LIBRARIES ${CLHEP_LIBRARIES} ${GSL_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} AthenaInterprocess CxxUtils EventInfo GeoModelUtilities MuonCalibEvent MuonReadoutGeometry PathResolver )
 
 atlas_add_component( TrigL2MuonSA
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/FtfRoadDefiner.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/FtfRoadDefiner.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d7789555e3f7f486b3a044ed53ef0e554fca64dd
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/FtfRoadDefiner.cxx
@@ -0,0 +1,199 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "FtfRoadDefiner.h"
+
+TrigL2MuonSA::FtfRoadDefiner::FtfRoadDefiner(const std::string& type,
+                                             const std::string& name,
+                                             const IInterface*  parent):
+  AthAlgTool(type, name, parent)
+{
+}
+
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
+
+StatusCode TrigL2MuonSA::FtfRoadDefiner::initialize()
+{
+
+  ATH_CHECK( m_extrapolator.retrieve() );
+
+  return StatusCode::SUCCESS;
+}
+
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
+
+StatusCode TrigL2MuonSA::FtfRoadDefiner::defineRoad(const xAOD::TrackParticle* idtrack,
+						    TrigL2MuonSA::MuonRoad&    muonRoad)
+{
+  ATH_MSG_DEBUG("FtfRoadDefiner::defineRoad");
+
+  const int N_SECTOR = 2; // 0: normal, 1:overlap
+
+  double extFtfInnerEta=0.,  extFtfInnerZ=0.,  extFtfInnerR=0.,  extFtfInnerPhi=0.;
+  double extFtfMiddleEta=0., extFtfMiddleZ=0., extFtfMiddleR=0., extFtfMiddlePhi=0.;
+  double extFtfOuterEta=0.,  extFtfOuterZ=0.,  extFtfOuterR=0.,  extFtfOuterPhi=0.;
+
+  double aw_ftf[3]={0.,0.,0.}; // slope of FTF Road for Inner/Middle/Outer
+  double bw_ftf[3]={0.,0.,0.}; // intercept of FTF Road for Inner/Middle/Outer
+
+  // Inner
+  auto extFtfInner = extTrack( idtrack, 5000., 6000., muonRoad.ext_ftf_flag[0][0]); //Large secotr
+  if( !extFtfInner ) {
+    ATH_MSG_DEBUG("extrapolated track parameters on BarrelInner is null");
+  } else {
+    extFtfInnerEta = extFtfInner->eta();
+    extFtfInnerPhi = extFtfInner->position().phi();
+    extFtfInnerZ = extFtfInner->position().z();
+    extFtfInnerR = std::hypot(extFtfInner->position().x(), extFtfInner->position().y());
+    ATH_MSG_DEBUG("extFtfInnerEta: " << extFtfInnerEta << ", extFtfInnerPhi: " << extFtfInnerPhi << ", extFtfInnerZ: " << extFtfInnerZ << ", extFtfInnerR: " << extFtfInnerR);
+    aw_ftf[0] = std::tan(2*std::atan(std::exp(-extFtfInnerEta)));
+    bw_ftf[0] = extFtfInnerR - (aw_ftf[0])*extFtfInnerZ;
+    muonRoad.r_ftf[0][0] = extFtfInnerR;
+    muonRoad.z_ftf[0][0] = extFtfInnerZ;
+  }
+
+  // Middle
+  auto extFtfMiddle = extTrack( idtrack , 8000., 9000., muonRoad.ext_ftf_flag[1][0]);
+  if( !extFtfMiddle ) {
+    ATH_MSG_DEBUG("extrapolated track parameters on BarrelMiddle is null");
+  } else {
+    extFtfMiddleEta = extFtfMiddle->eta();
+    extFtfMiddlePhi = extFtfMiddle->position().phi();
+    extFtfMiddleZ = extFtfMiddle->position().z();
+    extFtfMiddleR = std::hypot(extFtfMiddle->position().x(), extFtfMiddle->position().y());
+    ATH_MSG_DEBUG("extFtfMiddleEta: " << extFtfMiddleEta << ", extFtfMiddlePhi: " << extFtfMiddlePhi << ", extFtfMiddleZ: " << extFtfMiddleZ << ", extFtfMiddleR: " << extFtfMiddleR);
+    aw_ftf[1] = std::tan(2*std::atan(std::exp(-extFtfMiddleEta)));
+    bw_ftf[1] = extFtfMiddleR - (aw_ftf[1])*extFtfMiddleZ;
+    muonRoad.r_ftf[1][0] = extFtfMiddleR;
+    muonRoad.z_ftf[1][0] = extFtfMiddleZ;
+  }
+
+  // Outer
+  auto extFtfOuter = extTrack( idtrack , 10000., 12500., muonRoad.ext_ftf_flag[2][0]);
+  if( !extFtfOuter ) {
+    ATH_MSG_DEBUG("extrapolated track parameters on BarrelOuter is null");
+  } else {
+    extFtfOuterEta = extFtfOuter->eta();
+    extFtfOuterPhi = extFtfOuter->position().phi();
+    extFtfOuterZ = extFtfOuter->position().z();
+    extFtfOuterR = std::hypot(extFtfOuter->position().x(), extFtfOuter->position().y());
+    ATH_MSG_DEBUG("extFtfOuterEta: " << extFtfOuterEta << ", extFtfOuterPhi: " << extFtfOuterPhi << ", extFtfOuterZ: " << extFtfOuterZ << ", extFtfOuterR: " << extFtfOuterR);
+    aw_ftf[2] = std::tan(2*std::atan(std::exp(-extFtfOuterEta)));
+    bw_ftf[2] = extFtfOuterR - (aw_ftf[2])*extFtfOuterZ;
+    muonRoad.r_ftf[2][0] = extFtfOuterR;
+    muonRoad.z_ftf[2][0] = extFtfOuterZ;
+  }
+
+  muonRoad.extFtfMiddleEta = extFtfMiddleEta;
+  muonRoad.extFtfMiddlePhi = extFtfMiddlePhi;
+
+  for (int i_sector=0; i_sector<N_SECTOR; i_sector++) { // 0: normal sector, 1: overlap sector, which is used when a muon pass through boundary of MS sectors
+    muonRoad.aw_ftf[0][i_sector]  = aw_ftf[0];
+    muonRoad.bw_ftf[0][i_sector]  = bw_ftf[0];
+    muonRoad.aw_ftf[1][i_sector]  = aw_ftf[1];
+    muonRoad.bw_ftf[1][i_sector]  = bw_ftf[1];
+    muonRoad.aw_ftf[2][i_sector]  = aw_ftf[2];
+    muonRoad.bw_ftf[2][i_sector]  = bw_ftf[2];
+    muonRoad.aw_ftf[3][i_sector]  = aw_ftf[0];
+    muonRoad.bw_ftf[3][i_sector]  = bw_ftf[0];
+    muonRoad.aw_ftf[4][i_sector]  = aw_ftf[1];
+    muonRoad.bw_ftf[4][i_sector]  = bw_ftf[1];
+    muonRoad.aw_ftf[5][i_sector]  = aw_ftf[2];
+    muonRoad.bw_ftf[5][i_sector]  = bw_ftf[2];
+    muonRoad.aw_ftf[6][i_sector]  = aw_ftf[0];
+    muonRoad.bw_ftf[6][i_sector]  = bw_ftf[0];
+    muonRoad.aw_ftf[7][i_sector]  = aw_ftf[0];
+    muonRoad.bw_ftf[7][i_sector]  = bw_ftf[0];
+    muonRoad.aw_ftf[8][i_sector]  = aw_ftf[0];
+    muonRoad.bw_ftf[8][i_sector]  = bw_ftf[0];
+    muonRoad.aw_ftf[9][i_sector]  = aw_ftf[1];//BME
+    muonRoad.bw_ftf[9][i_sector]  = bw_ftf[1];
+    muonRoad.aw_ftf[10][i_sector] = aw_ftf[1];//BMG
+    muonRoad.bw_ftf[10][i_sector] = bw_ftf[1];
+
+    muonRoad.eta_ftf[0][i_sector]  = extFtfInnerEta;
+    muonRoad.phi_ftf[0][i_sector]  = extFtfInnerPhi;
+    muonRoad.eta_ftf[1][i_sector]  = extFtfMiddleEta;
+    muonRoad.phi_ftf[1][i_sector]  = extFtfMiddlePhi;
+    muonRoad.eta_ftf[2][i_sector]  = extFtfOuterEta;
+    muonRoad.phi_ftf[2][i_sector]  = extFtfOuterPhi;
+    muonRoad.eta_ftf[3][i_sector]  = extFtfInnerEta;
+    muonRoad.phi_ftf[3][i_sector]  = extFtfInnerPhi;
+    muonRoad.eta_ftf[4][i_sector]  = extFtfMiddleEta;
+    muonRoad.phi_ftf[4][i_sector]  = extFtfMiddlePhi;
+    muonRoad.eta_ftf[5][i_sector]  = extFtfOuterEta;
+    muonRoad.phi_ftf[5][i_sector]  = extFtfOuterPhi;
+    muonRoad.eta_ftf[6][i_sector]  = extFtfInnerEta;
+    muonRoad.phi_ftf[6][i_sector]  = extFtfInnerPhi;
+    muonRoad.eta_ftf[7][i_sector]  = extFtfInnerEta;
+    muonRoad.phi_ftf[7][i_sector]  = extFtfInnerPhi;
+    muonRoad.eta_ftf[8][i_sector]  = extFtfInnerEta;
+    muonRoad.phi_ftf[8][i_sector]  = extFtfInnerPhi;
+    muonRoad.eta_ftf[9][i_sector]  = extFtfMiddleEta;//BME
+    muonRoad.phi_ftf[9][i_sector]  = extFtfMiddlePhi;
+    muonRoad.eta_ftf[10][i_sector] = extFtfMiddleEta;//BMG
+    muonRoad.phi_ftf[10][i_sector] = extFtfMiddlePhi;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
+
+// extrapolate a FTF track to MS in order to define FTF Road
+std::unique_ptr<const Trk::TrackParameters> TrigL2MuonSA::FtfRoadDefiner::extTrack( const xAOD::TrackParticle* trk, const double R, const double halflength, int& extFlag ) {
+
+  const bool boundaryCheck = true;
+  bool bCylinder = false;
+  bool bDisk = false;
+
+  double Z = ( trk->eta()>0 )? halflength:-halflength;
+
+  // Cylinder
+  std::unique_ptr<const Trk::CylinderSurface> barrel = std::make_unique<const Trk::CylinderSurface>( R, Z );
+  std::unique_ptr<const Trk::TrackParameters> param1( m_extrapolator->extrapolate(*trk, *barrel, Trk::anyDirection, boundaryCheck, Trk::muon) );
+  if(param1){
+    bCylinder = true;
+    ATH_MSG_DEBUG("Cylinder -> eta: " << param1->eta() << ", phi: " << param1->position().phi() << ", Z: " << param1->position().z() << ", Rms: " << std::hypot(param1->position().x(), param1->position().y()));
+  } else {
+    ATH_MSG_DEBUG("Cylinder -> extrapolated track parameters on Cylinder is null");
+  }
+
+  // Disk
+  Amg::Transform3D* matrix = new Amg::Transform3D( Amg::Vector3D( 0.,0.,Z ) );
+
+  std::unique_ptr<const Trk::DiscSurface> disc = std::make_unique<const Trk::DiscSurface>( matrix, 0, R );
+  std::unique_ptr<const Trk::TrackParameters> param2( m_extrapolator->extrapolate(*trk, *disc, Trk::anyDirection, boundaryCheck, Trk::muon) );
+  if(param2){
+    bDisk = true;
+    ATH_MSG_DEBUG("Disk     -> eta: " << param2->eta() << ", phi: " << param2->position().phi() << ", Z: " << param2->position().z() << ", Rms: " << std::hypot(param2->position().x(), param2->position().y()));
+  } else {
+    ATH_MSG_DEBUG("Disk     -> extrapolated track parameters on Disk is null");
+  }
+
+  ATH_MSG_DEBUG("R: " << R << ", Z: " << Z);
+  ATH_MSG_DEBUG("bCylinder:" << bCylinder << ", bDisk:" << bDisk );
+
+  matrix = 0;
+  delete matrix;
+
+  if ( bCylinder && bDisk ){
+    extFlag = 0;
+    return param1;
+  } else if ( bCylinder && !bDisk){
+    extFlag = 1;
+    return param1;
+  } else if ( !bCylinder && bDisk){
+    extFlag = 2;
+    return param2;
+  } else {
+    extFlag = 3;
+    return param1;
+  }
+
+  return nullptr;
+}
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/FtfRoadDefiner.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/FtfRoadDefiner.h
new file mode 100644
index 0000000000000000000000000000000000000000..a814605967a3392065ba2d3e2b8734793d617001
--- /dev/null
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/FtfRoadDefiner.h
@@ -0,0 +1,48 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef  TRIGL2MUONSA_FTFROADDEFINER_H
+#define  TRIGL2MUONSA_FTFROADDEFINER_H
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include "MuonRoad.h"
+
+#include "xAODTracking/TrackParticleContainer.h"
+#include "TrkExInterfaces/IExtrapolator.h"
+
+namespace TrigL2MuonSA {
+
+  // --------------------------------------------------------------------------------
+  // --------------------------------------------------------------------------------
+
+  class FtfRoadDefiner: public AthAlgTool
+  {
+  public:
+
+    FtfRoadDefiner(const std::string& type,
+		   const std::string& name,
+		   const IInterface*  parent);
+
+    virtual StatusCode initialize() override;
+
+  public:
+    StatusCode defineRoad( const xAOD::TrackParticle* idtrack,
+			   TrigL2MuonSA::MuonRoad&    muonRoad);
+    std::unique_ptr<const Trk::TrackParameters> extTrack( const xAOD::TrackParticle* trk, const double R, const double halflength,  int& extFlag );
+
+  protected:
+
+  private:
+    ToolHandle<Trk::IExtrapolator> m_extrapolator{
+      this, "IOExtrapolator", "Trk::Extrapolator/AtlasExtrapolator"};
+
+  };
+
+  // --------------------------------------------------------------------------------
+  // --------------------------------------------------------------------------------
+}
+
+#endif // TRIGL2MUONSA_FTFROADDEFINER_H
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtRegionDefiner.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtRegionDefiner.cxx
index a6946c94e455c3fa3194bdc74678bf5e92cd632e..33e4d6a109747d59d5cdb8b48b70f765534ce538 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtRegionDefiner.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MdtRegionDefiner.cxx
@@ -40,6 +40,7 @@ StatusCode TrigL2MuonSA::MdtRegionDefiner::getMdtRegions(const LVL1::RecMuonRoI*
 							 TrigL2MuonSA::MuonRoad& muonRoad,
 							 TrigL2MuonSA::MdtRegion& mdtRegion)
 {
+  constexpr double ZERO_LIMIT = 1e-5;
   mdtRegion.Clear();
   
   int sectors[2];
@@ -178,6 +179,11 @@ StatusCode TrigL2MuonSA::MdtRegionDefiner::getMdtRegions(const LVL1::RecMuonRoI*
   else {
     for (int i=0; i<6; i++){
       for (int j=0; j<2; j++){
+        if (std::abs(muonRoad.extFtfMiddlePhi) > ZERO_LIMIT) { // for inside-out
+          if (i==4) muonRoad.phi[9][j] = muonRoad.extFtfMiddlePhi;
+          else if (i==5) muonRoad.phi[10][j] = muonRoad.extFtfMiddlePhi;
+          else muonRoad.phi[i][j] = muonRoad.extFtfMiddlePhi;
+        }
         if (i==4) muonRoad.phi[9][j] = p_roi->phi();
         else if (i==5) muonRoad.phi[10][j] = p_roi->phi();
         else muonRoad.phi[i][j] = p_roi->phi();
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.cxx
index 8f45444ac4f8522833f252f2ae9415e92c1d0ead..d963f86054986ae0eaec038db4c7239f420799df 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.cxx
@@ -172,6 +172,7 @@ void TrigL2MuonSA::MuFastDataPreparator::setExtrapolatorTool(ToolHandle<ITrigMuo
 
 StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRoI*     p_roi,
                                                            const TrigRoiDescriptor*    p_roids,
+                                                           const bool                  insideOut,
                                                            TrigL2MuonSA::RpcHits&      rpcHits,
                                                            TrigL2MuonSA::MuonRoad&     muonRoad,
                                                            TrigL2MuonSA::MdtRegion&    mdtRegion,
@@ -184,7 +185,7 @@ StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRo
   
   StatusCode sc = StatusCode::SUCCESS;
   
-  if(m_use_rpc) {
+  if(m_use_rpc && !insideOut) {
 
     m_rpcPatFinder->clear();
 
@@ -201,6 +202,8 @@ StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRo
     if (!sc.isSuccess()) {
       ATH_MSG_DEBUG("Error in RPC data prepapration. Continue using RoI");
     }
+  } else {
+    ATH_MSG_DEBUG("Skip RpcDataPreparator");
   }
 
   SG::ReadCondHandle<RpcCablingCondData> readHandle{m_readKey};
@@ -217,6 +220,7 @@ StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRo
   ATH_MSG_DEBUG("nr of RPC hits=" << rpcHits.size());
 
   sc = m_rpcRoadDefiner->defineRoad(p_roi,
+                                    insideOut,
                                     muonRoad,
                                     rpcHits,
                                     &m_rpcPatFinder,
@@ -254,6 +258,7 @@ StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRo
 
 StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRoI*     p_roi,
                                                            const TrigRoiDescriptor*    p_roids,
+                                                           const bool                  insideOut,
                                                            TrigL2MuonSA::TgcHits&      tgcHits,
                                                            TrigL2MuonSA::MuonRoad&     muonRoad,
                                                            TrigL2MuonSA::MdtRegion&    mdtRegion,
@@ -266,15 +271,21 @@ StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRo
 {
   StatusCode sc = StatusCode::SUCCESS;
   ATH_MSG_DEBUG("RoI eta/phi=" << p_roi->eta() << "/" << p_roi->phi());
-  
-  sc = m_tgcDataPreparator->prepareData(p_roi,
-                                        tgcHits);
+
+  if(!insideOut) {
+    sc = m_tgcDataPreparator->prepareData(p_roi,
+                                          tgcHits);
+  } else {
+    ATH_MSG_DEBUG("Skip TgcDataPreparator");
+  }
+
   if (!sc.isSuccess()) {
     ATH_MSG_DEBUG("Error in TGC data preparation. Continue using RoI");
   }
   ATH_MSG_DEBUG("nr of TGC hits=" << tgcHits.size());
-  
+
   sc = m_tgcRoadDefiner->defineRoad(p_roi,
+                                    insideOut,
                                     tgcHits,
                                     muonRoad,
                                     tgcFitResult);
@@ -282,7 +293,7 @@ StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRo
     ATH_MSG_WARNING("Error in road definition.");
     return sc;
   }
-  
+
   sc = m_mdtDataPreparator->prepareData(p_roi,
                                         p_roids,
                                         tgcFitResult,
@@ -297,7 +308,7 @@ StatusCode TrigL2MuonSA::MuFastDataPreparator::prepareData(const LVL1::RecMuonRo
   }
   ATH_MSG_DEBUG("nr of MDT (normal)  hits=" << mdtHits_normal.size());
   ATH_MSG_DEBUG("nr of MDT (overlap) hits=" << mdtHits_overlap.size());
-  
+
   if(!m_cscDataPreparator.empty()) {
     sc = m_cscDataPreparator->prepareData(p_roids,
 					  muonRoad,
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.h
index abe72e71d6dcf806b0aa0a54cb8de6f0ed846ffa..0f896e18374be9f4368ac61c76d35bda3bdfee29 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastDataPreparator.h
@@ -55,6 +55,7 @@ class MuFastDataPreparator: public AthAlgTool {
   
   StatusCode prepareData(const LVL1::RecMuonRoI*     p_roi,
 			 const TrigRoiDescriptor*    p_roids,
+			 const bool                  insideOut,
 			 TrigL2MuonSA::RpcHits&      rpcHits,
 			 TrigL2MuonSA::MuonRoad&     muonRoad,
 			 TrigL2MuonSA::MdtRegion&    mdtRegion,
@@ -64,6 +65,7 @@ class MuFastDataPreparator: public AthAlgTool {
   
   StatusCode prepareData(const LVL1::RecMuonRoI*     p_roi,
 			 const TrigRoiDescriptor*    p_roids,
+			 const bool                  insideOut,
 			 TrigL2MuonSA::TgcHits&      tgcHits,
 			 TrigL2MuonSA::MuonRoad&     muonRoad,
 			 TrigL2MuonSA::MdtRegion&    mdtRegion,
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx
index 1b70f6312da74ac71695a1d6ac1bd2cbe8cbe161..743f13929934ad5767b6dc7972d4e50c5eb613a8 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastPatternFinder.cxx
@@ -113,12 +113,12 @@ StatusCode TrigL2MuonSA::MuFastPatternFinder::findPatterns(const TrigL2MuonSA::M
   ATH_CHECK( findPatterns(muonRoad, mdtHits, v_trackPatterns) );
   ATH_CHECK( m_nswPatternFinder->findPatterns(muonRoad, stgcHits, mmHits, v_trackPatterns.back()) );
 
-  for(unsigned int i_hit=0; i_hit<v_trackPatterns.at(0).stgcSegment.size(); i_hit++) {
-    ATH_MSG_DEBUG("PatternFinder: output sTGC hits global eta/phi/r/z/layer/channelType/isOutlier " << v_trackPatterns.at(0).stgcSegment[i_hit].eta << "/" << v_trackPatterns.at(0).stgcSegment[i_hit].phi << "/" << v_trackPatterns.at(0).stgcSegment[i_hit].r << "/" << v_trackPatterns.at(0).stgcSegment[i_hit].z << "/" << v_trackPatterns.at(0).stgcSegment[i_hit].layerNumber << "/" << v_trackPatterns.at(0).stgcSegment[i_hit].channelType << "/" << v_trackPatterns.at(0).stgcSegment[i_hit].isOutlier);
+  for(unsigned int i_hit=0; i_hit<v_trackPatterns.back().stgcSegment.size(); i_hit++) {
+    ATH_MSG_DEBUG("PatternFinder: output sTGC hits global eta/phi/r/z/layer/channelType/isOutlier " << v_trackPatterns.back().stgcSegment[i_hit].eta << "/" << v_trackPatterns.back().stgcSegment[i_hit].phi << "/" << v_trackPatterns.back().stgcSegment[i_hit].r << "/" << v_trackPatterns.back().stgcSegment[i_hit].z << "/" << v_trackPatterns.back().stgcSegment[i_hit].layerNumber << "/" << v_trackPatterns.back().stgcSegment[i_hit].channelType << "/" << v_trackPatterns.back().stgcSegment[i_hit].isOutlier);
   }
 
-  for(unsigned int i_hit=0; i_hit<v_trackPatterns.at(0).mmSegment.size(); i_hit++) {
-    ATH_MSG_DEBUG("PatternFinder: output MM hits global eta/phi/r/z/layer/isOutlier " << v_trackPatterns.at(0).mmSegment[i_hit].eta << "/" << v_trackPatterns.at(0).mmSegment[i_hit].phi << "/" << v_trackPatterns.at(0).mmSegment[i_hit].r << "/" << v_trackPatterns.at(0).mmSegment[i_hit].z << "/" << v_trackPatterns.at(0).mmSegment[i_hit].layerNumber << "/" << v_trackPatterns.at(0).mmSegment[i_hit].isOutlier);
+  for(unsigned int i_hit=0; i_hit<v_trackPatterns.back().mmSegment.size(); i_hit++) {
+    ATH_MSG_DEBUG("PatternFinder: output MM hits global eta/phi/r/z/layer/isOutlier " << v_trackPatterns.back().mmSegment[i_hit].eta << "/" << v_trackPatterns.back().mmSegment[i_hit].phi << "/" << v_trackPatterns.back().mmSegment[i_hit].r << "/" << v_trackPatterns.back().mmSegment[i_hit].z << "/" << v_trackPatterns.back().mmSegment[i_hit].layerNumber << "/" << v_trackPatterns.back().mmSegment[i_hit].isOutlier);
   }
 
   return StatusCode::SUCCESS;
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.cxx
index 42fde417509e27b993fe9d96005f611d73057e46..fd7e12adc02c4335a11ca6c2d420ca15a668dc55 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.cxx
@@ -16,6 +16,11 @@
 
 #include "AthenaBaseComps/AthMsgStreamMacros.h"
 
+namespace{
+  constexpr double ZERO_LIMIT = 1.e-6;
+}
+
+
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
@@ -82,6 +87,7 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::setMCFlag(BooleanProperty use_mcLU
 // --------------------------------------------------------------------------------
 
 StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuonRoI*    p_roi,
+                                                              const TrigL2MuonSA::MuonRoad& muonRoad,
                                                               TrigL2MuonSA::RpcFitResult& rpcFitResult,
                                                               std::vector<TrigL2MuonSA::TrackPattern>& v_trackPatterns)
 {
@@ -91,15 +97,19 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuo
 
     if (rpcFitResult.isSuccess) {
       //      itTrack->phiMSDir = rpcFitResult.phiDir;
-      itTrack.phiMSDir = (cos(rpcFitResult.phi)!=0)? tan(rpcFitResult.phi): 0;
+      itTrack.phiMSDir = (cos(rpcFitResult.phi)!=0)? std::tan(rpcFitResult.phi): 0;
     } else {
-      itTrack.phiMSDir = (cos(p_roi->phi())!=0)? tan(p_roi->phi()): 0;
+      if ( std::abs(muonRoad.extFtfMiddlePhi) > ZERO_LIMIT ) { //inside-out
+	itTrack.phiMSDir = (cos(muonRoad.extFtfMiddlePhi)!=0)? std::tan(muonRoad.extFtfMiddlePhi): 0;
+      } else {
+	itTrack.phiMSDir = (cos(p_roi->phi())!=0)? std::tan(p_roi->phi()): 0;
+      }
       itTrack.isRpcFailure = true;
     }
 
     ATH_CHECK( superPointFitter(itTrack) );
   }
-  // 
+  //
 
   return StatusCode::SUCCESS;
 }
@@ -107,17 +117,22 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuo
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
-StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuonRoI*   p_roi,
-                                                              TrigL2MuonSA::TgcFitResult& tgcFitResult,
-                                                              std::vector<TrigL2MuonSA::TrackPattern>& v_trackPatterns)
+StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPointsSimple(const LVL1::RecMuonRoI*   p_roi,
+								    const TrigL2MuonSA::MuonRoad& muonRoad,
+								    TrigL2MuonSA::TgcFitResult& tgcFitResult,
+								    std::vector<TrigL2MuonSA::TrackPattern>& v_trackPatterns)
 {
-  
+
   for (TrigL2MuonSA::TrackPattern& itTrack : v_trackPatterns) { // loop for track candidates
 
     if (tgcFitResult.isSuccess) {
       itTrack.phiMSDir = tgcFitResult.phiDir;
     } else {
-      itTrack.phiMSDir = (cos(p_roi->phi())!=0)? tan(p_roi->phi()): 0;
+      if ( abs(muonRoad.extFtfMiddlePhi) > ZERO_LIMIT ) { //insideout
+	itTrack.phiMSDir = (cos(muonRoad.extFtfMiddlePhi)!=0)? tan(muonRoad.extFtfMiddlePhi): 0;
+      } else {
+	itTrack.phiMSDir = (cos(p_roi->phi())!=0)? tan(p_roi->phi()): 0;
+      }
       itTrack.isTgcFailure = true;
     }
 
@@ -125,7 +140,7 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuo
 
     ATH_CHECK( m_nswStationFitter->superPointFitter(p_roi, itTrack) );
   }
-  // 
+  //
   return StatusCode::SUCCESS;
 }
 
@@ -137,7 +152,7 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuo
                                                               TrigL2MuonSA::TgcFitResult& tgcFitResult,
                                                               std::vector<TrigL2MuonSA::TrackPattern>& v_trackPatterns)
 {
-  
+
   for (TrigL2MuonSA::TrackPattern& itTrack : v_trackPatterns) { // loop for track candidates
 
     if (tgcFitResult.isSuccess) {
@@ -152,6 +167,10 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuo
     makeReferenceLine(itTrack, muonRoad);
     ATH_CHECK( m_alphaBetaEstimate->setAlphaBeta(p_roi, tgcFitResult, itTrack, muonRoad) );
 
+    if ( itTrack.etaBin < -1 ) {
+      itTrack.etaBin = (int)((fabs(muonRoad.extFtfMiddleEta)-1.)/0.05); // eta binning is the same as AlphaBetaEstimate
+    }
+
     ATH_CHECK( m_ptFromAlphaBeta->setPt(itTrack,tgcFitResult) );
 
     double exInnerA = fromAlphaPtToInn(tgcFitResult,itTrack);
@@ -162,7 +181,7 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::findSuperPoints(const LVL1::RecMuo
     ATH_CHECK( m_nswStationFitter->superPointFitter(p_roi, itTrack) );
 
   }
-  // 
+  //
   return StatusCode::SUCCESS;
 }
 
@@ -177,7 +196,6 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::superPointFitter(TrigL2MuonSA::Tra
    float Xor, Yor, sigma, rm=0., phim=0;
    float Ymid, Xmid, Amid;
 
-   const float ZERO_LIMIT         = 1e-6;
    const unsigned int MAX_STATION = 10; // no BMG(Backup=10)
    const float SIGMA              = 0.0080;
    const float DRIFTSPACE_LIMIT   = 16.;
@@ -352,7 +370,6 @@ StatusCode TrigL2MuonSA::MuFastStationFitter::superPointFitter(TrigL2MuonSA::Tra
       float Ymid  = 0.;
       float Xmid  = 0.;
       float Amid  = 0.;
-      const float ZERO_LIMIT         = 1e-6;
       const float SIGMA              = 0.0080;
       const float DRIFTSPACE_LIMIT   = 16.;
       const int   MIN_MDT_FOR_FIT    = 3;
@@ -496,7 +513,6 @@ void TrigL2MuonSA::MuFastStationFitter::stationSPFit(TrigL2MuonSA::MdtHits*    m
   float Xor, Yor, sigma, rm=0., phim=0;
   float Ymid, Xmid, Amid;
  
-  const float ZERO_LIMIT         = 1e-6;
   const unsigned int MAX_STATION = 8;
   const float SIGMA              = 0.0080;
   const float DRIFTSPACE_LIMIT   = 16.;
@@ -1403,8 +1419,6 @@ int TrigL2MuonSA::MuFastStationFitter::Evlfit(int Ifla, TrigL2MuonSA::PBFitResul
   Ntry = 0;
   Ifit = 0;
   
-  const double ZERO_LIMIT = 1e-6;
-  
   for(j=0;j<pbFitResult.NPOI;j++) if(pbFitResult.IGLIN[j]>=1) pbFitResult.NDOF++;
   
   while(pbFitResult.NDOF>=1) {
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.h
index 0f407bb29318abdba42f6b8679d7569a242ff579..6cc69744fb6abfc0e50ec0d0e272af6a1310aa37 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastStationFitter.h
@@ -38,11 +38,13 @@ class MuFastStationFitter: public AthAlgTool
     
    public:
       StatusCode findSuperPoints(const LVL1::RecMuonRoI*    p_roi,
+				 const TrigL2MuonSA::MuonRoad& muonRoad,
 				 TrigL2MuonSA::RpcFitResult& rpcFitResult,
 				 std::vector<TrigL2MuonSA::TrackPattern>& v_trackPatterns);
-      StatusCode findSuperPoints(const LVL1::RecMuonRoI*    p_roi,
-				 TrigL2MuonSA::TgcFitResult& tgcFitResult,
-				 std::vector<TrigL2MuonSA::TrackPattern>& v_trackPatterns);
+      StatusCode findSuperPointsSimple(const LVL1::RecMuonRoI*    p_roi,
+				       const TrigL2MuonSA::MuonRoad& muonRoad,
+				       TrigL2MuonSA::TgcFitResult& tgcFitResult,
+				       std::vector<TrigL2MuonSA::TrackPattern>& v_trackPatterns);
 
       StatusCode findSuperPoints(const LVL1::RecMuonRoI*    p_roi,
                                  const TrigL2MuonSA::MuonRoad& muonRoad,
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx
index 7d6359611974ee8abd68087fc87e2064d7e9f41a..3169847a8bc76a9c45e85aaca886c9806e76ba8c 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.cxx
@@ -111,6 +111,12 @@ HLT::ErrorCode MuFastSteering::hltInitialize()
     return HLT::BAD_JOB_SETUP;
   }
 
+  // FtfRoadDefiner
+  if ( m_ftfRoadDefiner.retrieve().isFailure() ) {
+    ATH_MSG_ERROR("Could not retrieve " << m_ftfRoadDefiner);
+    return HLT::BAD_JOB_SETUP;
+  }
+
   // Set service tools
   m_trackExtrapolator->setExtrapolatorTool(&m_backExtrapolatorTool);
   m_dataPreparator->setExtrapolatorTool(&m_backExtrapolatorTool);
@@ -190,6 +196,16 @@ HLT::ErrorCode MuFastSteering::hltInitialize()
     ATH_MSG_ERROR("ReadHandleKey for DataVector<LVL1::RecMuonRoI> key:" << m_recRoiCollectionKey.key() << " initialize Failure!");
     return HLT::BAD_JOB_SETUP;
   }
+  // for Inside-Out mode ---
+  if (m_FTFtrackKey.initialize(m_insideOut).isFailure() ) {
+    ATH_MSG_ERROR("ReadHandleKey for xAOD::TrackParticleContainer key:" << m_FTFtrackKey.key() << " initialize Failure!");
+    return HLT::BAD_JOB_SETUP;
+  }
+  if (m_outputCBmuonCollKey.initialize(m_insideOut).isFailure() ) {
+    ATH_MSG_ERROR("ReadHandleKey for xAOD::L2CombinedMuonContainer key:" << m_outputCBmuonCollKey.key() << " initialize Failure!");
+    return HLT::BAD_JOB_SETUP;
+  }
+  // ----
   if (m_muFastContainerKey.initialize().isFailure() ) {
     ATH_MSG_ERROR("WriteHandleKey for xAOD::L2StandAloneMuonContainer key:" << m_muFastContainerKey.key() << " initialize Failure!");
     return HLT::BAD_JOB_SETUP;
@@ -263,6 +279,7 @@ const LVL1::RecMuonRoI* matchingRecRoI( uint32_t roiWord,
 StatusCode MuFastSteering::execute()
 {
   ATH_MSG_DEBUG("StatusCode MuFastSteering::execute start");
+  ATH_MSG_DEBUG("InsideOutMode: " << m_insideOut);
 
   auto totalTimer = Monitored::Timer( "TIME_Total" );
   auto monitorIt	= Monitored::Group(m_monTool, totalTimer );
@@ -351,10 +368,37 @@ StatusCode MuFastSteering::execute()
   auto muMsContainer = SG::makeHandle(m_muMsContainerKey, ctx);
   ATH_CHECK(muMsContainer.record(std::make_unique<TrigRoiDescriptorCollection>()));
 
-  // to StatusCode findMuonSignature()
-  ATH_CHECK(findMuonSignature(internalRoI, recRoIVector,
-			      *muFastContainer, *muIdContainer, *muMsContainer, *muCompositeContainer ));
 
+  // Inside-out L2Muon mode
+  if(m_insideOut) {
+    ATH_MSG_DEBUG("start inside-out mode...");
+
+    auto muonCBColl = SG::makeHandle (m_outputCBmuonCollKey, ctx);
+    ATH_CHECK( muonCBColl.record (std::make_unique<xAOD::L2CombinedMuonContainer>(),
+				  std::make_unique<xAOD::L2CombinedMuonAuxContainer>()) );
+
+    auto trackHandle = SG::makeHandle( m_FTFtrackKey, ctx );
+    if (!trackHandle.isValid()){
+      ATH_MSG_ERROR("ReadHandle for TrackParticleContainer key:" << m_FTFtrackKey.key() << " isn't Valid");
+      return StatusCode::FAILURE;
+    }
+    const xAOD::TrackParticleContainer *tracks = trackHandle.cptr();
+
+    ATH_CHECK(findMuonSignatureIO(*tracks, internalRoI, recRoIVector,
+				  *muonCBColl, *muFastContainer ));
+
+    ATH_MSG_DEBUG("REGTEST: xAOD::L2CombinedMuonContainer key:" << m_outputCBmuonCollKey.key() << " size = " << muonCBColl->size());
+    for (const auto p_CBmuon : *muonCBColl){
+      ATH_MSG_DEBUG("REGTEST: xAOD::L2CombinedMuonContainer key:" << m_outputCBmuonCollKey.key() << " pt = " << (*p_CBmuon).pt() << " GeV");
+      ATH_MSG_DEBUG("REGTEST: xAOD::L2CombinedMuonContainer key:" << m_outputCBmuonCollKey.key() << " eta/phi = " << (*p_CBmuon).eta() << "/" << (*p_CBmuon).phi());
+    }
+
+  }
+  else {
+    // to StatusCode findMuonSignature()
+    ATH_CHECK(findMuonSignature(internalRoI, recRoIVector,
+				*muFastContainer, *muIdContainer, *muMsContainer, *muCompositeContainer ));
+  }
 
   // DEBUG TEST: Recorded data objects
   ATH_MSG_DEBUG("Recorded data objects");
@@ -627,6 +671,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
       m_tgcHits.clear();
       sc = m_dataPreparator->prepareData(*p_roi,
                                          *p_roids,
+                                         m_insideOut,
                                          m_rpcHits,
                                          m_muonRoad,
                                          m_mdtRegion,
@@ -642,7 +687,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
       }
       if (m_use_timer) m_timingTimers[ITIMER_DATA_PREPARATOR]->pause();
       prepTimer.stop();
@@ -656,7 +701,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::FAILURE;
+	continue;
       }
 
       // Pattern finding
@@ -672,7 +717,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
       }
       if (m_use_timer) m_timingTimers[ITIMER_PATTERN_FINDER]->pause();
       patternTimer.stop();
@@ -681,6 +726,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
       if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->resume();
       stationFitterTimer.start();
       sc = m_stationFitter->findSuperPoints(*p_roi,
+                                            m_muonRoad,
                                             m_rpcFitResult,
                                             trackPatterns);
       if (!sc.isSuccess()) {
@@ -690,7 +736,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
       }
       if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->pause();
       stationFitterTimer.stop();
@@ -709,7 +755,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
       }
       if (m_use_timer) m_timingTimers[ITIMER_TRACK_FITTER]->pause();
       trackFitterTimer.stop();
@@ -723,6 +769,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
       m_tgcHits.clear();
       sc = m_dataPreparator->prepareData(*p_roi,
                                          *p_roids,
+                                         m_insideOut,
                                          m_tgcHits,
                                          m_muonRoad,
                                          m_mdtRegion,
@@ -741,7 +788,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
       }
       if (m_use_timer) m_timingTimers[ITIMER_DATA_PREPARATOR]->pause();
       prepTimer.stop();
@@ -764,7 +811,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
       }
       if (m_use_timer) m_timingTimers[ITIMER_PATTERN_FINDER]->pause();
       patternTimer.stop();
@@ -773,9 +820,10 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
       if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->resume();
       stationFitterTimer.start();
       if(!m_use_new_segmentfit){
-        sc = m_stationFitter->findSuperPoints(*p_roi,
-                                              m_tgcFitResult,
-                                              trackPatterns);
+        sc = m_stationFitter->findSuperPointsSimple(*p_roi,
+						    m_muonRoad,
+						    m_tgcFitResult,
+						    trackPatterns);
       }else{
         sc = m_stationFitter->findSuperPoints(*p_roi,
                                               m_muonRoad,
@@ -792,7 +840,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
       }
 
       if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->pause();
@@ -813,7 +861,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
         	            m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			    m_stgcHits, m_mmHits,
                             trackPatterns, outputTracks, outputID, outputMS);
-        return StatusCode::SUCCESS;
+	continue;
         }
       if (m_use_timer) m_timingTimers[ITIMER_TRACK_FITTER]->pause();
       trackFitterTimer.stop();
@@ -844,7 +892,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
       	                  m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			  m_stgcHits, m_mmHits,
                           trackPatterns, outputTracks, outputID, outputMS);
-      return StatusCode::SUCCESS;
+      continue;
     }
     if (m_use_timer) m_timingTimers[ITIMER_TRACK_EXTRAPOLATOR]->pause();
     trackExtraTimer.stop();
@@ -858,7 +906,7 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
        	                  m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits, 
 			  m_stgcHits, m_mmHits,
                           trackPatterns, outputTracks, outputID, outputMS);
-      return StatusCode::SUCCESS;
+      continue;
     }
 
     // Update output trigger element
@@ -939,6 +987,381 @@ StatusCode MuFastSteering::findMuonSignature(const std::vector<const TrigRoiDesc
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 
+// findMuonSignature of L2 inside-out version
+// try to find MS tracks seeded by FTF tracks
+StatusCode MuFastSteering::findMuonSignatureIO(const xAOD::TrackParticleContainer&         idtracks,
+					       const std::vector<const TrigRoiDescriptor*> roids,
+					       const std::vector<const LVL1::RecMuonRoI*>  muonRoIs,
+					       DataVector<xAOD::L2CombinedMuon>&           outputCBs,
+					       DataVector<xAOD::L2StandAloneMuon>&         outputSAs)
+{
+  ATH_MSG_DEBUG("StatusCode MuFastSteering::findMuonSignatureIO start");
+  StatusCode sc = StatusCode::SUCCESS;
+  const float ZERO_LIMIT = 1.e-5;
+
+  auto prepTimer           = Monitored::Timer( "TIME_Data_Preparator" );
+  auto patternTimer        = Monitored::Timer( "TIME_Pattern_Finder" );
+  auto stationFitterTimer  = Monitored::Timer( "TIME_Station_Fitter" );
+  auto trackFitterTimer    = Monitored::Timer( "TIME_Track_Fitter" );
+  auto trackExtraTimer     = Monitored::Timer( "TIME_Track_Extrapolator" );
+  auto calibrationTimer    = Monitored::Timer( "TIME_Calibration_Streamer" );
+
+  auto monitorIt       = Monitored::Group(m_monTool, prepTimer, patternTimer, stationFitterTimer,
+					  trackFitterTimer, trackExtraTimer, calibrationTimer );
+
+  if (m_use_timer){
+    for (int i_timer = m_timingTimers.size()-1; i_timer>=0; --i_timer){
+      m_timingTimers[i_timer]->start();
+      if (i_timer != ITIMER_TOTAL_PROCESSING && i_timer != ITIMER_TOTAL_PROCESSING) m_timingTimers[i_timer]->pause();
+    }
+  }
+
+  DataVector<const TrigRoiDescriptor>::const_iterator p_roids;
+
+  p_roids = roids.begin();
+  for (const auto p_roi : muonRoIs) {
+
+    ATH_MSG_DEBUG("roi eta/phi: " << (*p_roi).eta() << "/" << (*p_roi).phi());
+
+    // idtracks loop
+    if ( (idtracks).empty() ) ATH_MSG_DEBUG("IO TEST: xAOD::TrackParticleContainer has 0 tracks --> Can not use FTF tracks...");
+    else  ATH_MSG_DEBUG("IO TEST: xAOD::TrackParticleContainer has " << (idtracks).size() << " tracks --> Start inside-out mode!");
+
+    std::vector<TrigL2MuonSA::TrackPattern> trackPatterns;
+    int idtrack_idx = -1;
+    for (auto idtrack : idtracks) {
+
+      idtrack_idx++;
+      ATH_MSG_DEBUG("IO TEST: FTF track key:" << m_FTFtrackKey.key() << " pt = " << idtrack->pt()/1000 << " GeV");
+      ATH_MSG_DEBUG("IO TEST: FTF track key:" << m_FTFtrackKey.key() << " eta/phi = " << idtrack->eta() << "/" << idtrack->phi());
+
+      if(idtrack->pt() < m_ftfminPt) {
+	ATH_MSG_DEBUG("IO TEST: skip FTF track due to pT threshold: " << m_ftfminPt << " MeV");
+	continue;
+      }
+
+      prepTimer.start();
+      m_mdtHits_normal.clear();
+      m_mdtHits_overlap.clear();
+      m_cscHits.clear();
+      m_stgcHits.clear();
+      m_mmHits.clear();
+      m_rpcFitResult.Clear();
+      m_tgcFitResult.Clear();
+      m_rpcHits.clear();
+      m_tgcHits.clear();
+
+      m_muonRoad.Clear();
+      bool hasSP = false;
+
+      sc = m_ftfRoadDefiner->defineRoad(idtrack, m_muonRoad);
+      if (!sc.isSuccess()) {
+	ATH_MSG_WARNING("FtfRoadDefiner failed");
+	continue;
+      } else {
+	ATH_MSG_DEBUG("FtfRoadDefiner::defineRoad success");
+      }
+
+      if ( std::abs(idtrack->eta()) < 1.05 ){
+	ATH_MSG_DEBUG("FTF track at IP is in  Barrel: " << idtrack->eta());
+      } else {
+	ATH_MSG_DEBUG("FTF track at IP is in  Endcap: " << idtrack->eta());
+      }
+
+      if ( std::abs(m_muonRoad.extFtfMiddleEta) < 1.05 ){ // Barrel Inside-out
+	ATH_MSG_DEBUG("m_muonRoad.extFtfMiddleEta Barrel: " << m_muonRoad.extFtfMiddleEta);
+
+	ATH_MSG_DEBUG("Barrel algorithm of IOmode starts");
+
+	m_muonRoad.setScales(m_scaleRoadBarrelInner,
+			     m_scaleRoadBarrelMiddle,
+			     m_scaleRoadBarrelOuter);
+
+	// Data preparation
+	sc = m_dataPreparator->prepareData(p_roi,
+					   *p_roids,
+					   m_insideOut,
+					   m_rpcHits,
+					   m_muonRoad,
+					   m_mdtRegion,
+					   m_rpcFitResult,
+					   m_mdtHits_normal,
+					   m_mdtHits_overlap);
+	if (!sc.isSuccess()) {
+	  ATH_MSG_WARNING("Data preparation failed");
+	  continue;
+	} else {
+	  ATH_MSG_DEBUG("Data preparation success");
+	}
+	if (m_use_timer) m_timingTimers[ITIMER_DATA_PREPARATOR]->pause();
+	prepTimer.stop();
+
+	// Pattern finding
+	if (m_use_timer) m_timingTimers[ITIMER_PATTERN_FINDER]->resume();
+	patternTimer.start();
+	sc = m_patternFinder->findPatterns(m_muonRoad,
+					   m_mdtHits_normal,
+					   trackPatterns);
+	if (!sc.isSuccess()) {
+	  ATH_MSG_WARNING("Pattern finder failed");
+	  continue;
+	}
+	if (m_use_timer) m_timingTimers[ITIMER_PATTERN_FINDER]->pause();
+	patternTimer.stop();
+
+	// Superpoint fit
+	if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->resume();
+	stationFitterTimer.start();
+	sc = m_stationFitter->findSuperPoints(p_roi,
+					      m_muonRoad,
+					      m_rpcFitResult,
+					      trackPatterns);
+	if (!sc.isSuccess()) {
+	  ATH_MSG_WARNING("Super point fitter failed");
+	  continue;
+	}
+	if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->pause();
+	stationFitterTimer.stop();
+
+	// Check if at least 1 SP
+	for (size_t i=0; i<std::extent<decltype(trackPatterns.back().superPoints), 0>::value; i++) {
+	  if ( std::abs(trackPatterns.back().superPoints[i].R) > ZERO_LIMIT && std::abs(trackPatterns.back().superPoints[i].Z) > ZERO_LIMIT ) { // if R and Z exist
+	    hasSP = true;
+	  }
+	}
+
+	// Track fitting
+	if (m_use_timer) m_timingTimers[ITIMER_TRACK_FITTER]->resume();
+	trackFitterTimer.start();
+	sc = m_trackFitter->findTracks(p_roi,
+				       m_rpcFitResult,
+				       trackPatterns);
+	if (!sc.isSuccess()) {
+	  ATH_MSG_WARNING("Track fitter failed");
+	  if(hasSP) {
+	    storeMuonSA(p_roi, *p_roids, m_muonRoad, m_mdtRegion, m_rpcHits, m_tgcHits,
+	    		m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits,
+	    		m_stgcHits, m_mmHits,
+	    		trackPatterns.back(), outputSAs);
+	    xAOD::L2CombinedMuon* muonCB = new xAOD::L2CombinedMuon();
+	    muonCB->makePrivateStore();
+	    muonCB->setStrategy(0);
+	    muonCB->setErrorFlag(-9);
+	    muonCB->setPt(idtrack->pt());
+	    muonCB->setEta(idtrack->eta());
+	    muonCB->setPhi(idtrack->phi());
+	    muonCB->setCharge(idtrack->charge());
+	    ElementLink<xAOD::L2StandAloneMuonContainer> muonSAEL(outputSAs, outputSAs.size()-1);
+	    muonCB->setMuSATrackLink(muonSAEL);
+	    ElementLink<xAOD::TrackParticleContainer> idtrkEL(idtracks, idtrack_idx);
+	    muonCB->setIdTrackLink(idtrkEL);
+	    outputCBs.push_back(muonCB);
+	  }
+	  continue;
+        }
+	if (m_use_timer) m_timingTimers[ITIMER_TRACK_FITTER]->pause();
+        trackFitterTimer.stop();
+
+      } else { // Endcap Inside-out
+	ATH_MSG_DEBUG("m_muonRoad.extFtfMiddleEta Endcap: " << m_muonRoad.extFtfMiddleEta);
+	ATH_MSG_DEBUG("Endcap algorithm of IOmode starts");
+
+	prepTimer.start();
+	// Data preparation
+	sc = m_dataPreparator->prepareData(p_roi,
+					   *p_roids,
+					   m_insideOut,
+					   m_tgcHits,
+					   m_muonRoad,
+					   m_mdtRegion,
+					   m_tgcFitResult,
+					   m_mdtHits_normal,
+					   m_mdtHits_overlap,
+					   m_cscHits,
+					   m_stgcHits,
+					   m_mmHits);
+	if (!sc.isSuccess()) {
+	  ATH_MSG_WARNING("Data preparation failed");
+	  continue;
+	} else{
+	  ATH_MSG_DEBUG("Data preparation success");
+	}
+	if (m_use_timer) m_timingTimers[ITIMER_DATA_PREPARATOR]->pause();
+	prepTimer.stop();
+
+	// Pattern finding
+	if (m_use_timer) m_timingTimers[ITIMER_PATTERN_FINDER]->resume();
+	patternTimer.start();
+	sc = m_patternFinder->findPatterns(m_muonRoad,
+					   m_mdtHits_normal,
+					   m_stgcHits,
+					   m_mmHits,
+					   trackPatterns);
+	if (!sc.isSuccess()) {
+	  ATH_MSG_WARNING("Pattern finder failed");
+	  continue;
+	}
+	if (m_use_timer) m_timingTimers[ITIMER_PATTERN_FINDER]->pause();
+	patternTimer.stop();
+
+	// Superpoint fit
+	if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->resume();
+	stationFitterTimer.start();
+	sc = m_stationFitter->findSuperPointsSimple(p_roi,
+						    m_muonRoad,
+						    m_tgcFitResult,
+						    trackPatterns);
+	/////csc SuperPoint
+	m_cscsegmaker->FindSuperPointCsc(m_cscHits,trackPatterns,m_tgcFitResult,m_muonRoad);
+	if (!sc.isSuccess()) {
+	  ATH_MSG_WARNING("Super point fitter failed");
+	  continue;
+	}
+	if (m_use_timer) m_timingTimers[ITIMER_STATION_FITTER]->pause();
+	stationFitterTimer.stop();
+
+	// Check if at least 1 SP
+	for (size_t i=0; i<std::extent<decltype(trackPatterns.back().superPoints), 0>::value; i++) {
+	  if ( std::abs(trackPatterns.back().superPoints[i].R) > ZERO_LIMIT && std::abs(trackPatterns.back().superPoints[i].Z) > ZERO_LIMIT ) { // if R and Z exist
+	    hasSP = true;
+	  }
+	}
+
+	// Track fittingh
+        if (m_use_timer) m_timingTimers[ITIMER_TRACK_FITTER]->resume();
+	trackFitterTimer.start();
+        sc = m_trackFitter->findTracks(p_roi,
+				       m_tgcFitResult,
+				       trackPatterns,
+				       m_muonRoad);
+        if (!sc.isSuccess()) {
+          ATH_MSG_WARNING("Track fitter failed");
+	  if(hasSP) {
+	    storeMuonSA(p_roi, *p_roids, m_muonRoad, m_mdtRegion, m_rpcHits, m_tgcHits,
+	    		m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits,
+	    		m_stgcHits, m_mmHits,
+	    		trackPatterns.back(), outputSAs);
+	    xAOD::L2CombinedMuon* muonCB = new xAOD::L2CombinedMuon();
+	    muonCB->makePrivateStore();
+	    muonCB->setStrategy(0);
+	    muonCB->setErrorFlag(-9);
+	    muonCB->setPt(idtrack->pt());
+	    muonCB->setEta(idtrack->eta());
+	    muonCB->setPhi(idtrack->phi());
+	    muonCB->setCharge(idtrack->charge());
+	    ElementLink<xAOD::L2StandAloneMuonContainer> muonSAEL(outputSAs, outputSAs.size()-1);
+	    muonCB->setMuSATrackLink(muonSAEL);
+	    ElementLink<xAOD::TrackParticleContainer> idtrkEL(idtracks, idtrack_idx);
+	    muonCB->setIdTrackLink(idtrkEL);
+	    outputCBs.push_back(muonCB);
+	  }
+	  continue;
+	}
+	if (m_use_timer) m_timingTimers[ITIMER_TRACK_FITTER]->pause();
+	trackFitterTimer.stop();
+
+      }
+
+      // fix if eta is strange
+      for (unsigned int i=0 ;i<trackPatterns.size(); i++) {
+	TrigL2MuonSA::TrackPattern track = trackPatterns[i];
+	const float ETA_LIMIT       = 2.8;
+	const float DELTA_ETA_LIMIT = 1.0;
+	float roiEta = (*p_roi).eta();
+	if (std::abs(track.pt) > ZERO_LIMIT
+	    && ( std::abs(track.etaMap) > ETA_LIMIT || std::abs(track.etaMap-roiEta) > DELTA_ETA_LIMIT ) ) {
+          trackPatterns[i].etaMap = roiEta;
+        }
+      }
+
+      // Update monitoring variables
+      sc = updateMonitor(p_roi, m_mdtHits_normal, trackPatterns );
+      if (sc != StatusCode::SUCCESS) {
+	ATH_MSG_WARNING("Failed to update monitoring variables");
+      }
+
+      // Update output trigger element
+      if(hasSP) {
+	storeMuonSA(p_roi, *p_roids, m_muonRoad, m_mdtRegion, m_rpcHits, m_tgcHits,
+		    m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits,
+		    m_stgcHits, m_mmHits,
+		    trackPatterns.back(), outputSAs);
+	xAOD::L2CombinedMuon* muonCB = new xAOD::L2CombinedMuon();
+	muonCB->makePrivateStore();
+	muonCB->setStrategy(0);
+	muonCB->setErrorFlag(-9);
+	muonCB->setPt(idtrack->pt());
+	muonCB->setEta(idtrack->eta());
+	muonCB->setPhi(idtrack->phi());
+	muonCB->setCharge(idtrack->charge());
+	ElementLink<xAOD::L2StandAloneMuonContainer> muonSAEL(outputSAs, outputSAs.size()-1);
+	muonCB->setMuSATrackLink(muonSAEL);
+	ElementLink<xAOD::TrackParticleContainer> idtrkEL(idtracks, idtrack_idx);
+	muonCB->setIdTrackLink(idtrkEL);
+	outputCBs.push_back(muonCB);
+      }
+
+    }
+
+    if(outputSAs.size()==0) {
+      ATH_MSG_DEBUG("outputSAs size = 0 -> push_back dummy");
+      m_muonRoad.Clear();
+      TrigL2MuonSA::MdtRegion mdtRegion;
+      m_rpcHits.clear();
+      m_tgcHits.clear();
+      m_rpcFitResult.Clear();
+      m_tgcFitResult.Clear();
+      m_mdtHits_normal.clear();
+      m_cscHits.clear();
+      m_stgcHits.clear();
+      m_mmHits.clear();
+      trackPatterns.clear();
+      TrigL2MuonSA::TrackPattern trackPattern;
+      storeMuonSA(p_roi, *p_roids, m_muonRoad, mdtRegion, m_rpcHits, m_tgcHits,
+      		  m_rpcFitResult, m_tgcFitResult, m_mdtHits_normal, m_cscHits,
+      		  m_stgcHits, m_mmHits,
+      		  trackPattern, outputSAs);
+      xAOD::L2CombinedMuon* muonCB = new xAOD::L2CombinedMuon();
+      muonCB->makePrivateStore();
+      muonCB->setStrategy(-9);
+      muonCB->setErrorFlag(-9);
+      muonCB->setPt(0);
+      muonCB->setEta(0);
+      muonCB->setPhi(0);
+      ElementLink<xAOD::L2StandAloneMuonContainer> muonSAEL(outputSAs, outputSAs.size()-1);
+      muonCB->setMuSATrackLink(muonSAEL);
+      outputCBs.push_back(muonCB);
+    }
+
+
+    ATH_MSG_DEBUG("outputSAs size: " << outputSAs.size());
+    ATH_MSG_DEBUG("idtracks size: " << idtracks.size());
+    for (auto outputSA : outputSAs){
+      ATH_MSG_DEBUG("outputSA pt/eta/phi: " << outputSA->pt() << "/" << outputSA->etaMS() << "/" << outputSA->phiMS());
+    }
+
+    ATH_MSG_DEBUG("outputCBs size: " << outputCBs.size());
+    for (auto outputCB : outputCBs){
+      ATH_MSG_DEBUG("outputCB pt/eta/phi: " << outputCB->pt() << "/" << outputCB->eta() << "/" << outputCB->phi());
+    }
+
+  }
+
+  if (m_use_timer) m_timingTimers[ITIMER_TOTAL_PROCESSING]->pause();
+
+  if (m_use_timer) {
+    for (unsigned int i_timer=0; i_timer<m_timingTimers.size(); i_timer++) {
+      m_timingTimers[i_timer]->stop();
+    }
+  }
+
+  ATH_MSG_DEBUG("StatusCode MuFastSteering::findMuonSignatureIO success");
+  return StatusCode::SUCCESS;
+}
+
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
+
 bool MuFastSteering::updateOutputObjects(const LVL1::RecMuonRoI*                        roi,
                                          const TrigRoiDescriptor*                       roids,
                                          const TrigL2MuonSA::MuonRoad&                  muonRoad,
@@ -959,7 +1382,7 @@ bool MuFastSteering::updateOutputObjects(const LVL1::RecMuonRoI*
   
   if( trackPatterns.size() > 0 ) {
 
-    const TrigL2MuonSA::TrackPattern& pattern = trackPatterns[0];
+    const TrigL2MuonSA::TrackPattern& pattern = trackPatterns.back();
 
     // Update output trigger element
     storeMuonSA(roi, roids, muonRoad, mdtRegion, rpcHits, tgcHits,
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.h
index ba95ecd9ef5b522399b7d5ad21a2b20ce48a84b2..9d1dcbf632724367128dd4bf174d5eb46003d0e8 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastSteering.h
@@ -24,6 +24,7 @@
 #include "GaudiKernel/IIncidentListener.h"
 #include "CscSegmentMaker.h"
 #include "CscRegUtils.h"
+#include "FtfRoadDefiner.h"
 
 //adding a part of DataHandle for AthenaMT
 #include "AthenaBaseComps/AthReentrantAlgorithm.h"
@@ -34,6 +35,7 @@
 #include "xAODTrigMuon/L2StandAloneMuonContainer.h"
 #include "xAODTrigger/TrigCompositeAuxContainer.h"
 #include "xAODTrigger/TrigCompositeContainer.h"
+#include "xAODTracking/TrackParticleContainer.h"
 #include "AthenaMonitoringKernel/GenericMonitoringTool.h"
 
 class IRegSelSvc;
@@ -84,6 +86,13 @@ class MuFastSteering : public HLT::FexAlgo,
 			       TrigRoiDescriptorCollection&	 		outputMS,
 			       DataVector<xAOD::TrigComposite>&			outputComposite );
 
+  /** findMuonSignatureIO(), includes reconstract algorithms for inside-out mode **/
+  StatusCode findMuonSignatureIO(const xAOD::TrackParticleContainer&            idtracks,
+				 const std::vector<const TrigRoiDescriptor*>    roids,
+				 const std::vector<const LVL1::RecMuonRoI*>     muonRoIs,
+				 DataVector<xAOD::L2CombinedMuon>&              outputCBs,
+				 DataVector<xAOD::L2StandAloneMuon>&            outputSAs );
+
   int L2MuonAlgoMap(const std::string& name);
 
   // handler for "UpdateAfterFork" actions
@@ -168,6 +177,8 @@ class MuFastSteering : public HLT::FexAlgo,
 	this, "TrackFitter", "TrigL2MuonSA::MuFastTrackFitter", "track fitter" };
   ToolHandle<TrigL2MuonSA::MuFastTrackExtrapolator>  m_trackExtrapolator {
 	this, "TrackExtrapolator", "TrigL2MuonSA::MuFastTrackExtrapolator", "track extrapolator" };
+  ToolHandle<TrigL2MuonSA::FtfRoadDefiner>           m_ftfRoadDefiner {
+        this, "FtfRoadDefiner", "TrigL2MuonSA::FtfRoadDefiner", "ftf road definer" };
 
   /** Handle to MuonBackExtrapolator tool */
   ToolHandle<ITrigMuonBackExtrapolator> m_backExtrapolatorTool {
@@ -231,6 +242,8 @@ class MuFastSteering : public HLT::FexAlgo,
 
   Gaudi::Property< double > m_winPt { this, "WinPt", 4.0 };
 
+  Gaudi::Property< bool > m_insideOut { this, "InsideOutMode", false, "" };
+  Gaudi::Property< float > m_ftfminPt { this, "FTFminPt", 3500, "pT [MeV] threshold to FTF tracks for L2Muon Inside-out mode" };
   Gaudi::Property< bool > m_topoRoad { this, "topoRoad", false, "create road in barrel not to highly overlap surrounding L1 RoIs" };
   Gaudi::Property< float > m_dPhisurrRoI { this, "dPhisurrRoI", 99, "phi range to find surrounding L1 RoIs" };
   Gaudi::Property< float > m_dEtasurrRoI { this, "dEtasurrRoI", 99, "eta range to find surrounding L1 RoIs" };
@@ -257,6 +270,10 @@ class MuFastSteering : public HLT::FexAlgo,
   SG::ReadHandleKey<DataVector<LVL1::RecMuonRoI>> m_recRoiCollectionKey{
 	this, "RecMuonRoI", "HLT_RecMURoIs", "Name of the input data on LVL1::RecMuonRoI produced by L1Decoder"};
 
+  //ReadHandle FTF Tracks
+  SG::ReadHandleKey<xAOD::TrackParticleContainer> m_FTFtrackKey{
+	this, "TrackParticlesContainerName", "HLT_xAODTracks_Muon", "Name of the input data on xAOD::TrackParticleContainer produced by FTF for Inside-Out mode"};
+
   //WriteHandle <xAOD::L2StandAloneMuonContainer>
   SG::WriteHandleKey<xAOD::L2StandAloneMuonContainer> m_muFastContainerKey{
 	this, "MuonL2SAInfo", "MuonL2SAInfo", "Name of the output data on xAOD::L2StandAloneMuonContainer"};
@@ -273,6 +290,10 @@ class MuFastSteering : public HLT::FexAlgo,
   SG::WriteHandleKey<TrigRoiDescriptorCollection> m_muMsContainerKey{
 	this, "forMS", "forMS", "Name of the output data for MS"};
 
+  //WriteHandle <xAOD::L2CombinedMuonContainer> for Inside-out Mode
+  SG::WriteHandleKey<xAOD::L2CombinedMuonContainer> m_outputCBmuonCollKey{
+	this, "L2IOCB", "MuonL2CBInfo", "output CB Muon container name"};
+
   // Monitor system
   ToolHandle< GenericMonitoringTool > m_monTool { this, "MonTool", "", "Monitoring tool" };
 };
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastTrackFitter.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastTrackFitter.cxx
index ae2002805f87f7ce0a6561a4e22830c8f06be6aa..402cd8004bd8279bd4cdced23a0291fb9cd389fd 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastTrackFitter.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuFastTrackFitter.cxx
@@ -159,6 +159,10 @@ StatusCode TrigL2MuonSA::MuFastTrackFitter::findTracks(const LVL1::RecMuonRoI*
 
      ATH_CHECK( m_alphaBetaEstimate->setAlphaBeta(p_roi, tgcFitResult, itTrack, muonRoad) );
 
+     if ( itTrack.etaBin < -1 ) {
+       itTrack.etaBin = (int)((fabs(muonRoad.extFtfMiddleEta)-1.)/0.05); // eta binning is the same as AlphaBetaEstimate
+     }
+
      ATH_CHECK( m_ptFromAlphaBeta->setPt(itTrack,tgcFitResult) );
      
    }
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuonRoad.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuonRoad.h
index fe267bb21abb08bbb214c8c0b308807bde56e00c..f10a7aa577db3b3bbe08751952e9359ac1232847 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuonRoad.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/MuonRoad.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef  TRIGL2MUONSA_MUONROAD_H
@@ -33,6 +33,8 @@ namespace TrigL2MuonSA {
       phiRoI     = 0;
       MDT_sector_trigger = 0;
       MDT_sector_overlap = 0;
+      extFtfMiddleEta = 0;
+      extFtfMiddlePhi = 0;
       for(int i=0; i<N_STATION; i++) {
 	scales[i] = 1;
 	for(int j=0; j<N_LAYER; j++) {	  
@@ -41,6 +43,12 @@ namespace TrigL2MuonSA {
 	for(int j=0; j<N_SECTOR; j++) {	  
 	  aw[i][j]   = 0;
 	  bw[i][j]   = 0;
+	  aw_ftf[i][j]  = 0;
+	  bw_ftf[i][j]  = 0;
+	  phi_ftf[i][j] = 0;
+	  eta_ftf[i][j] = 0;
+	  r_ftf[i][j]   = 0;
+	  z_ftf[i][j]   = 0;
 	  phi[i][j]  = 0;
 	}
       }
@@ -78,6 +86,17 @@ namespace TrigL2MuonSA {
     int    MDT_sector_trigger;
     int    MDT_sector_overlap;
 
+    // FTF varibles
+    double extFtfMiddleEta;
+    double extFtfMiddlePhi;
+    double aw_ftf[N_STATION][N_SECTOR];
+    double bw_ftf[N_STATION][N_SECTOR];
+    double phi_ftf[N_STATION][N_SECTOR];
+    double eta_ftf[N_STATION][N_SECTOR];
+    double r_ftf[N_STATION][N_SECTOR];
+    double z_ftf[N_STATION][N_SECTOR];
+    int ext_ftf_flag[N_STATION][N_SECTOR];
+
     std::vector<Identifier> stationList;
 
   };
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.cxx
index 3228d2083fa20ddff2c05f65f8071ffd893e5abe..16cc5e662b05b8b763a8eb7b5492e62af1c7ac12 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.cxx
@@ -19,8 +19,8 @@ TrigL2MuonSA::RpcRoadDefiner::RpcRoadDefiner(const std::string& type,
 {
 }
 
-// -------------------------------------------------------------------------------- 
-// --------------------------------------------------------------------------------                  
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
 
 StatusCode TrigL2MuonSA::RpcRoadDefiner::initialize()
 {
@@ -32,6 +32,7 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::initialize()
 // --------------------------------------------------------------------------------
 
 StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*      p_roi,
+						    const bool                   insideOut,
 						    TrigL2MuonSA::MuonRoad&      muonRoad,
 						    TrigL2MuonSA::RpcHits&       /*rpcHits*/,
 						    ToolHandle<RpcPatFinder>*    rpcPatFinder,
@@ -43,11 +44,11 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
 {
 
   const double ZERO_LIMIT = 1e-5;
-  
+
   const int N_LAYER = 5; // 0: inner, 1: middle, 2: outer 4: BME 5: BMG
   const int N_SECTOR = 2; // 0: normal, 1:overlap
 
-  if (m_use_rpc) {
+  if (m_use_rpc && !insideOut) {
     double aw[3]={0.,0.,0.};
     double bw[3]={0.,0.,0.};
     unsigned int rpc_pattern;
@@ -66,7 +67,7 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
     } else {
       rpcFitResult.isSuccess = false;
     }
-    
+
     double phi_middle;
     double phi_outer;
     unsigned int phi_pattern;
@@ -77,35 +78,54 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
     } else {
       rpcFitResult.phi = p_roi->phi();
     }
-  } 
+  } else {
+    ATH_MSG_DEBUG("Skip rpcPatFinder");
+  }
 
   // RPC data is not available -> use RoI 
-  
+
   muonRoad.isEndcap   = false;
-  muonRoad.phiMiddle  = rpcFitResult.phi;
+  if(!insideOut) {
+    muonRoad.phiMiddle  = rpcFitResult.phi;
+  } else {
+    muonRoad.phiMiddle  = muonRoad.extFtfMiddlePhi;
+    rpcFitResult.phi = muonRoad.extFtfMiddlePhi;
+    rpcFitResult.phi_middle = muonRoad.extFtfMiddlePhi;
+    rpcFitResult.phi_outer = muonRoad.extFtfMiddlePhi;
+  }
   muonRoad.phiRoI     = p_roi->phi();
   muonRoad.side       = (p_roi->phi()<0.)? 0 : 1;
   muonRoad.LargeSmall = ((p_roi->sectorID() + 1)/2 )%2;
-  
+
   const int PhysicsSector = ((p_roi->sectorID() + 1)/4 )%8 + 1;
-  
+
   int special = 0;
   if (muonRoad.LargeSmall == 0 && (PhysicsSector == 6 || PhysicsSector == 8 ))
     special = 1;
   if (muonRoad.LargeSmall == 1 && (PhysicsSector == 6 || PhysicsSector == 7 ))
     special = 1;
   muonRoad.Special = special;
-  
+
   for (int i_station=0; i_station<6; i_station++) {
     for (int i_layer=0; i_layer<8; i_layer++) {
       if(!rpcFitResult.isSuccess) {
-	if (i_station==0)      muonRoad.rWidth[i_station][i_layer] = 500;//for inner
-	else if (i_station==1) muonRoad.rWidth[i_station][i_layer] = 650;//for middle
-	else if (i_station==2) muonRoad.rWidth[i_station][i_layer] = 800;//for outer
-	else if (i_station==3) muonRoad.rWidth[i_station][i_layer] = 500;//EndcapInner
-	else if (i_station==4) muonRoad.rWidth[9][i_layer] = 650;//BME
-	else if (i_station==5) muonRoad.rWidth[10][i_layer] = 650;//BMG
-	else muonRoad.rWidth[i_station][i_layer] = m_rWidth_RPC_Failed;
+	if (!insideOut){
+	  if (i_station==0)      muonRoad.rWidth[i_station][i_layer] = 500;//for inner
+	  else if (i_station==1) muonRoad.rWidth[i_station][i_layer] = 650;//for middle
+	  else if (i_station==2) muonRoad.rWidth[i_station][i_layer] = 800;//for outer
+	  else if (i_station==3) muonRoad.rWidth[i_station][i_layer] = 500;//EndcapInner
+	  else if (i_station==4) muonRoad.rWidth[9][i_layer] = 650;//BME
+	  else if (i_station==5) muonRoad.rWidth[10][i_layer] = 650;//BMG
+	  else muonRoad.rWidth[i_station][i_layer] = m_rWidth_RPC_Failed;
+	} else {
+	  if (i_station==0)      muonRoad.rWidth[i_station][i_layer] = 400;//for inner
+	  else if (i_station==1) muonRoad.rWidth[i_station][i_layer] = 200;//for middle
+	  else if (i_station==2) muonRoad.rWidth[i_station][i_layer] = 400;//for outer
+	  else if (i_station==3) muonRoad.rWidth[i_station][i_layer] = 400;//EndcapInner
+	  else if (i_station==4) muonRoad.rWidth[9][i_layer] = m_rWidth_RPC_Failed;//BME
+	  else if (i_station==5) muonRoad.rWidth[10][i_layer] = m_rWidth_RPC_Failed;//BMG
+	  else muonRoad.rWidth[i_station][i_layer] = m_rWidth_RPC_Failed;
+	}
       }
       else {
 	if (i_station==0)      muonRoad.rWidth[i_station][i_layer] = 400;//for inner
@@ -118,15 +138,15 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
       }
     }
   }
-  
+
   int sector_trigger = 99;
   int sector_overlap = 99;
   std::vector<Identifier> stationList;
   std::vector<IdentifierHash> mdtHashList;
-  
+
   // get sector_trigger and sector_overlap by using the region selector
   IdContext context = m_idHelperSvc->mdtIdHelper().module_context();
-  
+
   double etaMin =  p_roi->eta()-.02;
   double etaMax =  p_roi->eta()+.02;
   double phiMin = muonRoad.phiMiddle-.01;
@@ -142,21 +162,21 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
   else m_regionSelector->DetHashIDList(MDT, mdtHashList);
 
   if(roi) delete roi;
-  
+
   for( const IdentifierHash& hash : mdtHashList){
-    
+
     Identifier id;
     const int convert = m_idHelperSvc->mdtIdHelper().get_id(hash, id, &context);
 
     if(convert!=0) ATH_MSG_ERROR("problem converting hash list to id");
-    
+
     muonRoad.stationList.push_back(id);
     const int stationPhi = m_idHelperSvc->mdtIdHelper().stationPhi(id);
     std::string name = m_idHelperSvc->mdtIdHelper().stationNameString(m_idHelperSvc->mdtIdHelper().stationName(id));
-    
+
     if ( name[1]=='M' && name[2]=='E' ) continue;//exclude BME
     if ( name[1]=='M' && name[2]=='G' ) continue;//exclude BMG
-    
+
     int LargeSmall = 0;
     if(name[2]=='S' || name[2]=='F' || name[2]=='G' ) LargeSmall = 1;
     const int sector = (stationPhi-1)*2 + LargeSmall;
@@ -165,16 +185,16 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
     else if(sector_trigger != sector)
       sector_overlap = sector;
   }
-  
+
   const int MDT_tr = (PhysicsSector - 1)*2 + muonRoad.LargeSmall;
   if (MDT_tr == sector_overlap) {
     sector_overlap = sector_trigger;
     sector_trigger = MDT_tr;
   }
-  
+
   muonRoad.MDT_sector_trigger = sector_trigger;
   muonRoad.MDT_sector_overlap = sector_overlap;
-  
+
   if (rpcFitResult.isSuccess) {
     for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
       muonRoad.aw[0][i_sector] = rpcFitResult.slope_inner;
@@ -190,7 +210,7 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
       muonRoad.aw[10][i_sector] = rpcFitResult.slope_middle;//BMG
       muonRoad.bw[10][i_sector] = rpcFitResult.offset_middle;
     }
-   
+
   } else {
     const double roiEtaLow = (roiEtaMinLow + roiEtaMaxLow) * 0.5;
     const double roiEtaHigh = (roiEtaMinHigh + roiEtaMaxHigh) * 0.5;
@@ -198,7 +218,7 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
     const double thetaHigh  = atan(exp(-fabs(roiEtaHigh)))*2.;
     const double awLow     = (fabs(roiEtaLow) > ZERO_LIMIT)? tan(thetaLow)*(fabs(roiEtaLow)/roiEtaLow): 0.;
     const double awHigh     = (fabs(roiEtaHigh) > ZERO_LIMIT)? tan(thetaHigh)*(fabs(roiEtaHigh)/roiEtaHigh): 0.;
-    
+
     for (int i_station=0; i_station<N_LAYER; i_station++) {
       for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
 	muonRoad.aw[i_station][i_sector] = awLow;
@@ -211,8 +231,27 @@ StatusCode TrigL2MuonSA::RpcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
     }
   }
 
+  if (insideOut) {
+    for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
+      ATH_MSG_DEBUG("Use aw_ftf and bw_ftf as aw and bw");
+      muonRoad.aw[0][i_sector]  = muonRoad.aw_ftf[0][0];
+      muonRoad.bw[0][i_sector]  = muonRoad.bw_ftf[0][0];
+      muonRoad.aw[1][i_sector]  = muonRoad.aw_ftf[1][0];
+      muonRoad.bw[1][i_sector]  = muonRoad.bw_ftf[1][0];
+      muonRoad.aw[2][i_sector]  = muonRoad.aw_ftf[2][0];
+      muonRoad.bw[2][i_sector]  = muonRoad.bw_ftf[2][0];
+      muonRoad.aw[3][i_sector]  = muonRoad.aw_ftf[3][0]; // Endcap Inner
+      muonRoad.bw[3][i_sector]  = muonRoad.bw_ftf[3][0];
+      muonRoad.aw[9][i_sector]  = muonRoad.aw_ftf[9][0];//BME
+      muonRoad.bw[9][i_sector]  = muonRoad.bw_ftf[9][0];
+      muonRoad.aw[10][i_sector] = muonRoad.aw_ftf[10][0];//BMG
+      muonRoad.bw[10][i_sector] = muonRoad.bw_ftf[10][0];
+    }
+  }
+  ATH_MSG_DEBUG("muonRoad.phiMiddle: " << muonRoad.phiMiddle);
+
   return StatusCode::SUCCESS;
 }
 
-// --------------------------------------------------------------------------------  
-// --------------------------------------------------------------------------------                  
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.h
index 3c603fce18c62ae79e71dc9b78b2b4c0792b7ad1..2d048de141ae9740fe5612126d82d20019d28797 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/RpcRoadDefiner.h
@@ -39,6 +39,7 @@ class RpcRoadDefiner: public AthAlgTool
   
  public:
   StatusCode defineRoad(const LVL1::RecMuonRoI*      p_roi,
+			const bool                   insideOut,
 			TrigL2MuonSA::MuonRoad&      muonRoad,
 			TrigL2MuonSA::RpcHits&       rpcHits,
 			ToolHandle<RpcPatFinder>*    rpcPatFinder,
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.cxx
index 5a5214a76ef95172d7f892b78b779b16834cb414..462859b0adc50bc55368baec8b99c5b630ba1fff 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.cxx
@@ -44,6 +44,7 @@ StatusCode TrigL2MuonSA::TgcRoadDefiner::initialize()
 // --------------------------------------------------------------------------------
 
 StatusCode TrigL2MuonSA::TgcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*      p_roi,
+                                                    const bool                   insideOut,
                                                     const TrigL2MuonSA::TgcHits& tgcHits,
                                                     TrigL2MuonSA::MuonRoad&      muonRoad,
                                                     TrigL2MuonSA::TgcFitResult&  tgcFitResult)
@@ -109,6 +110,8 @@ StatusCode TrigL2MuonSA::TgcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
 		  << "/" << tgcFitResult.tgcMid1[2] << "/" << tgcFitResult.tgcMid1[3]);
     ATH_MSG_DEBUG("tgcFitResult.tgcMid2[0/1/2/3]=" << tgcFitResult.tgcMid2[0] << "/" << tgcFitResult.tgcMid2[1]
 		  << "/" << tgcFitResult.tgcMid2[2] << "/" << tgcFitResult.tgcMid2[3]);
+  } else {
+    ATH_MSG_DEBUG("Skip TGC Fit due to zero-tgcHits");
   }
    
   if (tgcHits.size()>0 && !isMiddleFailure){
@@ -256,6 +259,7 @@ StatusCode TrigL2MuonSA::TgcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
     
   } else {
     // If no TGC hit are available, estimate the road from RoI
+    ATH_MSG_DEBUG("Because no TGC hits are available, estimate the road from RoI");
 
     roiEta = p_roi->eta();
     theta  = atan(exp(-fabs(roiEta)))*2.;
@@ -367,7 +371,30 @@ StatusCode TrigL2MuonSA::TgcRoadDefiner::defineRoad(const LVL1::RecMuonRoI*
   
   muonRoad.MDT_sector_trigger = sector_trigger;
   muonRoad.MDT_sector_overlap = sector_overlap;
-  
+
+  if (insideOut) {
+    muonRoad.side      = (muonRoad.extFtfMiddleEta<0.)? 0 : 1;
+    muonRoad.phiMiddle =  muonRoad.extFtfMiddlePhi;
+    muonRoad.phiRoI    = p_roi->phi();
+    for (int i_sector=0; i_sector<N_SECTOR; i_sector++) {
+      ATH_MSG_DEBUG("Use aw_ftf and bw_ftf as aw and bw");
+      muonRoad.aw[endcap_inner][i_sector]  = muonRoad.aw_ftf[3][0];
+      muonRoad.bw[endcap_inner][i_sector]  = muonRoad.bw_ftf[3][0];
+      muonRoad.aw[endcap_middle][i_sector] = muonRoad.aw_ftf[4][0];
+      muonRoad.bw[endcap_middle][i_sector] = muonRoad.bw_ftf[4][0];
+      muonRoad.aw[endcap_outer][i_sector]  = muonRoad.aw_ftf[5][0];
+      muonRoad.bw[endcap_outer][i_sector]  = muonRoad.bw_ftf[5][0];
+      muonRoad.aw[endcap_extra][i_sector]  = muonRoad.aw_ftf[6][0];
+      muonRoad.bw[endcap_extra][i_sector]  = muonRoad.bw_ftf[6][0];
+      muonRoad.aw[csc][i_sector]           = muonRoad.aw_ftf[7][0];
+      muonRoad.bw[csc][i_sector]           = muonRoad.bw_ftf[7][0];
+      muonRoad.aw[bee][i_sector]           = muonRoad.aw_ftf[8][0];
+      muonRoad.bw[bee][i_sector]           = muonRoad.bw_ftf[8][0];
+      muonRoad.aw[barrel_inner][i_sector]  = muonRoad.aw_ftf[0][0];
+      muonRoad.bw[barrel_inner][i_sector]  = muonRoad.bw_ftf[0][0];
+    }
+  }
+
   //
   return StatusCode::SUCCESS;
 }
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.h b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.h
index 8fd29389e19853009373d030187c333cc8d944a1..0ee78135ca39ca997e13dcd93396c6c19cf6223a 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.h
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/TgcRoadDefiner.h
@@ -37,6 +37,7 @@ class TgcRoadDefiner: public AthAlgTool
   virtual StatusCode initialize() override;
 
   StatusCode defineRoad(const LVL1::RecMuonRoI*      p_roi,
+                        const bool                   insideOut,
                         const TrigL2MuonSA::TgcHits& tgcHits,
                         TrigL2MuonSA::MuonRoad&      muonRoad,
                         TrigL2MuonSA::TgcFitResult&  tgcFitResult);
diff --git a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/components/TrigL2MuonSA_entries.cxx b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/components/TrigL2MuonSA_entries.cxx
index 10c3af10287b52745eb632654e78fe502bd9675d..38c7cb7e3d0043a0189b6db42142a47c7594214c 100644
--- a/Trigger/TrigAlgorithms/TrigL2MuonSA/src/components/TrigL2MuonSA_entries.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2MuonSA/src/components/TrigL2MuonSA_entries.cxx
@@ -31,6 +31,7 @@
 #include "../MmDataPreparator.h"
 #include "../NswPatternFinder.h"
 #include "../NswStationFitter.h"
+#include "../FtfRoadDefiner.h"
 
 using namespace TrigL2MuonSA;
 
@@ -63,6 +64,7 @@ DECLARE_COMPONENT( StgcDataPreparator )
 DECLARE_COMPONENT( MmDataPreparator )
 DECLARE_COMPONENT( NswPatternFinder )
 DECLARE_COMPONENT( NswStationFitter )
+DECLARE_COMPONENT( FtfRoadDefiner )
 
 DECLARE_COMPONENT( PtBarrelLUTSvc )
 DECLARE_COMPONENT( PtEndcapLUTSvc )
diff --git a/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.cxx b/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.cxx
index 62385efd4f6d8bf42820ccb70b32f0690be7fa2e..4cfa79340b39e4f44a3cb36b24f565ce52276122 100644
--- a/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.cxx
+++ b/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.cxx
@@ -1,12 +1,13 @@
 /*
   Filter chains for muon trigger algorithms. Designed to pass if at least one active chain is not in the list to be filtered.
   
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonChainFilterAlg.h"
 #include "TrigCompositeUtils/HLTIdentifier.h"
 #include "xAODTrigMuon/L2CombinedMuonAuxContainer.h"
+#include "xAODTrigMuon/L2StandAloneMuonAuxContainer.h"
 
 MuonChainFilterAlg::MuonChainFilterAlg(const std::string& name, ISvcLocator* pSvcLocator )
 :AthAlgorithm(name, pSvcLocator)
@@ -19,6 +20,12 @@ StatusCode MuonChainFilterAlg::initialize(){
 
   ATH_CHECK(m_inputDecisionKeys.initialize());
   ATH_CHECK(m_muCombKey.initialize(m_writeL2muComb));
+  ATH_CHECK(m_muFastKey.initialize(m_writeL2muFast));
+  if ( m_filterChains.size()!=0 ) {
+    for (size_t i=0; i<m_filterChains.size(); ++i) {
+      ATH_MSG_DEBUG("IO TEST: " << i << " filter chains >> " << m_filterChains[i]);
+    }
+  }
   return StatusCode::SUCCESS;
 }
 
@@ -80,6 +87,11 @@ StatusCode MuonChainFilterAlg::execute()
     SG::WriteHandle wh_muons(m_muCombKey);
     ATH_CHECK( wh_muons.record (std::make_unique<xAOD::L2CombinedMuonContainer>(), std::make_unique<xAOD::L2CombinedMuonAuxContainer>()) );
   }
+  //write out empty muFast container since edm creator expects the container to always be present in the view
+  if(!pass && m_writeL2muFast){
+    SG::WriteHandle wh_muons(m_muFastKey);
+    ATH_CHECK( wh_muons.record (std::make_unique<xAOD::L2StandAloneMuonContainer>(), std::make_unique<xAOD::L2StandAloneMuonAuxContainer>()) );
+  }
   setFilterPassed(pass);
 
   return StatusCode::SUCCESS;
diff --git a/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.h b/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.h
index 63aaa7db4a08fae356c6b12ab19161feb1e6e44b..40bf4c4370386d52c26a01f6e7aa4580cf3fcf62 100644
--- a/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.h
+++ b/Trigger/TrigAlgorithms/TrigMuonEF/src/MuonChainFilterAlg.h
@@ -1,7 +1,7 @@
 /*
   Filter to deselect chains for muon trigger algorithms
   
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGMUONEF_MUONCHAINFILTERALG_H
@@ -11,6 +11,7 @@
 #include "StoreGate/ReadHandleKeyArray.h"
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
 #include "xAODTrigMuon/L2CombinedMuonContainer.h"
+#include "xAODTrigMuon/L2StandAloneMuonContainer.h"
 
 class MuonChainFilterAlg : public AthAlgorithm
 {
@@ -32,10 +33,14 @@ class MuonChainFilterAlg : public AthAlgorithm
   private :
 
     Gaudi::Property< std::vector<std::string> > m_filterChains {this, "ChainsToFilter", { }, "Vector of chains to filter out" };
-    Gaudi::Property< bool > m_writeL2muComb {this, "WriteMuComb", true, "Flag to record muComb muons" };
+    Gaudi::Property< bool > m_writeL2muComb {this, "WriteMuComb", false, "Flag to record muComb muons" };
+
     SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer>  m_inputDecisionKeys{ this, "InputDecisions", {}, "Inputs to the filter" };
     SG::WriteHandleKey<xAOD::L2CombinedMuonContainer> m_muCombKey {this, "L2MuCombContainer", "MuonL2CBInfo", "Output container for muComb"};
 
+    Gaudi::Property< bool > m_writeL2muFast {this, "WriteMuFast", false, "Flag to record muFast muons" };
+    SG::WriteHandleKey<xAOD::L2StandAloneMuonContainer> m_muFastKey {this, "L2MuFastContainer", "MuonL2SAInfo", "Output container for muFast"};
+
 };
 
 #endif
diff --git a/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py b/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py
index b9b828cecc8e399fcda815ea6f84cc13d2aa9a3f..d7a3a2c084f74cda6854009c0a357048307c51b2 100755
--- a/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py
+++ b/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py
@@ -402,6 +402,36 @@ def TrigmuCombHypoToolwORFromDict( chainDict ):
     return tool
 
 
+# muComb Hypo for L2 inside-out
+def Trigl2IOHypoToolwORFromDict( chainDict ):
+
+    thresholds = getThresholdsFromDict( chainDict )
+
+    config = TrigmuCombHypoConfig()
+
+    tight = False # can be probably decoded from some of the proprties of the chain, expert work
+
+    acceptAll = False
+
+    tool=config.ConfigurationHypoTool( chainDict['chainName'], thresholds, tight, acceptAll )
+
+    # Overlap Removal
+    tool.ApplyOR = True
+    tool.RequireDR       = True
+    tool.RequireMufastDR = False
+    tool.RequireMass     = True
+    tool.RequireSameSign = True
+    tool.EtaBins         = [0, 0.9, 1.1, 1.9, 2.1, 9.9]
+    tool.DRThres         = [0.002, 0.001, 0.002, 0.002, 0.002]
+    tool.MufastDRThres   = [0]
+    tool.MassThres       = [0.004, 0.002, 0.006, 0.006, 0.006]
+
+    # addMonitoring( tool, TrigL2MuonOverlapRemoverMonitoringMucomb, "TrigmuCombHypoTool", chainDict['chainName'] )
+
+    return tool
+
+
+
 class TrigmuCombHypoConfig(object):
 
     log = logging.getLogger('TrigmuCombHypoConfig')
diff --git a/Trigger/TrigHypothesis/TrigMuonHypoMT/src/TrigmuCombHypoAlg.cxx b/Trigger/TrigHypothesis/TrigMuonHypoMT/src/TrigmuCombHypoAlg.cxx
index df344f096ba633e103e1b8de71cc2526cfe262d0..e513ce36b297ea52a9c5bc7431efb860f0e702cc 100644
--- a/Trigger/TrigHypothesis/TrigMuonHypoMT/src/TrigmuCombHypoAlg.cxx
+++ b/Trigger/TrigHypothesis/TrigMuonHypoMT/src/TrigmuCombHypoAlg.cxx
@@ -65,12 +65,12 @@ StatusCode TrigmuCombHypoAlg::execute(const EventContext& context) const
     ATH_CHECK( muCombHandle.isValid() );
     ATH_MSG_DEBUG( "Muinfo handle size: " << muCombHandle->size() << "...");
 
-    // make a link to the first entry of the container, if there is one
-    if ( muCombHandle->size() ) {
-      auto muCombEL = ViewHelper::makeLink( *viewEL, muCombHandle, 0 );
+    // loop over muCombs (more than one muon can be found by L2 inside-out algos)
+    for(uint i=0; i<muCombHandle->size(); i++){
+      auto muCombEL = ViewHelper::makeLink( *viewEL, muCombHandle, i );
       ATH_CHECK( muCombEL.isValid() );
       const xAOD::L2CombinedMuon* muComb = *muCombEL;
-    
+
       // create new decisions
       auto newd = newDecisionIn( decisions );
 
diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
index 89be0d093aa1a0e0391296e73f1c21a3c441bc62..7f6e353af4fc61601840c1265c0b84e3ac938383 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
@@ -79,6 +79,9 @@ TrigSignatureMoniMT                                 INFO -- #234102568 Features
 TrigSignatureMoniMT                                 INFO HLT_2mu14_L12MU10 #2619091790
 TrigSignatureMoniMT                                 INFO -- #2619091790 Events         3          3          0          0          0          0          2          1          1          1          -          -          -          -          -          1
 TrigSignatureMoniMT                                 INFO -- #2619091790 Features                             0          0          0          0          8          4          4          4          -          -          -          -          -
+TrigSignatureMoniMT                                 INFO HLT_2mu14_l2io_L12MU10 #945295390
+TrigSignatureMoniMT                                 INFO -- #945295390 Events          3          3          0          0          0          0          2          2          1          1          -          -          -          -          -          1
+TrigSignatureMoniMT                                 INFO -- #945295390 Features                              0          0          0          0          8          14         4          4          -          -          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_2mu15_L12MU10 #557204938
 TrigSignatureMoniMT                                 INFO -- #557204938 Events          3          3          0          0          0          0          2          1          1          1          -          -          -          -          -          1
 TrigSignatureMoniMT                                 INFO -- #557204938 Features                              0          0          0          0          8          4          4          4          -          -          -          -          -
@@ -109,6 +112,9 @@ TrigSignatureMoniMT                                 INFO -- #3304584056 Features
 TrigSignatureMoniMT                                 INFO HLT_2mu6_L12MU6 #1747073535
 TrigSignatureMoniMT                                 INFO -- #1747073535 Events         4          4          0          0          0          0          3          2          2          2          -          -          -          -          -          2
 TrigSignatureMoniMT                                 INFO -- #1747073535 Features                             0          0          0          0          12         8          8          8          -          -          -          -          -
+TrigSignatureMoniMT                                 INFO HLT_2mu6_l2io_L12MU6 #2996403520
+TrigSignatureMoniMT                                 INFO -- #2996403520 Events         4          4          0          0          0          0          3          3          2          2          -          -          -          -          -          2
+TrigSignatureMoniMT                                 INFO -- #2996403520 Features                             0          0          0          0          12         26         8          8          -          -          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_2mu6_muonqual_L12MU6 #2398136098
 TrigSignatureMoniMT                                 INFO -- #2398136098 Events         4          4          0          0          0          0          3          2          2          2          -          -          -          -          -          2
 TrigSignatureMoniMT                                 INFO -- #2398136098 Features                             0          0          0          0          12         8          8          8          -          -          -          -          -
@@ -646,6 +652,9 @@ TrigSignatureMoniMT                                 INFO -- #86648125 Features
 TrigSignatureMoniMT                                 INFO HLT_mu35_ivarmedium_L1MU20 #597064890
 TrigSignatureMoniMT                                 INFO -- #597064890 Events          8          8          0          0          0          0          8          5          3          2          1          -          -          -          -          1
 TrigSignatureMoniMT                                 INFO -- #597064890 Features                              0          0          0          0          10         6          4          2          1          -          -          -          -
+TrigSignatureMoniMT                                 INFO HLT_mu4_l2io_L1MU4 #1048276860
+TrigSignatureMoniMT                                 INFO -- #1048276860 Events         12         12         0          0          0          0          11         11         11         11         -          -          -          -          -          11
+TrigSignatureMoniMT                                 INFO -- #1048276860 Features                             0          0          0          0          14         46         15         15         -          -          -          -          -
 TrigSignatureMoniMT                                 INFO HLT_mu50_L1MU20 #3657158931
 TrigSignatureMoniMT                                 INFO -- #3657158931 Events         8          8          0          0          0          0          8          5          2          1          -          -          -          -          -          1
 TrigSignatureMoniMT                                 INFO -- #3657158931 Features                             0          0          0          0          10         6          2          1          -          -          -          -          -
diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
index 8f864ecf55931667bf2a15a6cfe42957b58b7886..350b5c69ca71dd75baa29c3cb785e24ee98e8a29 100644
--- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
@@ -79,6 +79,9 @@ TrigSignatureMoniMT                                 INFO -- #234102568 Features
 TrigSignatureMoniMT                                 INFO HLT_2mu14_L12MU10 #2619091790
 TrigSignatureMoniMT                                 INFO -- #2619091790 Events         20         20         0          0          0          0          0          0          0          0          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #2619091790 Features                             0          0          0          0          0          0          0          0          -          -          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2mu14_l2io_L12MU10 #945295390
+TrigSignatureMoniMT                                 INFO -- #945295390 Events          20         20         0          0          0          0          0          0          0          0          -          -          -          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #945295390 Features                              0          0          0          0          0          0          0          0          -          -          -          -          -          
 TrigSignatureMoniMT                                 INFO HLT_2mu15_L12MU10 #557204938
 TrigSignatureMoniMT                                 INFO -- #557204938 Events          20         20         0          0          0          0          0          0          0          0          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #557204938 Features                              0          0          0          0          0          0          0          0          -          -          -          -          -          
@@ -109,6 +112,9 @@ TrigSignatureMoniMT                                 INFO -- #3304584056 Features
 TrigSignatureMoniMT                                 INFO HLT_2mu6_L12MU6 #1747073535
 TrigSignatureMoniMT                                 INFO -- #1747073535 Events         20         20         0          0          0          0          0          0          0          0          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #1747073535 Features                             0          0          0          0          0          0          0          0          -          -          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2mu6_l2io_L12MU6 #2996403520
+TrigSignatureMoniMT                                 INFO -- #2996403520 Events         20         20         0          0          0          0          0          0          0          0          -          -          -          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #2996403520 Features                             0          0          0          0          0          0          0          0          -          -          -          -          -          
 TrigSignatureMoniMT                                 INFO HLT_2mu6_muonqual_L12MU6 #2398136098
 TrigSignatureMoniMT                                 INFO -- #2398136098 Events         20         20         0          0          0          0          0          0          0          0          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #2398136098 Features                             0          0          0          0          0          0          0          0          -          -          -          -          -          
@@ -646,6 +652,9 @@ TrigSignatureMoniMT                                 INFO -- #86648125 Features
 TrigSignatureMoniMT                                 INFO HLT_mu35_ivarmedium_L1MU20 #597064890
 TrigSignatureMoniMT                                 INFO -- #597064890 Events          20         20         0          0          0          0          1          1          0          0          0          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #597064890 Features                              0          0          0          0          1          1          0          0          0          -          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_mu4_l2io_L1MU4 #1048276860
+TrigSignatureMoniMT                                 INFO -- #1048276860 Events         20         20         0          0          0          0          2          1          0          0          -          -          -          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #1048276860 Features                             0          0          0          0          3          1          0          0          -          -          -          -          -          
 TrigSignatureMoniMT                                 INFO HLT_mu50_L1MU20 #3657158931
 TrigSignatureMoniMT                                 INFO -- #3657158931 Events         20         20         0          0          0          0          1          1          0          0          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #3657158931 Features                             0          0          0          0          1          1          0          0          -          -          -          -          -          
diff --git a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
index fcd5a22a62d2fb4e06f3fcd55f5fec33375f4804..c8cdcce1afefb78b953450b92c563f34affb6eab 100644
--- a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
+++ b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
@@ -230,9 +230,15 @@ TriggerHLTListRun3 = [
     ('xAOD::L2StandAloneMuonContainer#HLT_MuonL2SAInfo',        'BS ESD AODFULL', 'Muon', 'inViews:MUViewRoIs'),
     ('xAOD::L2StandAloneMuonAuxContainer#HLT_MuonL2SAInfoAux.', 'BS ESD AODFULL', 'Muon'),
 
+    ('xAOD::L2StandAloneMuonContainer#HLT_MuonL2SAInfoIOmode',        'BS ESD AODFULL', 'Muon', 'inViews:MUCombViewRoIs'),
+    ('xAOD::L2StandAloneMuonAuxContainer#HLT_MuonL2SAInfoIOmodeAux.', 'BS ESD AODFULL', 'Muon'),
+
     ('xAOD::L2CombinedMuonContainer#HLT_MuonL2CBInfo',          'BS ESD AODFULL', 'Muon', 'inViews:MUCombViewRoIs'),
     ('xAOD::L2CombinedMuonAuxContainer#HLT_MuonL2CBInfoAux.',   'BS ESD AODFULL', 'Muon'),
 
+    ('xAOD::L2CombinedMuonContainer#HLT_MuonL2CBInfoIOmode',          'BS ESD AODFULL', 'Muon', 'inViews:MUCombViewRoIs'),
+    ('xAOD::L2CombinedMuonAuxContainer#HLT_MuonL2CBInfoIOmodeAux.',   'BS ESD AODFULL', 'Muon'),
+
     ('xAOD::L2IsoMuonContainer#HLT_MuonL2ISInfo',               'BS ESD AODFULL', 'Muon', 'inViews:MUIsoViewRoIs'),
     ('xAOD::L2IsoMuonAuxContainer#HLT_MuonL2ISInfoAux.',        'BS ESD AODFULL', 'Muon'),
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
index 8af44f9614549ec937cb962db8484daa0a6b13f5..32d066a3c9a65af7661a0bd5e532b8ac41c0ef75 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
@@ -350,6 +350,10 @@ def setupMenu():
         ChainProp(name='HLT_2mu4_bUpsimumu_L12MU4', groups=BphysicsGroup),
         #ATR-20839
         ChainProp(name='HLT_2mu4_bDimu_L12MU4', groups=BphysicsGroup),
+        #ATR-21003
+        ChainProp(name='HLT_mu4_l2io_L1MU4', groups=SingleMuonGroup),
+        ChainProp(name='HLT_2mu14_l2io_L12MU10', groups=MultiMuonGroup),
+        ChainProp(name='HLT_2mu6_l2io_L12MU6',     l1SeedThresholds=['MU6'],   groups=MultiMuonGroup),
     ]
 
     TriggerFlags.CombinedSlice.signatures = TriggerFlags.CombinedSlice.signatures() + [
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
index 82d7fc9784474ff9c4835ad716c0a6b8d2a6024b..a02231864877113c44c29e1420e35b8d8442754c 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
@@ -186,7 +186,7 @@ MuonChainParts = {
     'trigType'       : ['mu'],
     'etaRange'       : ['0eta2550','0eta105'],
     'threshold'      : '',
-    'extra'          : ['noL1', 'Comb', 'fast', 'msonly','lateMu', "Dr", "muoncalib"],
+    'extra'          : ['noL1', 'Comb', 'fast', 'msonly','lateMu', "Dr", "muoncalib" ,'l2io'],
     'IDinfo'         : [],
     'isoInfo'        : ['ivar','ivarmedium'],
     'invMassInfo'    : ['10invm70'],
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py
index 824a4e6adac8e9293e0be0dd38c5c14983ec51c6..1d0bf15daab88ebf1009b0c9d924c09c6f47ff76 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py
@@ -11,7 +11,7 @@ log = logging.getLogger("TriggerMenuMT.HLTMenuConfig.Muon.MuonDef")
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase
 
-from TriggerMenuMT.HLTMenuConfig.Muon.MuonSequenceSetup import muFastSequence, muFastOvlpRmSequence, muCombSequence, muCombOvlpRmSequence, muEFSASequence, muIsoSequence, muEFCBSequence, muEFSAFSSequence, muEFCBFSSequence, muEFIsoSequence, efLateMuRoISequence, efLateMuSequence
+from TriggerMenuMT.HLTMenuConfig.Muon.MuonSequenceSetup import muFastSequence, muFastOvlpRmSequence, muCombSequence, muCombOvlpRmSequence, mul2IOOvlpRmSequence, muEFSASequence, muIsoSequence, muEFCBSequence, muEFSAFSSequence, muEFCBFSSequence, muEFIsoSequence, efLateMuRoISequence, efLateMuSequence
 from TrigMuonHypoMT.TrigMuonHypoMTConfig import TrigMuonEFInvMassHypoToolFromDict
 
 # this must be moved to the HypoTool file:
@@ -38,6 +38,9 @@ def muCombSequenceCfg(flags):
 def muCombOvlpRmSequenceCfg(flags):
     return muCombOvlpRmSequence()
 
+def mul2IOOvlpRmSequenceCfg(flags):
+    return mul2IOOvlpRmSequence()
+
 def muEFSASequenceCfg(flags):
     return muEFSASequence()
 
@@ -107,6 +110,7 @@ class MuonChainConfiguration(ChainConfigurationBase):
             "":[['getmuFast', 'getmuComb'], ['getmuEFSA', 'getmuEFCB']],
             "fast":[['getmuFast']],
             "Comb":[['getmuFast', 'getmuComb']],
+            "l2io":[['getmuFast', 'getmuCombIO'], ['getmuEFSA', 'getmuEFCB']],
             "noL2Comb" : [['getmuFast'], ['getmuEFSA', 'getmuEFCB']],
             "ivar":[['getmuFast', 'getmuComb', 'getmuIso']],
             "noL1":[[],['getFSmuEFSA', 'getFSmuEFCB']],
@@ -123,7 +127,7 @@ class MuonChainConfiguration(ChainConfigurationBase):
     # --------------------
     def getmuFast(self):
         doOvlpRm = False
-        if "bTau" in self.chainName or "bJpsi" in self.chainName or "bUpsi" in self.chainName or "bDimu" in self.chainName or "bBmu" in self.chainName:
+        if "bTau" in self.chainName or "bJpsi" in self.chainName or "bUpsi" in self.chainName or "bDimu" in self.chainName or "bBmu" in self.chainName or "l2io" in self.chainName:
            doOvlpRm = False
         elif self.mult>1:
            doOvlpRm = True
@@ -154,6 +158,10 @@ class MuonChainConfiguration(ChainConfigurationBase):
         else:
            return self.getStep(2, 'muComb', [muCombSequenceCfg] )
 
+    # --------------------
+    def getmuCombIO(self):
+        return self.getStep(2, 'muCombIO', [mul2IOOvlpRmSequenceCfg] )
+
     # --------------------
     def getmuEFSA(self):
         return self.getStep(3,'muEFSA',[ muEFSASequenceCfg])
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
index 20ae6f40614bdc1609182cc65f0abca6517c0bb3..50de2d383311caf02387a7ea0355fa804b6f7490 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
@@ -5,7 +5,8 @@
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFragmentsPool
 from AthenaCommon.CFElements import parOR, seqAND, seqOR
 from AthenaConfiguration.AllConfigFlags import ConfigFlags
-
+from AthenaCommon.Logging import logging
+log = logging.getLogger('MuonSequenceSetup')
 
 #-----------------------------------------------------#
 ### Used the algorithms as Step1 "muFast step" ###
@@ -115,7 +116,7 @@ def muCombAlgSequence(ConfigFlags):
     l2muCombViewsMaker.ViewFallThrough = True #if this needs to access anything from the previous step, from within the view
 
     ### get ID tracking and muComb reco sequences ###    
-    from TriggerMenuMT.HLTMenuConfig.Muon.MuonSetup  import muCombRecoSequence, muonIDFastTrackingSequence
+    from TriggerMenuMT.HLTMenuConfig.Muon.MuonSetup  import muFastRecoSequence, muCombRecoSequence, muonIDFastTrackingSequence
     muCombRecoSequence, sequenceOut = muCombRecoSequence( l2muCombViewsMaker.InViewRoIs, "FTF" )
  
     #Filter algorithm to run muComb only if non-Bphysics muon chains are active
@@ -126,7 +127,10 @@ def muCombAlgSequence(ConfigFlags):
     muonChainFilter.ChainsToFilter=bphysChains
     muonChainFilter.InputDecisions = [ CFNaming.inputMakerOutName(l2muCombViewsMaker.name()) ]
     muonChainFilter.L2MuCombContainer = sequenceOut
+    muonChainFilter.WriteMuFast = False
+    muonChainFilter.WriteMuComb = True
 
+    # for nominal muComb
     muCombFilterSequence = seqAND("l2muCombFilterSequence", [muonChainFilter, muCombRecoSequence])
 
     extraLoads = []
@@ -135,7 +139,22 @@ def muCombAlgSequence(ConfigFlags):
       extraLoads += [( 'xAOD::TrigCompositeContainer' , 'StoreGateSvc+'+decision )]
 
     muFastIDRecoSequence = muonIDFastTrackingSequence( l2muCombViewsMaker.InViewRoIs , "", extraLoads )
-    muCombIDSequence = parOR("l2muCombIDSequence", [muFastIDRecoSequence, muCombFilterSequence])
+    # muCombIDSequence = parOR("l2muCombIDSequence", [muFastIDRecoSequence, muCombFilterSequence])
+
+    # for Inside-out L2SA
+    muFastIORecoSequence, sequenceOutL2SAIO = muFastRecoSequence( "MURoIs", doFullScanID=False, InsideOutMode=True )
+    insideoutMuonChainFilter = MuonChainFilterAlg("FilterInsideOutMuonChains")
+    insideoutMuonChains = getInsideOutMuonChainNames()
+    insideoutMuonChainFilter.ChainsToFilter = insideoutMuonChains
+    insideoutMuonChainFilter.InputDecisions = [ CFNaming.inputMakerOutName(l2muCombViewsMaker.name()) ]
+    insideoutMuonChainFilter.L2MuFastContainer = sequenceOutL2SAIO
+    insideoutMuonChainFilter.L2MuCombContainer = muNames.L2CBName+"IOmode"
+    insideoutMuonChainFilter.WriteMuFast = True
+    insideoutMuonChainFilter.WriteMuComb = True
+
+    muFastIOFilterSequence = seqAND("l2muFastIOFilterSequence", [insideoutMuonChainFilter, muFastIORecoSequence])
+
+    muCombIDSequence = parOR("l2muCombIDSequence", [muFastIDRecoSequence, muCombFilterSequence, muFastIOFilterSequence])
 
     l2muCombViewsMaker.ViewNodeName = muCombIDSequence.name()
 
@@ -182,6 +201,25 @@ def muCombOvlpRmSequence():
 
 
 
+def mul2IOOvlpRmSequence():
+
+    (l2muCombSequence, l2muCombViewsMaker, sequenceOut) = RecoFragmentsPool.retrieve(muCombAlgSequence, ConfigFlags)
+
+    ### set up muCombHypo algorithm ###
+    from TrigMuonHypoMT.TrigMuonHypoMTConfig import TrigmuCombHypoAlg
+    trigmuCombHypo = TrigmuCombHypoAlg("TrigL2MuCBIOHypoAlg")
+    trigmuCombHypo.MuonL2CBInfoFromMuCombAlg = muNames.L2CBName+"IOmode"
+
+    # from TrigMuonHypoMT.TrigMuonHypoMTConfig import TrigL2MuonOverlapRemoverMucombToolFromDict
+    from TrigMuonHypoMT.TrigMuonHypoMTConfig import Trigl2IOHypoToolwORFromDict
+
+    return MenuSequence( Sequence    = l2muCombSequence,
+                         Maker       = l2muCombViewsMaker,
+                         Hypo        = trigmuCombHypo,
+                         HypoToolGen = Trigl2IOHypoToolwORFromDict )
+
+
+
 ######################
 ###  EFSA step ###
 ######################
@@ -603,3 +641,26 @@ def getBphysChainNames():
         for chain in bphysSlice:
             chains.append(chain.name)
     return chains
+
+############################################################
+### Get muon triggers except L2 inside-out trigger
+### to filter chains where we don't want to run L2SA IO mode
+############################################################
+
+def getInsideOutMuonChainNames():
+
+    from TriggerJobOpts.TriggerFlags import TriggerFlags
+    muonSlice = TriggerFlags.MuonSlice.signatures()
+    bphysSlice = TriggerFlags.BphysicsSlice.signatures()
+    chains =[]
+
+    try:
+        chains += [chain.name for chain in muonSlice if "l2io" not in chain.name]
+    except Exception as e:
+        log.debug(e)
+    try:
+        chains += [chain.name for chain in bphysSlice if "l2io" not in chain.name]
+    except Exception as e:
+        log.debug(e)
+
+    return chains
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py
index c638bde29a222f6c80bc037f731f279c0bf3d3e3..57209cf03234fb7814026744cf7a34e1c17278e8 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSetup.py
@@ -335,12 +335,33 @@ def makeMuonPrepDataAlgs(RoIs="MURoIs", forFullScan=False):
   return muDecodeRecoSequence
 
 
-def muFastRecoSequence( RoIs, doFullScanID = False ):
+def muFastRecoSequence( RoIs, doFullScanID = False, InsideOutMode=False ):
 
   from AthenaCommon.AppMgr import ToolSvc
   from AthenaCommon.CFElements import parOR
 
-  muFastRecoSequence = parOR("l2MuViewNode")
+  # muFastRecoSequence = parOR("l2MuViewNode")
+  postFix = ""
+  if InsideOutMode:
+    postFix = "IOmode"
+  muFastRecoSequence = parOR("l2Mu"+postFix+"ViewNode")
+
+  # In insideout mode, need to inherit muon decoding objects for TGC, RPC, MDT, CSC
+  if InsideOutMode:
+    import AthenaCommon.CfgMgr as CfgMgr
+    ViewVerify = CfgMgr.AthViews__ViewDataVerifier("muFastIOmodeViewDataVerifier")
+    ViewVerify.DataObjects = [('Muon::TgcPrepDataContainer','StoreGateSvc+TGC_Measurements'),
+                              ('TgcRdoContainer' , 'StoreGateSvc+TGCRDO'),
+                              ('Muon::RpcPrepDataContainer','StoreGateSvc+RPC_Measurements'),
+                              ('Muon::MdtPrepDataContainer','StoreGateSvc+MDT_DriftCircles'),
+                              ('TrigRoiDescriptorCollection','StoreGateSvc+MURoIs')]
+    if MuonGeometryFlags.hasCSC():
+      ViewVerify.DataObjects += [('Muon::CscPrepDataContainer','StoreGateSvc+CSC_Clusters')]
+    if MuonGeometryFlags.hasSTGC():
+      ViewVerify.DataObjects += [('Muon::sTgcPrepDataContainer','StoreGateSvc+STGC_Measurements')]
+    if MuonGeometryFlags.hasMM():
+      ViewVerify.DataObjects += [('Muon::MMPrepDataContainer','StoreGateSvc+MM_Measurements')]
+    muFastRecoSequence+=ViewVerify
 
   import AthenaCommon.CfgMgr as CfgMgr
   muFastRecoVDV = CfgMgr.AthViews__ViewDataVerifier("muFastRecoVDV")
@@ -427,7 +448,7 @@ def muFastRecoSequence( RoIs, doFullScanID = False ):
 
   ### set up MuFastSteering ###
   from TrigL2MuonSA.TrigL2MuonSAConfig import TrigL2MuonSAMTConfig
-  muFastAlg = TrigL2MuonSAMTConfig("Muon")
+  muFastAlg = TrigL2MuonSAMTConfig("Muon"+postFix)
 
   from TrigL2MuonSA.TrigL2MuonSAConf import TrigL2MuonSA__MuFastDataPreparator
   MuFastDataPreparator = TrigL2MuonSA__MuFastDataPreparator()
@@ -451,11 +472,14 @@ def muFastRecoSequence( RoIs, doFullScanID = False ):
 
   muFastAlg.RecMuonRoI = "HLT_RecMURoIs"
   muFastAlg.MuRoIs = RoIs
-  muFastAlg.MuonL2SAInfo = muNames.L2SAName
-  muFastAlg.MuonCalibrationStream = "MuonCalibrationStream"
-  muFastAlg.forID = muNames.L2forIDName
-  muFastAlg.forMS = "forMS" 
+  muFastAlg.MuonL2SAInfo = muNames.L2SAName+postFix
+  muFastAlg.L2IOCB = muNames.L2CBName+postFix
+  muFastAlg.MuonCalibrationStream = "MuonCalibrationStream"+postFix
+  muFastAlg.forID = muNames.L2forIDName+postFix
+  muFastAlg.forMS = "forMS"+postFix
   muFastAlg.FILL_FSIDRoI = doFullScanID
+  muFastAlg.InsideOutMode = InsideOutMode
+  muFastAlg.TrackParticlesContainerName = TrackParticlesName
 
   muFastRecoSequence += muFastAlg
   sequenceOut = muFastAlg.MuonL2SAInfo