/**
   * Look up for the given destination
   *
   * @param replyDest the JNDI name to lookup Destination required
   * @return Destination for the JNDI name passed
   */
  public Destination getReplyDestination(String replyDest) {
    if (log.isDebugEnabled()) {
      log.debug("Lookup the JMS destination " + replyDest + " of type " + replyDestinationType);
    }

    try {
      return JMSUtils.lookupDestination(
          jmsConnectionFactory.getContext(), replyDest, replyDestinationType);
    } catch (NamingException e) {
      handleException(
          "Couldn't locate the JMS destination " + replyDest + " of type " + replyDestinationType,
          e);
    }

    // never executes but keeps the compiler happy
    return null;
  }
  /**
   * Create a one time MessageProducer for this JMS OutTransport information. For simplicity and
   * best compatibility, this method uses only JMS 1.0.2b API. Please be cautious when making any
   * changes
   *
   * @return a JMSSender based on one-time use resources
   * @throws JMSException on errors, to be handled and logged by the caller
   */
  public JMSMessageSender createJMSSender(MessageContext msgCtx) throws JMSException {

    // digest the targetAddress and locate CF from the EPR
    loadConnectionFactoryFromProperties();

    // create a one time connection and session to be used
    String user = properties != null ? properties.get(JMSConstants.PARAM_JMS_USERNAME) : null;
    String pass = properties != null ? properties.get(JMSConstants.PARAM_JMS_PASSWORD) : null;

    QueueConnectionFactory qConFac = null;
    TopicConnectionFactory tConFac = null;

    int destType = -1;
    // TODO: there is something missing here for destination type generic
    if (JMSConstants.DESTINATION_TYPE_QUEUE.equals(destinationType)) {
      destType = JMSConstants.QUEUE;
      qConFac = (QueueConnectionFactory) connectionFactory;

    } else if (JMSConstants.DESTINATION_TYPE_TOPIC.equals(destinationType)) {
      destType = JMSConstants.TOPIC;
      tConFac = (TopicConnectionFactory) connectionFactory;
    } else {
      // treat jmsdestination type=queue(default is queue)
      destType = JMSConstants.QUEUE;
      qConFac = (QueueConnectionFactory) connectionFactory;
    }

    if (msgCtx.getProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER) != null) {
      XAConnection connection = null;
      if (user != null && pass != null) {
        if (qConFac != null) {
          connection = ((XAConnectionFactory) qConFac).createXAConnection(user, pass);
        } else if (tConFac != null) {
          connection = ((XAConnectionFactory) tConFac).createXAConnection(user, pass);
        }
      } else {
        if (qConFac != null) {
          connection = ((XAConnectionFactory) qConFac).createXAConnection();
        } else if (tConFac != null) {
          connection = ((XAConnectionFactory) tConFac).createXAConnection();
        }
      }

      if (connection == null) {
        connection = ((XAConnectionFactory) qConFac).createXAConnection();
      }

      XASession session = null;
      MessageProducer producer = null;

      if (connection != null) {
        if (destType == JMSConstants.QUEUE) {
          session = connection.createXASession();
          producer = session.createProducer(destination);
        } else {
          session = connection.createXASession();
          producer = session.createProducer(destination);
        }
      }

      XAResource xaResource = session.getXAResource();
      TransactionManager tx = null;
      Xid xid1 = null;
      Transaction transaction = null;
      java.util.UUID uuid = java.util.UUID.randomUUID();

      try {
        tx = (TransactionManager) msgCtx.getProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER);
        transaction = tx.getTransaction();
        msgCtx.setProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER, tx);
        msgCtx.setProperty(JMSConstants.JMS_XA_TRANSACTION, transaction);
        xid1 =
            new JMSXid(
                JMSConstants.JMS_XA_TRANSACTION_PREFIX.getBytes(StandardCharsets.UTF_8),
                1,
                uuid.toString().getBytes());
        msgCtx.setProperty("XID", xid1);
        xaResource.start(xid1, XAResource.TMNOFLAGS);
      } catch (SystemException e) {
        handleException("Error Occurred during starting getting Transaction.", e);
      } catch (XAException e) {
        handleException("Error Occurred during starting XA resource.", e);
      }
      return new JMSMessageSender(
          connection,
          session,
          producer,
          destination,
          jmsConnectionFactory == null ? this.cacheLevel : jmsConnectionFactory.getCacheLevel(),
          jmsSpecVersion,
          destType == -1 ? null : destType == JMSConstants.QUEUE ? Boolean.TRUE : Boolean.FALSE,
          transaction,
          xid1,
          xaResource);
    } else {
      Connection connection = null;
      if (user != null && pass != null) {
        if (qConFac != null) {
          connection = qConFac.createQueueConnection(user, pass);
        } else if (tConFac != null) {
          connection = tConFac.createTopicConnection(user, pass);
        }
      } else {
        if (qConFac != null) {
          connection = qConFac.createQueueConnection();
        } else if (tConFac != null) {
          connection = tConFac.createTopicConnection();
        }
      }

      if (connection == null) {
        connection = jmsConnectionFactory != null ? jmsConnectionFactory.getConnection() : null;
      }

      Session session = null;
      MessageProducer producer = null;

      if (connection != null) {
        if (destType == JMSConstants.QUEUE) {
          session =
              ((QueueConnection) connection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
          producer = ((QueueSession) session).createSender((Queue) destination);
        } else {
          session =
              ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
          producer = ((TopicSession) session).createPublisher((Topic) destination);
        }
      }
      return new JMSMessageSender(
          connection,
          session,
          producer,
          destination,
          jmsConnectionFactory == null ? this.cacheLevel : jmsConnectionFactory.getCacheLevel(),
          jmsSpecVersion,
          destType == -1 ? null : destType == JMSConstants.QUEUE ? Boolean.TRUE : Boolean.FALSE);
    }
  }