docs: public void passivate(StatefulBeanO beanO, BeanMetaData bmd) // d648122
      throws RemoteException
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled()) //130050
              Tr.entry(tc, "passivate: " + beanO);
  
          if (beanO.isRemoved() || isTerminating())
          {
              if (isTraceOn && tc.isEventEnabled()) //130050
                  Tr.event(tc, "Bean removed!");
              return;
          }
  
          BeanId bid = beanO.getId();
          Object sb = beanO.ivEjbInstance; // d367572.7
          boolean exceptionCaught = false; //155114
          ObjectOutputStream beanStream = null; //155114
  
          // LI2775-107.2 Begins WS18354.02a,MD19305C
          Object credToken = ivContainer.getEJBRuntime().pushServerIdentity();
          // LI2775-107.2 Ends
  
          ObjectOutputStream beanStream2 = null; // d430549.11
  
          // Get the JPAExPcBindingContext for this SFSB.
          Object exPC = beanO.getJPAExPcBindingContext(); //d468174
  
          try
          {
              // LIDB2018-1 begins
              // Check whether SFSB failover is enabled. Note, we could
              // factor out this code so it is the same regardless of
              // whether SFSB failover is enabled or not.  However, to
              // ensure no impact to existing performance when not enabled,
              // we chose to not factor into a common implementation.
              ByteArrayOutputStream baos = null;
              long lastAccessTime = beanO.getLastAccessTime();
  
              //PK69093 - Only allow one stream to be open for writing at one time.
              synchronized (ivPassivateLock)
              {
                  if (beanO.sfsbFailoverEnabled())
                  {
                      // For failover, initially write to a ByteArrayOutputStream. This will later be converted to
                      // bytes and then persisted
  
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "failover is enabled");
  
                      // If the EJB module is 3.0 or greater, use the new format, which is later
                      if (getEJBModuleVersion(beanO) >= BeanMetaData.J2EE_EJB_VERSION_3_0)
                      {
                          // Set up the bean stream to initially write to a ByteArrayOutputStream
                          baos = new ByteArrayOutputStream(1024);
                          beanStream = createPassivationOutputStream(new GZIPOutputStream(baos));
                      }
                      else
                      {
                          // pre-3.0 module - Use old format since we may be in a mixed cluster environment
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "processing EJB 2.1 module or prior");
  
                          // Serialize and compress the data in SFSB.
                          byte[] bytes = getCompressedBytes(sb, lastAccessTime, exPC);
  
                          // Get a file outstream that does not compress the data
                          // since we already have the data compressed.
                          OutputStream ostream = ivBeanStore.getOutputStream(bid);
                          beanStream = createPassivationOutputStream(ostream);
  
                          // Write length of compressed data.
                          beanStream.writeInt(bytes.length);
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "length of compressed bytes is: " + bytes.length);
  
                          // Write compressed data to file.
                          beanStream.write(bytes);
                          beanStream.close();
  
                          // Replicate compressed data to failover servers by calling
                          // the method that updates the failover cache entry for this SFSB.
                          beanO.updateFailoverEntry(bytes, lastAccessTime);
  
                          return;
                      }
                  }
                  else // failover not enabled - setup the beanStream
                  {
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "failover is NOT enabled");
                      beanStream = createPassivationOutputStream(ivBeanStore.getGZIPOutputStream(bid));
                  }
  
                  // Passivate sb in the 3.0 format
                  EJBObjectInfo objectInfo = null;
                  Map<String, Map<String, Field>> passivatorFields = getPassivatorFields(bmd); // d648122
  
                  if (sb instanceof Serializable)
                  {
                      objectInfo = createSerializableObjectInfo(sb);
                  }
                  else
                  {
                      objectInfo = createNonSerializableObjectInfo(sb, passivatorFields); // d648122
                  }
  
                  // Write last access time.
                  beanStream.writeLong(lastAccessTime);
  
                  // Write the persistence context
                  beanStream.writeObject(exPC);
  
                  // Write the SFSB state.
                  beanStream.writeObject(objectInfo);
  
                  // Write the managed object state of the EJB instance
                  writeManagedObjectContext(beanStream, beanO.ivEjbManagedObjectContext);
  
                  Object[] interceptors = beanO.ivInterceptors;
                  if (interceptors == null)
                  {
                      beanStream.writeInt(-1);
                  }
                  else
                  {
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "Processing " + interceptors.length + " interceptors");
  
                      beanStream.writeInt(interceptors.length);
                      for (int i = 0; i < interceptors.length; i++)
                      {
                          Object interceptor = interceptors[i];
  
                          EJBObjectInfo interceptorObjectInfo = null;
                          if (interceptor instanceof Serializable)
                          {
                              interceptorObjectInfo = createSerializableObjectInfo(interceptor);
                          }
                          else
                          {
                              interceptorObjectInfo = createNonSerializableObjectInfo(interceptor, passivatorFields); // d648122
                          }
  
                          beanStream.writeObject(interceptorObjectInfo);
                      }
                  }
  
                  beanStream.close();
  
                  // If failover is enabled, now convert to a byte array and persist it
                  if (beanO.sfsbFailoverEnabled() && baos != null) //d468174
                  {
                      byte[] bytes = baos.toByteArray();
                      beanStream2 = createPassivationOutputStream(ivBeanStore.getOutputStream(bid));
                      beanStream2.writeInt(bytes.length);
                      beanStream2.write(bytes);
                      beanStream2.close();
  
                      // Replicate compressed data to failover cache servers by calling
                      // the method that updates the failover cache entry for this SFSB.
                      beanO.updateFailoverEntry(bytes, lastAccessTime);
                  }
                  // LIDB2018-1 ends
              }
          } catch (CSIException ex)
          {
              exceptionCaught = true; //155114
              FFDCFilter.processException(ex, CLASS_NAME + ".passivate", "113", this);
              throw new RemoteException("passivation failed", ex);
          } catch (Throwable e) //155114
          {
              // d584932 - Catch Throwable, not Exception, to ensure that we
              // set exceptionCaught when Errors are thrown.
              exceptionCaught = true; //155114
              FFDCFilter.processException(e, CLASS_NAME + ".passivate", "107", this);
              Tr.warning(tc, "CANNOT_PASSIVATE_STATEFUL_BEAN_CNTR0001W",
                         new Object[] { beanO.toString(), this, e }); //p111002.3
              throw new RemoteException("passivation failed", e);
          } finally //155114
          {
              // LI2775-107.2 Begins WS18354.02a,MD19305C
              if (credToken != null) // d646413.2
              {
                  ivContainer.getEJBRuntime().popServerIdentity(credToken);
              }
              // LI2775-107.2 Ends
  
              if (exceptionCaught) // 155114
              {
                  // attempt to close and remove the beanStore
                  try
                  {
                      if (beanStream != null)
                      {
                          beanStream.close();
                          // PK69093 - beanStore.remove will access a file, as such lets synch this call
                          // such that only one file can be open for remove at a time.
                          synchronized (ivRemoveLock)
                          {
                              ivBeanStore.remove(bid);
                          }
                      }
  
                      if (beanStream2 != null) // d430549.11
                      {
                          beanStream2.close();
                      }
                  } catch (Exception ex)
                  {
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "exception closing stream", ex);
                  }
              }
          }
  
          if (isTraceOn && tc.isEntryEnabled()) //130050
              Tr.exit(tc, "passivate");
      }