docs: public void sendToExceptionDestination(
                                             SIBusMessage siMessage,
                                             String alternateUser,
                                             TransactionCommon tran,
                                             int exceptionReason,
                                             ConnectionImpl conn,
                                             String[] exceptionStrings) throws SINotPossibleInCurrentConfigurationException, SIResourceException
      {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.entry(tc, "sendToExceptionDestination",
                          new Object[] { siMessage, alternateUser, tran, Integer.valueOf(exceptionReason), conn, exceptionStrings });
  
          boolean sendComplete = false;
          boolean defaultInUse = false; // Assume non-default exception destination is being used.
          LocalTransaction localTran = null;
  
          JsMessage jsMessage = (JsMessage) siMessage;
  
          // It isn't really valid to give us a message with no reliability set in it but
          // as it's part of the Core SPI I guess it could happen. For that reason, rather than
          // rejecting it we patch it up (so we don't start rejecting messages we'd previously
          // of accpeted -e.g. in the unit tests).
          if (jsMessage.getReliability().equals(Reliability.NONE))
          {
              // If we've got the original destination, use the default reliability of that
              if (_originalDestination != null)
              {
                  jsMessage.setReliability(_originalDestination.getDefaultReliability());
              }
              // Otherwise, get it from the system exception destination
              else
              {
                  try
                  {
                      _exceptionDestination =
                                      _messageProcessor.getDestinationManager().
                                                      getDestination(_exceptionDestinationName, true);
  
                      jsMessage.setReliability(_exceptionDestination.getDefaultReliability());
                  } catch (SIException e3)
                  {
                      /*
                       * ERROR : SYSTEM.DEFAULT.EXCEPTION.DESTINATION.<MENAME> queue did
                       * not exist on the ME. This should ALWAYS exist.
                       */
  
                      FFDCFilter.processException(
                                                  e3,
                                                  "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                                  "1:1279:1.137",
                                                  this);
  
                      SibTr.exception(tc, e3);
  
                      SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0003",
                                  new Object[] {
                                                "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                                "1:1287:1.137",
                                                e3,
                                                _exceptionDestinationName });
  
                      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                          SibTr.exit(tc, "sendToExceptionDestination", e3);
                      throw new SIErrorException(e3);
                  }
              }
          }
  
          SIMPMessage message = new MessageItem(jsMessage);
  
          UndeliverableReturnCode rc = checkMessage(message);
          if (rc == UndeliverableReturnCode.BLOCK)
          {
              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                  SibTr.exit(tc, "sendToExceptionDestination", rc);
  
              SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0005",
                          new Object[] {
                                        "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                        "1:1309:1.137",
                                        rc });
              throw new SINotPossibleInCurrentConfigurationException(
                              nls.getFormattedMessage(
                                                      "INTERNAL_MESSAGING_ERROR_CWSIP0005",
                                                      new Object[] {
                                                                    "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                                                    "1:1316:1.137",
                                                                    rc },
                                                      null));
          }
  
          if (rc != UndeliverableReturnCode.DISCARD)
          {
              JsMessage msg = null;
  
              try
              {
                  msg = message.getMessage().getReceived();
              } catch (MessageCopyFailedException e)
              {
                  // FFDC
                  FFDCFilter.processException(
                                              e,
                                              "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                              "1:1335:1.137",
                                              this);
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      SibTr.exit(tc, "sendToExceptionDestination", e);
  
                  SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0002",
                              new Object[] {
                                            "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                            "1:1344:1.137",
                                            e });
  
                  throw new SIErrorException(
                                  nls.getFormattedMessage(
                                                          "INTERNAL_MESSAGING_ERROR_CWSIP0002",
                                                          new Object[] {
                                                                        "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                                                        "1:1352:1.137",
                                                                        e },
                                                          null), e);
              }
  
              // F001333-14610
              // Pass null for the subscription ID as this code path is not currently
              // used in any scenario where a subscription would be present.
              msg = setMessageProperties(msg, exceptionReason, exceptionStrings, null);
  
              /*
               * If Destination is not null, get the exception destination.
               * If it is null - this indicates the default exception destination was required
               * so use this instead.
               */
  
              String newExceptionDestination = null;
  
              if (_originalDestination != null)
              {
                  newExceptionDestination = _originalDestination.getExceptionDestination();
                  if (newExceptionDestination.equals(JsConstants.DEFAULT_EXCEPTION_DESTINATION))
                  {
                      newExceptionDestination = _defaultExceptionDestinationName;
                      defaultInUse = true;
                  }
              }
              else
              {
                  newExceptionDestination = _defaultExceptionDestinationName;
                  defaultInUse = true;
              }
  
              /*
               * Entering synch block.
               * We MUST put the ExceptionDestination instance on a destination. Ideally
               * we would have an instance per consumer point (since there will be a
               * producerSession instance per consumerpoint). We cannot do this because we
               * cannot get references to the consumerpoints at the time we need to use the
               * ExceptionDestination.
               * 
               * Rather than perform a destination lookup every time we call
               * this method, we synchronize on one instance. If a different dest is needed
               * then we do a lookup within the synchronized block. This
               * introduces an optimisation for consecutive sends to the same exception
               * destination.
               */
  
              synchronized (_exceptionDestinationLock)
              {
  
                  /*
                   * If inputhandler ref has not been created yet, or exception destination has changed
                   * since the last call of this method, then get the inputhandler associated
                   * with the given exception destination
                   * 
                   * This inputhandler will be used to send messages to the exception destination
                   */
  
                  if (_inputHandler == null || !newExceptionDestination.equals(_exceptionDestinationName))
                  {
  
                      _exceptionDestinationName = newExceptionDestination;
  
                      /*
                       * Try to get an inputhandler to the exception destination specified in the
                       * destination's definition. If this fails, (e.g. if the exception destination
                       * does not exist) then attempt to get one to the default (which should ALWAYS
                       * succeed). If this fails then report a fatal error.
                       */
  
                      //Get the named destination from the destination manager
                      try
                      {
                          _exceptionDestination =
                                          _messageProcessor.getDestinationManager().
                                                          getDestination(_exceptionDestinationName, true);
  
                          // Check whether bus security is enabled
                          if (_messageProcessor.isBusSecure())
                          {
                              // Check authority to access to exc destination
                              AccessResult result = checkExceptionDestinationAccess(msg,
                                                                                    conn,
                                                                                    alternateUser,
                                                                                    defaultInUse);
  
                              // Handle access denied
                              if (!result.isAllowed())
                              {
                                  // Report and audit the event
                                  handleAccessDenied(result, msg, alternateUser);
  
                                  // Behave as per "BLOCK". This is the same behaviour as things like
                                  // q full, etc. It means, for example, that messages will be backed
                                  // up on transmission queues if they cannot be delivered to either
                                  // target or exception destination.
                                  rc = UndeliverableReturnCode.BLOCK;
                              }
                          }
  
                          // Set the priority in the message based on the exception destinations default
                          msg.setPriority(_exceptionDestination.getDefaultPriority());
  
                          // Get the inputhandler associated with it
                          _inputHandler = _exceptionDestination.getInputHandler(_exceptionDestination.isPubSub() ? ProtocolType.PUBSUBINPUT : ProtocolType.UNICASTINPUT,
                                                                                _messageProcessor.getMessagingEngineUuid(),
                                                                                null);
                      } catch (SIException e)
                      {
                          // No FFDC code needed
  
                          SibTr.exception(tc, e);
  
                          /*
                           * If it was the default exception destination we failed to reference, then exit.
                           * Otherwise retry with the default
                           */
  
                          if (defaultInUse)
                          {
  
                              /*
                               * ERROR : SYSTEM.DEFAULT.EXCEPTION.DESTINATION.<MENAME> queue did
                               * not exist on the ME. This should ALWAYS exist.
                               */
  
                              FFDCFilter.processException(
                                                          e,
                                                          "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                                          "1:1483:1.137",
                                                          this);
  
                              SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0003",
                                          new Object[] {
                                                        "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                                        "1:1489:1.137",
                                                        e,
                                                        _exceptionDestinationName });
  
                              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                                  SibTr.exit(tc, "sendToExceptionDestination", e);
  
                              throw new SIErrorException(e);
                          }
  
                          /* Generate warning but retry with default exception destination */
                          SibTr.warning(tc, "EXCEPTION_DESTINATION_WARNING_CWSIP0291",
                                        new Object[] { _exceptionDestinationName, _messageProcessor.getMessagingEngineName(), e });
  
                          /* Get the default and retry */
                          _exceptionDestinationName = _defaultExceptionDestinationName;
  
                          /* Retry on the default ex.dest. */
                          //Get the named destination from the destination manager
                          try
                          {
                              _exceptionDestination =
                                              _messageProcessor.getDestinationManager().
                                                              getDestination(_exceptionDestinationName, true);
  
                              // Check whether bus security is enabled
                              if (_messageProcessor.isBusSecure())
                              {
                                  // Check authority to access to default exc destination
                                  AccessResult result = checkExceptionDestinationAccess(msg,
                                                                                        conn,
                                                                                        alternateUser,
                                                                                        true);
  
                                  // Handle access denied
                                  if (!result.isAllowed())
                                  {
                                      // Report and audit the event
                                      handleAccessDenied(result, msg, alternateUser);
  
                                      // Behave as per "BLOCK". This is the same behaviour as things like
                                      // q full, etc. It means, for example, that messages will be backed
                                      // up on transmission queues if they cannot be delivered to either
                                      // target or exception destination.
                                      rc = UndeliverableReturnCode.BLOCK;
                                  }
                              }
  
                              // Set the priority in the message based on the exception destinations default
                              msg.setPriority(_exceptionDestination.getDefaultPriority());
  
                              // Get the inputhandler associated with it
                              _inputHandler = _exceptionDestination.getInputHandler(_exceptionDestination.isPubSub() ? ProtocolType.PUBSUBINPUT : ProtocolType.UNICASTINPUT,
                                                                                    _messageProcessor.getMessagingEngineUuid(),
                                                                                    null);
  
                              defaultInUse = true;
                          } catch (SIException e2)
                          {
                              /*
                               * ERROR : SYSTEM.DEFAULT.EXCEPTION.DESTINATION.<MENAME> queue did
                               * not exist on the ME. This should ALWAYS exist.
                               */
  
                              FFDCFilter.processException(
                                                          e2,
                                                          "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                                          "1:1558:1.137",
                                                          this);
  
                              SibTr.exception(tc, e2);
  
                              SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0003",
                                          new Object[] {
                                                        "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                                        "1:1566:1.137",
                                                        e2,
                                                        _exceptionDestinationName });
  
                              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                                  SibTr.exit(tc, "sendToExceptionDestination", e2);
                              throw new SIErrorException(e2);
                          }
                      } // Inputhandler to an exception destination obtained
                  }
  
                  // If the put to the exc dest was not authorized, then this flag will
                  // have been set to BLOCK. Here we throw an exception
                  if (rc == UndeliverableReturnCode.BLOCK)
                  {
                      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                          SibTr.exit(tc, "sendToExceptionDestination", rc);
  
                      throw new SINotAuthorizedException(
                                      nls.getFormattedMessage(
                                                              "EXCEPTION_DESTINATION_AUTH_ERROR_SIMP0314",
                                                              new Object[] { _exceptionDestinationName,
                                                                            msg.getSecurityUserid() },
                                                              null));
                  }
  
                  /*
                   * Send the message using whichever exception destination we have chosen. If it
                   * is unsuccessful and it is not aimed at the default - then get an inputhandler
                   * to the default and retry the send. If a send to the default fails (which will
                   * be on the local ME) then retry every 10 seconds.
                   */
  
                  sendComplete = false;
  
                  while (!sendComplete)
                  {
                      // 533027 We need to create a new MessageItem each time round the loop,
                      // as we could fail at an unexpected point (such as while allocating an
                      // id to the message), and hence leave the MessageItem in an inconsistent state
                      // (such as with callbacks still registered).
                      MessageItem newItem = new MessageItem(msg);
  
                      try
                      {
                          newItem.setStoreAtSendTime(message.isToBeStoredAtSendTime());
  
                          TransactionCommon transaction = null;
                          if (tran == null)
                          {
                              localTran = _exceptionDestination.getTxManager().createLocalTransaction(false);
                              transaction = localTran;
                          }
                          else
                          {
                              transaction = tran;
                          }
  
                          _inputHandler.handleMessage(newItem, transaction, _messageProcessor.getMessagingEngineUuid());
  
                          // Report that the message has been successfully exceptioned.
                          JsMessagingEngine me = _messageProcessor.getMessagingEngine();
                          if (me.isEventNotificationEnabled() ||
                              UserTrace.tc_mt.isDebugEnabled())
                          {
                              String apiMsgId = null;
  
                              if (message.getMessage() instanceof JsApiMessage)
                                  apiMsgId = ((JsApiMessage) message.getMessage()).getApiMessageId();
                              else
                              {
                                  if (message.getMessage().getApiMessageIdAsBytes() != null)
                                      apiMsgId = message.getMessage().getApiMessageIdAsBytes().toString();
                              }
  
                              if (TraceComponent.isAnyTracingEnabled() && UserTrace.tc_mt.isDebugEnabled())
                              {
                                  if (message.getMessage().isApiMessage())
                                      SibTr.debug(UserTrace.tc_mt,
                                                  nls_mt.getFormattedMessage(
                                                                             "MESSAGE_EXCEPTION_DESTINATIONED_CWSJU0012",
                                                                             new Object[] {
                                                                                           apiMsgId,
                                                                                           message.getMessage().getSystemMessageId(),
                                                                                           _exceptionDestinationName,
                                                                                           Integer.valueOf(exceptionReason),
                                                                                           message.getMessage().getExceptionMessage() },
                                                                             null));
                              }
  
                              if (me.isEventNotificationEnabled())
                              {
                                  fireMessageExceptionedEvent(apiMsgId,
                                                              message,
                                                              exceptionReason);
                              }
                          }
  
                          /* Send was successful so exit while loop and return OK */
                          sendComplete = true;
                      } catch (SIException e)
                      {
                          // No FFDC code needed
                          if (!defaultInUse)
                          {
  
                              /* Generate warning but retry with default exception destination */
                              SibTr.warning(tc, "EXCEPTION_DESTINATION_WARNING_CWSIP0291",
                                            new Object[] { _exceptionDestinationName, _messageProcessor.getMessagingEngineName(), e });
  
                              /* Obtain inputhandler to default exception destination and send to this */
                              _exceptionDestinationName = _defaultExceptionDestinationName;
                              try
                              {
                                  _exceptionDestination =
                                                  _messageProcessor.getDestinationManager().
                                                                  getDestination(_exceptionDestinationName, true);
  
                                  // Set the priority in the message based on the exception destinations default
                                  msg.setPriority(_exceptionDestination.getDefaultPriority());
  
                                  // Get the inputhandler associated with it
                                  _inputHandler = _exceptionDestination.getInputHandler(_exceptionDestination.isPubSub() ? ProtocolType.PUBSUBINPUT : ProtocolType.UNICASTINPUT,
                                                                                        _messageProcessor.getMessagingEngineUuid(),
                                                                                        null);
  
                                  defaultInUse = true;
                              } catch (SIException e2)
                              {
                                  FFDCFilter.processException(
                                                              e2,
                                                              "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                                              "1:1702:1.137",
                                                              this);
  
                                  /*
                                   * ERROR : SYSTEM.DEFAULT.EXCEPTION.DESTINATION.<MENAME> queue did
                                   * not exist on the ME. This should ALWAYS exist.
                                   */
  
                                  SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0003",
                                              new Object[] {
                                                            "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                                            "1:1713:1.137",
                                                            e2,
                                                            _exceptionDestinationName });
  
                                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                                      SibTr.exit(tc, "sendToExceptionDestination", e2);
                                  throw new SIErrorException(e2);
                              }
                          }
                          else
                          {
                              if (e instanceof SIMPLimitExceededException)
                              {
                                  // Warning : Default exception destination full
                                  SibTr.warning(tc, "EXCEPTION_DESTINATION_WARNING_CWSIP0291",
                                                new Object[] { _exceptionDestinationName, _messageProcessor.getMessagingEngineName(), e });
  
                                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                                      SibTr.exit(tc, "sendToExceptionDestination", UndeliverableReturnCode.BLOCK);
                                  throw (SIMPLimitExceededException) e;
                              }
                              /*
                               * ERROR : Cannot deliver to local SYSTEM.DEFAULT.EXCEPTION.DESTINATION.
                               */
  
                              FFDCFilter.processException(
                                                          e,
                                                          "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                                          "1:1741:1.137",
                                                          this);
  
                              SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0003",
                                          new Object[] {
                                                        "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl",
                                                        "1:1747:1.137",
                                                        e,
                                                        _exceptionDestinationName });
  
                              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                                  SibTr.exit(tc, "sendToExceptionDestination", e);
                              throw new SIErrorException(e);
  
                          }
                      }
                  }
              } // End of synchronisation
          }
  
          // If report messages required - generate and send here
          if (message.getMessage().getReportException() != null)
          {
              // Create the ReportHandler object if not already created
              if (_reportHandler == null)
                  _reportHandler = new ReportHandler(_messageProcessor);
  
              TransactionCommon transaction;
              if (tran == null)
              {
                  transaction = localTran;
              }
              else
              {
                  transaction = tran;
              }
  
              try
              {
                  _reportHandler.handleMessage(message, transaction, SIApiConstants.REPORT_EXCEPTION);
              } catch (SIException e)
              {
                  /*
                   * ERROR : Cannot send report message
                   */
  
                  FFDCFilter.processException(
                                              e,
                                              "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                              "1:1791:1.137",
                                              this);
  
                  SibTr.error(tc, "EXCEPTION_DESTINATION_ERROR_CWSIP0295",
                              new Object[] { _exceptionDestinationName, _messageProcessor.getMessagingEngineName() });
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      SibTr.exit(tc, "sendToExceptionDestination", e);
                  throw new SIResourceException(e);
              }
          }
  
          if (localTran != null)
          {
              try
              {
                  localTran.commit();
              } catch (SIException e)
              {
                  /*
                   * ERROR : Cannot deliver to local SYSTEM.DEFAULT.EXCEPTION.DESTINATION.
                   */
  
                  FFDCFilter.processException(
                                              e,
                                              "com.ibm.ws.sib.processor.impl.ExceptionDestinationHandlerImpl.sendToExceptionDestination",
                                              "1:1819:1.137",
                                              this);
                  SibTr.error(tc, "INTERNAL_MESSAGING_ERROR_CWSIP0003",
                              new Object[] {
                                            "com.ibm.ws.sib.processor.impl.sendToExceptionDestination",
                                            "1:1824:1.137",
                                            e,
                                            _exceptionDestinationName });
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      SibTr.exit(tc, "sendToExceptionDestination", UndeliverableReturnCode.ERROR);
  
                  throw new SIResourceException(e);
              }
          }
  
          // If we got here then everything worked ok
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.exit(tc, "sendToExceptionDestination");
  
      }