docs: public synchronized void putException(Throwable throwable, String probeId, Conversation conversation)
     {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "putException",
                                             new Object[]{throwable, probeId, conversation});
  
        Throwable currentException = throwable;
  
        // First we need to work out how many exceptions to send back
        short numberOfExceptions = 0;
        while(currentException != null)
        {
           currentException = currentException.getCause();
           numberOfExceptions++;
        }
  
        // Now add them to the buffer
        currentException = throwable;
  
        // First put in the buffer how many exceptions are being sent back
        putShort(numberOfExceptions);
  
        // Now iterate over the rest
        while (currentException != null)
        {
           short exceptionId = getExceptionId(currentException);
  
           addException(currentException,
                        exceptionId,
                        probeId);
  
           // Now get the next one in the chain
           currentException = currentException.getCause();
           // Ensure we null out the probe - this doesn't apply for any more exceptions
           probeId = null;
        }
  
        final HandshakeProperties handshakeProperties = conversation.getHandshakeProperties();
        if ((handshakeProperties != null) &&
            ((CATHandshakeProperties)handshakeProperties).isFapLevelKnown())
        {
           // Only do FAP level checking if we know the FAP level - otherwise, assume a pre-FAP
           // 9 format for the exception flow.  We can find ourselves in a situation where we
           // don't know the FAP level if, for example, an exception is thrown during handshaking.
  
           final int fapLevel = ((CATHandshakeProperties)handshakeProperties).getFapLevel();
           if (fapLevel >= JFapChannelConstants.FAP_VERSION_9)
           {
              // At FAP version 9 or greater we transport the reason and inserts
              // of any exception which implements the Reasonable interface, or
              // inherits from SIException or SIErrorException.
              int reason = Reasonable.DEFAULT_REASON;
              String inserts[] = Reasonable.DEFAULT_INSERTS;
              if (throwable instanceof Reasonable)
              {
                 reason = ((Reasonable)throwable).getExceptionReason();
                 inserts = ((Reasonable)throwable).getExceptionInserts();
              }
              else if (throwable instanceof SIException)
              {
                 reason = ((SIException)throwable).getExceptionReason();
                 inserts = ((SIException)throwable).getExceptionInserts();
              }
              else if (throwable instanceof SIErrorException)
              {
                 reason = ((SIErrorException)throwable).getExceptionReason();
                 inserts = ((SIErrorException)throwable).getExceptionInserts();
              }
  
              putInt(reason);
              putShort(inserts.length);
              for (int i=0; i < inserts.length; ++i)
              {
                 putString(inserts[i]);
              }
           }
        }
  
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "putException");
     }