docs: @Override
      public JmsJcaConnection createConnection(final String userName,
                                               final String password) throws ResourceException, SIException,
                      SIErrorException {
  
          if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
              SibTr.entry(this, TRACE, "createConnection", new Object[] {
                                                                         userName, "*****" });
          }
  
          JmsJcaConnection connection = null;
  
          JmsJcaConnectionRequestInfo requestInfo = new JmsJcaConnectionRequestInfo(userName, password);
  
          try {
  
              if (_managed) {
  
                  /*
                   * In a managed environment obtain a managed connection
                   */
  
                  Object object = null;
                  boolean tryAgain = true;
  
                  do
                  {
  
                      // Try and allocate a connection.
                      object = _connectionManager.allocateConnection(
                                                                     _managedConnectionFactory, requestInfo);
  
                      // Ensure that we have a session of the right type.
                      if (object instanceof JmsJcaSessionImpl) {
  
                          // Get the core connection from the managed connection
                          SICoreConnection coreConnection = ((JmsJcaSessionImpl) object).getManagedConnection().getCoreConnection();
  
                          // PM21176 (PM07867) It is very important that the connection request info structure
                          // has a reference to a core connection, that is connected to the same
                          // ME as our saved core connection. If a new connection was created as part of
                          // allocateConnection then this will already be the case.
                          // However, if an existing connection was re-used from the pool, no
                          // connection will have been set on the connection request info, and
                          // JCA sessions created from this JCA connection might end up connecting
                          // to different messaging engines, preventing transaction completion.
                          if (requestInfo.getSICoreConnection() == null) {
                              requestInfo.setSICoreConnection(coreConnection);
                          }
  
                          SICoreConnection clonedCoreConnection = null;
  
                          // Clone the managed connection owned core connection for use by the connection
                          // object which we will return to JCA. Previous connection failures will only
                          // become apparent here so we catch any cloning exception and handle it as a
                          // connection failure on the managed connection.
  
                          Exception clonedException = null;
                          if (coreConnection != null) {
                              try {
                                  clonedCoreConnection = coreConnection.cloneConnection();
                              } catch (SIException e) {
                                  // No FFDC code needed
                                  if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled())
                                      SibTr.debug(TRACE, "Clone connection failed");
                                  JmsJcaManagedConnection mc = ((JmsJcaSessionImpl) object).getManagedConnection();
                                  mc.connectionErrorOccurred(e, true); // Inform JCA of connection failure on this Managed Connection
                                  clonedException = e;
                              } catch (SIErrorException e) {
                                  // No FFDC code needed
                                  if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled())
                                      SibTr.debug(TRACE, "Clone connection failed");
                                  JmsJcaManagedConnection mc = ((JmsJcaSessionImpl) object).getManagedConnection();
                                  mc.connectionErrorOccurred(e, true); // Inform JCA of connection failure on this Managed Connection
                                  clonedException = e;
                              }
                          }
  
                          if (clonedCoreConnection != null) {
                              connection = new JmsJcaConnectionImpl(this, clonedCoreConnection, (JmsJcaSessionImpl) object, requestInfo);
                          }
  
                          tryAgain = (clonedCoreConnection == null);
  
                          if (tryAgain)
                          {
                              SibTr.info(TRACE, NLS.getFormattedMessage(("CONNECTION_ERROR_RETRY_CWSJR1067"),
                                                                        new Object[] { clonedException }, null));
  
                              // We need to try again so we clone and change the cri (incremenet counter) which 
                              // forces j2c to create a new managed connection.  Cloning is needed to prevent
                              // a broken connection in the shared pool being returned because it has a
                              // cri == this cri (PM31826)
                              requestInfo = (JmsJcaConnectionRequestInfo) requestInfo.clone();
                              requestInfo.incrementRequestCounter();
                          }
  
                      } else {
  
                          throw new ResourceAdapterInternalException(
                                          NLS
                                                          .getFormattedMessage(
                                                                               ("EXCEPTION_RECEIVED_CWSJR1061"),
                                                                               new Object[] {
                                                                                             "createConnection",
                                                                                             JmsJcaSessionImpl.class
                                                                                                             .getName(),
                                                                                             object.getClass().getName() },
                                                                               null));
  
                      }
  
                  } while (tryAgain);
  
              } else {
  
                  /*
                   * Non-managed
                   */
  
                  final SICoreConnection coreConnection = createCoreConnection(
                                                                               userName, password);
  
                  // Now we have enough info to create a connection we should go
                  // ahead and create one.
                  connection = new JmsJcaConnectionImpl(this, coreConnection, requestInfo);
  
              }
  
          } catch (final ResourceException exception) {
  
              FFDCFilter.processException(exception, CLASS_NAME
                                                     + "createConnection", FFDC_PROBE_3, this);
              Throwable cause = exception.getCause();
  
              if (cause instanceof SIAuthenticationException)
              {
                  throw new SIAuthenticationException(NLS.getFormattedMessage("APPLICATION_AUTHENTICATION_EXCEPTION_1072",
                                                                              new Object[] { userName }, null));
              }
              else if (cause instanceof SIException)
              {
                  throw (SIException) cause;
              }
              else if (cause instanceof SIErrorException)
              {
                  throw (SIErrorException) cause;
              }
  
              throw exception;
          }
  
          if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
              SibTr.exit(this, TRACE, "createConnection", connection);
          }
          return connection;
  
      }