docs: @Override
      public MessageEndpoint createEndpoint(XAResource xaResource, long timeout) throws UnavailableException
      {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
          {
              Tr.entry(tc, "MEF.createEndpoint for enterprise class " + beanMetaData.enterpriseBeanName);
          }
  
          boolean recoverableXAResource = false;
          // d197017 begins
          // Make sure endpoint is activated before proceeding.
          Object proxy = null;
          MessageEndpointBase endpoint = null;
          boolean newInstanceRequired = false; //LI2110.56
          synchronized (ivStateLock)
          {
              // If RRS then xaResource passed in may be null. We need to enlist the RRS XAResource and not the XAResource passed in by the
              // RA. So in that case we need to check for the recoveryId
              if (xaResource != null || ivRRSTransactional) //d197017
              {
                  // Ensure setRecoveryID method is called prior to this method since
                  // recovery ID is needed to enlist the XAResource with the
                  // transaction service during beforeDelivery.
                  if ((ivRecoveryIdKnown == false) || (ivRecoveryId == 0)) //d194602
                  {
                      if (ivEnlistNotNeeded == false)
                      {
                          if (RecoverableXAResourceAccessor.isRecoverableXAResource(xaResource)) //d197017
                          {
                              recoverableXAResource = true;
                          }
                          else
                          {
                              // CNTR0082E: Can not enlist XAResource since recovery ID for
                              // resource adapter {0} for MDB {1} is not known.
                              Tr.error(tc, "ENDPOINT_RECOVERY_ID_UNKNOWN_CNTR0082E",
                                       ivRAKey, beanMetaData.j2eeName);
                              throw new UnavailableException("setRecoveryId must be called prior to createEndpoint");
                          }
                      }
                  }
              }
  
              if (ivState == ACTIVE_STATE)
              {
                  if (!isEndpointActive()) //d450478
                  {
                      // This can happen when RALifeCycleManager forcefully deactivates an
                      // endpoint during an RA stop operation. See the
                      // messageEndpointForcefullyDeactivated method in this class.
                      throw new UnavailableException("endpoint needs to be activated.");
                  }
  
                  // Use pool only if one was created.
                  if (ivInvocationHandlerPool != null) // d423445.1
                  {
                      // LI2110.56 start of change.
                      // Endpoint is active, so proceed with creating the endpoint.
                      // First see if one is available in the free pool.
                      endpoint = (MessageEndpointBase) ivInvocationHandlerPool.get();
                      if (endpoint == null)
                      {
                          // Free pool empty, so check whether it okay to create a new one.
                          // f743-7046 start
                          if (ivNumberOfMessageEndpointsCreated < ivMaxCreation) //LI2110.56
                          {
                              // Limit was NOT reached, so just increment count of created endpoints.
                              ++ivNumberOfMessageEndpointsCreated;
                              newInstanceRequired = true;
                          }
                          else
                          {
                              // Max creation limit reached. Was a valid wait timeout value provided?
                              if (timeout <= 0)
                              {
                                  if (majorJCAVersion == 1 && minorJCAVersion == 5)
                                  {
                                      // JCA 1.5 RA does not provide a timeout value, so throw same exceptions
                                      // we have always thrown in past to ensure same behavior.  //PM16610
                                      throw new UnavailableException("limit for number of MessageEndpoint proxies reached. Limit = " + ivMaxCreation);
                                  }
                                  else
                                  {
                                      // JCA 1.6 or later RA did not provide a valid wait timeout value, so throw the
                                      // retryable exception immediately.  //PM16610
                                      throw new RetryableUnavailableException("limit for number of MessageEndpoint proxies reached.  Limit = " + ivMaxCreation);
                                  }
                              }
                              else
                              {
                                  // A valid wait timeout value was provided, so it must be JCA 1.6 or later.
                                  // Wait for some thread to call MessageEndpoint.release() method. When that happens
                                  // the returnInvocationHandler method in this class is called and it will notify this
                                  // thread that it can proceed with the create.
                                  try
                                  {
                                      ivStateLock.wait(timeout);
                                  } catch (InterruptedException e)
                                  {
                                      //FFDCFilter.processException(e, CLASS_NAME + ".createEndpoint", "519", this);
                                  }
  
                                  // Determine whether wait timeout or release occurred. If release occurred,
                                  // then a handler will be retrieved from the pool.
                                  endpoint = (MessageEndpointBase) ivInvocationHandlerPool.get();
                                  if (endpoint == null)
                                  {
                                      // Timed out waiting for a proxy to be released.
                                      throw new RetryableUnavailableException("timed out waiting for a MessageEndpoint proxy to become available.");
                                  }
                                  else
                                  {
                                      // A MessageEndpoint proxy is now available. Ensure deactivate did not
                                      // occur while waiting for a MessageEndpoint to be released.
                                      if (ivState == ACTIVE_STATE)
                                      {
                                          // Still active and there is at least 1 MessageEndpoint proxy available.
                                          // handler was retrieved from the pool.  No need to create a new one.
                                          newInstanceRequired = false;
                                      }
                                      else if ((ivState == DEACTIVATING_STATE) || (ivState == DEACTIVATE_PENDING_STATE)) //d450478
                                      {
                                          throw new UnavailableException("deactivate of endpoint is in progress.");
                                      }
                                      else
                                      {
                                          throw new UnavailableException("endpoint needs to be activated.");
                                      }
                                  }
                              }
                          } // f743-7046 end of change.
                      } // LI2110.56 end of change.
                  }
              }
              else if (ivState == ACTIVATING_STATE)
              {
                  // Endpoint is activating, so check if calling thread is the activating thread.
                  if (ivActivatingThread == Thread.currentThread())
                  {
                      // Calling thread is the activating thread, so throw
                      // exception since we can not block the activating thread and
                      // it is not retryable from this thread.
                      throw new UnavailableException("activating thread not allowed to create endpoint during activation.");
                  }
                  else
                  {
                      // Not the activation thread, so block this thread until the activate completes.
                      try
                      {
                          if (timeout > 0) // f743-7046 start
                          {
                              ivStateLock.wait(timeout);
                          }
                          else
                          {
                              ivStateLock.wait();
                          } // f743-7046 end
                      } catch (InterruptedException i)
                      {
                          //FFDCFilter.processException(e, CLASS_NAME + ".createEndpoint", "406", this);
                      }
  
                      // Now verify activate was successful.
                      if (ivState != ACTIVE_STATE)
                      {
                          if (ivState == ACTIVATING_STATE) // f743-7046 start
                          {
                              // This can only happen if a JCA 1.6 or later RA provided a timeout value.
                              // So throw the retryable exception immediately.
                              throw new RetryableUnavailableException("timed out while waiting for activation to complete.");
                          }
                          else
                          {
                              // Neither in active nor activating state, so a deactivate must have occurred.
                              // This is not a transient condition, so throw non retryable exception.
                              throw new UnavailableException("endpoint needs to be activated.");
                          } // f743-7046 end
                      }
                  }
              }
              else if ((ivState == DEACTIVATING_STATE) || (ivState == DEACTIVATE_PENDING_STATE)) //d450478
              {
                  throw new UnavailableException("deactivate of endpoint is in progress.");
              }
              else
              {
                  throw new UnavailableException("endpoint needs to be activated.");
              }
          }
          // d197017 ends
  
          // Create MessageEndpoint Proxy object using the Constructor Method that
          // was cached by the initialize method of this object.
          UnavailableException ex = null;
          try
          {
              // Was above code able to get a MessageEndpointHandler
              // from the free pool?
              if (endpoint != null)
              {
                  // Yes, so get proxy object from the MessageEndpointHandler
                  // object obtained from free pool.
                  proxy = endpoint.ivProxy;
              }
              else
              {
                  // Nope, so free pool must have been empty.  Since we got this
                  // far, we know creation counter was incremented and newInstanceRequired
                  // flag should have been set by above code.  So go ahead and try
                  // to create a new instance.  Exception handler code below will decrement
                  // counter if something goes wrong in the creation.
                  proxy = beanMetaData.localImplClass.newInstance();
  
                  // For no-method interface MDB, the 'proxy' will not
                  // subclass MessageEndpointBase, but the MDB itself, so a separate
                  // MessageEndpointBase must be created to hold the metadata and
                  // associated with the real proxy.
                  if (beanMetaData.ivIsNoMethodInterfaceMDB)
                  {
                      endpoint = new MessageEndpointBase();
                      // Set the ivMessageEndpointBase on the generated proxy.
                      beanMetaData.ivMessageEndpointBaseField.set(proxy, endpoint);
                  }
                  // Otherwise, normal proxy - subclasses MessageEndpointBase
                  else
                  {
                      endpoint = (MessageEndpointBase) proxy;
                  }
  
                  MessageEndpointBase.construct(this,
                                                endpoint,
                                                ivRecoveryId,
                                                container,
                                                beanMetaData,
                                                pmiBean,
                                                wrapperManager,
                                                ivRRSTransactional);
                  endpoint.ivProxy = proxy;
              }
  
              // Initialize InvocationHandler to be owner of this
              // proxy object and XAResource and determine if enlistment
              // of a XAResource is needed.
              if (ivEnlistNotNeeded)
              {
                  if (xaResource == null)
                  {
                      // Enlistment is not needed and no XAResource
                      // was passed by RA.  So everything is fine.
                      MessageEndpointBase.initialize(endpoint, null, false, majorJCAVersion, minorJCAVersion); // f743-7046
                  }
                  else
                  {
                      // Enlistment is not needed, but the RA did pass an XAResource object.
                      // We need to throw an exception since transaction recovery setup was
                      // not completed successfully for this RA.
                      ex = mapAndLogTranEnlistmentNotNeeded();
                  }
              }
              else
              {
                  // Transaction recovery is setup for this RA, so
                  // use whatever the RA passed as an XAResource.
                  MessageEndpointBase.initialize(endpoint, xaResource, recoverableXAResource, majorJCAVersion, minorJCAVersion); // f743-7046
              }
          } catch (Throwable t)
          {
              // CNTR0083E: Creation of a message endpoint failed: \n {0}
              Tr.error(tc, "CREATE_ENDPOINT_FAILED_CNTR0083E", t);
              ex = new UnavailableException("Creation of MessageEndpoint Proxy failed", t);
          }
  
          // Check whether exception needs to be thrown.
          // If so, return invocation handler to pool if necessary
          // and throw the exception.
          if (ex != null)
          {
              // Use pool only if one was created.
              if (ivInvocationHandlerPool != null) // d423445.1
              {
                  // Since proxy not being returned to caller,
                  // Return InvocationHandler to the pool if both MessageEndpointHandler
                  // and proxy object was created prior to the exception.
                  if (endpoint != null && proxy != null) // LI2110.56
                  {
                      MessageEndpointBase.reset(endpoint); // F73236 PooledObject removed, call reset() directly
                      ivInvocationHandlerPool.put(endpoint);
                  }
                  else
                  {
                      // LI2110.56 beginning of change.
                      // Decrement creation counter so that it is not off by 1 as
                      // a result of a failure during creation of either MessageEndpointHandler
                      // or the proxy object itself (e.g. out of memory exception).
                      if (newInstanceRequired)
                      {
                          synchronized (ivStateLock)
                          {
                              --ivNumberOfMessageEndpointsCreated;
                          }
                      } // LI2110.56 end of change.
                  }
              }
  
              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              {
                  BeanMetaData bmd = super.beanMetaData;
                  Tr.exit(tc, "createEndpoint for enterprise class " + bmd.enterpriseBeanName + " failed.");
              }
  
              // Now throw the UnavailableException
              throw ex;
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
          {
              Tr.exit(tc, "MEF.createEndpoint for enterprise class " + beanMetaData.enterpriseBeanName);
          }
  
          return (MessageEndpoint) proxy;
      }