diff --git a/Calorimeter/CaloEvent/CaloEvent/CaloCluster.h b/Calorimeter/CaloEvent/CaloEvent/CaloCluster.h
index 12c06dd187d03875317b0fc417f77bbb30acf6e3..55ccf2591b94e5f25ec8456560d46cbf9d949edb 100644
--- a/Calorimeter/CaloEvent/CaloEvent/CaloCluster.h
+++ b/Calorimeter/CaloEvent/CaloEvent/CaloCluster.h
@@ -71,7 +71,7 @@ class CaloCluster;
 struct CaloClusterSignalState;
 
 
-class ATLAS_NOT_THREAD_SAFE CaloCluster :  public CaloCompositeKineBase,
+class CaloCluster :  public CaloCompositeKineBase,
                             public CaloCompositeCellBase<CaloClusterNavigable>,
 		                        virtual public INavigable4Momentum,
                             public ISignalState,
@@ -281,6 +281,15 @@ class ATLAS_NOT_THREAD_SAFE CaloCluster :  public CaloCompositeKineBase,
   /*! \brief Retrieve mass independent of signal state */
   virtual double m() const;
 
+  /*! \brief Retrieve energy for a specific signal state */
+  double e(signalstate_t s) const;
+  /*! \brief Retrieve eta for a specific signal state */
+  double eta(signalstate_t s) const;
+  /*! \brief Retrieve phi for a specific signal state */
+  double phi(signalstate_t s) const;
+  /*! \brief Retrieve mass for a specific signal state */
+  double m(signalstate_t s) const;
+
   /*! \brief Set energy */
   virtual void setE(double e);
   /*! \brief Set eta */
@@ -479,6 +488,9 @@ class ATLAS_NOT_THREAD_SAFE CaloCluster :  public CaloCompositeKineBase,
   data_link_type m_dataLink; /*!< link to data */ 
   /*!}*/
 
+  /// Non-const pointer to linked store.
+  CaloShower* m_shower;
+
   /*! \brief Stores basic energy signal */
   double m_basicSignal;
 
@@ -657,28 +669,28 @@ class ATLAS_NOT_THREAD_SAFE CaloCluster :  public CaloCompositeKineBase,
   // Just hide them from reflex for now.
 #ifndef __REFLEX__
   /*! \brief Pointer to getter functions */
-  mutable GET_VALUE m_getE;
+  GET_VALUE m_getE;
   /*! \brief Pointer to getter functions */
-  mutable GET_VALUE m_getEta;
+  GET_VALUE m_getEta;
   /*! \brief Pointer to getter functions */
-  mutable GET_VALUE m_getPhi;
+  GET_VALUE m_getPhi;
   /*! \brief Pointer to getter functions */
-  mutable GET_VALUE m_getM;
+  GET_VALUE m_getM;
 
   /*! \brief Pointer to setter functions */
-  mutable SET_VALUE m_setE;
+  SET_VALUE m_setE;
   /*! \brief Pointer to setter functions */
-  mutable SET_VALUE m_setEta;
+  SET_VALUE m_setEta;
   /*! \brief Pointer to setter functions */
-  mutable SET_VALUE m_setPhi;
+  SET_VALUE m_setPhi;
   /*! \brief Pointer to setter functions */
-  mutable SET_VALUE m_setM;
+  SET_VALUE m_setM;
 #endif
 
   /*! \brief Stores actual signal state */
-  mutable signalstate_t m_signalState;
+  signalstate_t m_signalState;
   /*! \brief Stores default signal state */
-  mutable signalstate_t m_defSigState;
+  signalstate_t m_defSigState;
 
   /*! \brief Stores raw signal */
   double m_rawE;
@@ -699,15 +711,12 @@ class ATLAS_NOT_THREAD_SAFE CaloCluster :  public CaloCompositeKineBase,
   double m_altM;
 
   /*! \brief Helper to switch to raw state */
-  bool setStateRaw() const;
   bool setStateRaw();
 
   /*! \brief Helper to switch to calibrated (LC) state */
-  bool setStateCal() const;
   bool setStateCal();
 
   /*! \brief Helper to switch to calibrated (cell weight) state */
-  bool setStateAlt() const;
   bool setStateAlt();
 
 public:
