docs: @Override
      void atTimeout(BeanId beanId) throws RemoteException
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled()) {
              Tr.entry(tc, "atTimeout " + beanId);
          }
  
          BeanO bean = null;
          Throwable exception = null;
          MasterKey key = new MasterKey(beanId);
  
          try
          {
              synchronized (locks.getLock(key))
              {
                  // Since the StatefulBeanReaper may detect that beans have timed
                  // out in various states (active or passivated), it is necessary
                  // to handle all of the various situations here.  Note that the
                  // bean may have even changed states, including being removed
                  // since the reaper first detected it has timed out.         d112258
                  if ((bean = (BeanO) cache.findDontPinNAdjustPinCount(key, 0)) == null)
                  {
                      // If the bean is not in the cache, then either the bean
                      // has been passivated (normal case), and so the passivated
                      // file needs to be deleted.  Or, the application or the
                      // background cache eviction thread has removed the bean,
                      // in which case there is nothing to do.                  d112258
                      // If the bean is using transaction activation policy and timed
                      // out while in a method, post invoke will update its last
                      // access and passivate it.  For this scenario, we must verify
                      // that the bean is still timed out now that we have locks.
                      TimeoutElement elt = reaper.getTimeoutElement(beanId);
                      if (reaper.beanExistsAndTimedOut(elt, beanId))
                      {
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "Bean not in cache: removing file");
  
                          // LIDB2018-1 begins
                          ivPassivator.remove(beanId, true); //LIDB2018-1 //d204278.2
  
                          // d204278.2
                          // Ensure bean is no longer in reaper list.
                          reaper.remove(beanId); // d103404.1
  
                          // StatefulPassivator.remove call did remove SFSB from
                          // either bean store or from local SfFailoverCache.  For the
                          // latter case, it did not remove from remote failover caches.
                          // So we need to ensure SFSB is removed from remote
                          // failover cache as well since a timeout occurred.
                          BeanMetaData bmd = beanId.getBeanMetaData();
                          SfFailoverClient failover = bmd.getSfFailoverClient();
                          if (failover != null)
                          {
                              failover.removeEntry(beanId);
                          }
                          // LIDB2018-1 ends
                      }
                      else
                      {
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "Bean not in cache: already removed");
                      }
                  }
                  else
                  {
                      // If the bean was found in the cache, then it is active
                      // (possibly even activated after the StatefulBeanReaper detected
                      // it had timed out). Since it is in the cache, it is possible
                      // that it is enlisted in a transaction, or was in a transaction
                      // and is now no longer timed out (because the timeout clock is
                      // reset at the end of a method). Double check that the bean is
                      // still timed out now that we've acquired locks.         d112258
                      StatefulBeanO sfbean = (StatefulBeanO) bean;
                      if (sfbean.isTimedOut()) //d204278, F61004.5
                      {
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "Found bean in cache: passivating / removing");
  
                          try
                          {
                              // The bean is in the cache and timed out. Remove it from
                              // the cache, reaper, and uninstall it which will take it
                              // through the required EJB lifecycle (passivate).  d112258
                              bean = (BeanO) cache.remove(key, false);
                              bean.ivCacheKey = null; // d199233
                              reaper.remove(beanId);
  
                              //d523478 start
                              // Ensure SFSB is removed from remote failover cache as well since a timeout occurred.
                              BeanMetaData bmd = beanId.getBeanMetaData();
                              SfFailoverClient failover = bmd.getSfFailoverClient();
                              if (failover != null)
                              {
                                  failover.removeEntry(beanId);
                              }
                              // d523478 end
  
                              // Now uninstall the bean.
                              ((StatefulBeanO) bean).uninstall();
                          } catch (IllegalOperationException ioe)
                          {
                              // This occurs if the bean timed out while enlisted with
                              // an active transaction (i.e. the timeout clock is
                              // reset at the end of trans).  Nothing should be done
                              // except release the pin taken above on the find.  d112258
                              // Do not ffdc, since expected (comment required).  d195475
                              //FFDCFilter.processException(ioe, CLASS_NAME + ".atTimeout",
                              //                            "457", this);
                              if (isTraceOn && tc.isDebugEnabled())
                                  Tr.debug(tc, "Found bean in cache: active");
                          }
                      }
                      else
                      {
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "Found bean in cache: no longer timed out");
                      }
                  }
              }
          } catch (RemoteException e)
          {
              FFDCFilter.processException(e, CLASS_NAME + ".atTimeout", "474", this);
              exception = e;
              throw e;
          } catch (RuntimeException e)
          {
              FFDCFilter.processException(e, CLASS_NAME + ".atTimeout", "480", this);
              exception = e;
              throw e;
          } finally
          {
              if (exception != null) {
                  if (isTraceOn && tc.isEventEnabled())
                      Tr.event(tc, "atTimeout: exception raised", exception);
              }
  
              if (isTraceOn && tc.isEntryEnabled())
                  Tr.exit(tc, "atTimeout");
          }
      }