@@ -765,6 +774,70 @@ inline void CaloCluster::setM(double m)
 { (this->*m_setM)(m); }  
 #endif
 
+inline double CaloCluster::e(signalstate_t s)   const 
+{
+  if (!hasSignalState(s)) return m_errorValue;
+  switch (s) {
+  case statename_t::CALIBRATED:
+    return P4EEtaPhiM::e();
+  case statename_t::UNCALIBRATED:
+    return m_rawE;
+  case statename_t::ALTCALIBRATED:
+    return m_altE;
+  default:
+    return m_errorValue;
+  }
+}
+
+
+inline double CaloCluster::eta(signalstate_t s) const
+{
+  if (!hasSignalState(s)) return m_errorValue;
+  switch (s) {
+  case statename_t::CALIBRATED:
+    return P4EEtaPhiM::eta();
+  case statename_t::UNCALIBRATED:
+    return m_rawEta;
+  case statename_t::ALTCALIBRATED:
+    return m_altEta;
+  default:
+    return m_errorValue;
+  }
+}
+
+
+inline double CaloCluster::phi(signalstate_t s) const
+{
+  if (!hasSignalState(s)) return m_errorValue;
+  switch (s) {
+  case statename_t::CALIBRATED:
+    return P4EEtaPhiM::phi();
+  case statename_t::UNCALIBRATED:
+    return m_rawPhi;
+  case statename_t::ALTCALIBRATED:
+    return m_altPhi;
+  default:
+    return m_errorValue;
+  }
+}
+
+
+inline double CaloCluster::m(signalstate_t s)   const
+{
+  if (!hasSignalState(s)) return m_errorValue;
+  switch (s) {
+  case statename_t::CALIBRATED:
+    return P4EEtaPhiM::m();
+  case statename_t::UNCALIBRATED:
+    return m_rawM;
+  case statename_t::ALTCALIBRATED:
+    return m_altM;
+  default:
+    return m_errorValue;
+  }
+}
+
+
 inline void CaloCluster::set4Mom(const I4Momentum* const pMom)
 {
   this->setE(pMom->e());
@@ -838,6 +911,7 @@ CaloCluster::setDataStore(CaloShower* pData,bool ownStores)
   //  m_dataStorePointer = pData;
   m_ownDataStore = ownStores;
   m_dataLink.setElement(pData);
+  m_shower = pData;
   return m_dataLink.isValid(); 
 } 
 
@@ -1189,7 +1263,7 @@ inline bool CaloCluster::setDataLink(CaloShowerContainer* pDataLink)
 {
   if (!pDataLink) 
     return false;
-  CaloShower* pData = const_cast<CaloShower*>(*m_dataLink);
+  CaloShower* pData = m_shower;
   m_ownDataStore = !pDataLink->ownElements();
   return CaloClusterLinkTemplate<CaloShowerContainer>::setLink(pDataLink,
 							       pData,
diff --git a/Calorimeter/CaloEvent/src/CaloCluster.cxx b/Calorimeter/CaloEvent/src/CaloCluster.cxx
index 1e49a6419caa56450c3e9db0ef2e79482c89fb06..80752fd69ea8fc391ecaf092b742249e92f092c6 100644
--- a/Calorimeter/CaloEvent/src/CaloCluster.cxx
+++ b/Calorimeter/CaloEvent/src/CaloCluster.cxx
@@ -77,6 +77,7 @@ CaloCluster::CaloCluster(double eta0 /*= 0*/, double phi0 /*= 0*/,
     CaloCompositeCellBase<CaloClusterNavigable>(),
     m_dataStore(varTypePattern),
     m_ownDataStore(false),
+    m_shower(nullptr),
     m_basicSignal(0.),
     m_time(0.),
     m_samplingPattern(0),
@@ -156,6 +157,7 @@ CaloCluster::CaloCluster(const CaloCluster* pCluster)
   }
   CaloShower* pData = isExternalShowerThere
     ? new CaloShower(*(pCluster->m_dataLink)) : new CaloShower();
+  m_shower = pData;
   CaloCellLink* pLink = pCluster->getCellLink() != 0 ? new CaloCellLink(pCluster->getCellLink()) : new CaloCellLink();
   this->setStores(pData,pLink,
 		  m_ownDataStore);
@@ -216,6 +218,7 @@ CaloCluster::CaloCluster(const CaloCluster& rCluster)
   }
   CaloShower* pData = isExternalShowerThere
     ? new CaloShower(*(rCluster.m_dataLink)) : new CaloShower();
+  m_shower = pData;
   CaloCellLink* pLink = rCluster.getCellLink() != 0 ? new CaloCellLink(rCluster.getCellLink()) : new CaloCellLink();
   this->setStores(pData,pLink,
 		  m_ownDataStore);
@@ -1100,14 +1103,15 @@ CaloCluster::getDataStore(const variable_type& varType,bool traceLink)
     }
 
   // check external store if requested
-  if ( m_ownDataStore && !m_dataLink.isValid()) 
-    m_dataLink.setElement(new CaloShower());
+  if ( m_ownDataStore && !m_dataLink.isValid()) {
+    m_shower = new CaloShower();
+    m_dataLink.setElement(m_shower);
+  }
 
   // trace
-  if ( ( traceLink || m_ownDataStore ) && m_dataLink.isValid() )
+  if ( ( traceLink || m_ownDataStore ) && m_shower )
     {
-      CaloShower* pData = const_cast<CaloShower*>(*m_dataLink);
-      return &(pData->getSamplingStore());
+      return &(m_shower->getSamplingStore());
     }
 
   return (CaloSamplingData*)0;
@@ -1178,14 +1182,14 @@ CaloClusterMomentStore* CaloCluster::getMomentStore(bool useLink)
   // follow link policy: use link!
   if ( m_ownDataStore && m_dataLink.isValid() == 0 )
     {
-      m_dataLink.setElement(new CaloShower());
+      m_shower = new CaloShower();
+      m_dataLink.setElement(m_shower);
       return this->getMomentStore(useLink);
     }
 
-  if ( m_dataLink.isValid() || m_ownDataStore ) 
+  if ( m_shower || m_ownDataStore ) 
     {
-      CaloShower* pData = const_cast<CaloShower*>(*m_dataLink);
-      return &(pData->getMomentStore());
+      return &(m_shower->getMomentStore());
     }
   return (CaloClusterMomentStore*)0;
 }
@@ -1389,17 +1393,6 @@ bool CaloCluster::setStateRaw()
   //
   return true;  
 }
-bool CaloCluster::setStateRaw() const
-{
-  // std::cout << "CaloCluster [" << this 
-  //	    << "] setStateRaw()" << std::endl;
-  m_getE   = &CaloCluster::getRawE;
-  m_getEta = &CaloCluster::getRawEta;
-  m_getPhi = &CaloCluster::getRawPhi;
-  m_getM   = &CaloCluster::getRawM;  
-  //
-  return true;  
-}
 
 bool CaloCluster::setStateAlt()
 {
@@ -1417,18 +1410,6 @@ bool CaloCluster::setStateAlt()
   return true;  
 }
 
-bool CaloCluster::setStateAlt() const
-{
-  // std::cout << "CaloCluster [" << this 
-  //	    << "] setStateAlt()" << std::endl;
-  m_getE   = &CaloCluster::getAltE;
-  m_getEta = &CaloCluster::getAltEta;
-  m_getPhi = &CaloCluster::getAltPhi;
-  m_getM   = &CaloCluster::getAltM;  
-  //
-  return true;  
-}
-
 bool CaloCluster::setStateCal()
 {
   // std::cout << "CaloCluster [" << this 
@@ -1445,18 +1426,6 @@ bool CaloCluster::setStateCal()
   return true;  
 }
 
-bool CaloCluster::setStateCal() const
-{
-  // std::cout << "CaloCluster [" << this 
-  //	    << "] setStateCal()" << std::endl;
-  m_getE   = &CaloCluster::getCalE;
-  m_getEta = &CaloCluster::getCalEta;
-  m_getPhi = &CaloCluster::getCalPhi;
-  m_getM   = &CaloCluster::getCalM;  
-  //
-  return true;  
-}
-
 void CaloCluster::addBadChannel(const CaloClusterBadChannelData& badChannel) 
 {
  m_badChannelData.push_back(badChannel);