docs: @Override
      public Dispatchable getThreadContext(Conversation conversation, WsByteBuffer data, int segmentType) {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.entry(this, tc, "getThreadContext",
                          new Object[]
                          {
                           conversation,
                           data,
                           "" + segmentType
                          });
  
          Dispatchable dispatchable = null;
          int transactionId = CommsConstants.NO_TRANSACTION;
          int messageOrderId = CommsConstants.NO_ORDER_CONTEXT;
  
          CommsByteBuffer buffer = poolManager.allocate();
          buffer.reset(data);
  
          ConversationState convState = (ConversationState) conversation.getAttachment();
          HandshakeProperties handshakeProperties = conversation.getHandshakeProperties();
  
          // If we are stopping or closing a session or a connection, ensure we dispatch to all the dispatch
          // queues so that it goes behind any other data currently in the queues.
          switch (segmentType) {
              case JFapChannelConstants.SEG_CLOSE_CONSUMER_SESS:
              case JFapChannelConstants.SEG_CLOSE_PRODUCER_SESS:
              case JFapChannelConstants.SEG_CLOSE_CONNECTION:
              case JFapChannelConstants.SEG_CLOSE_ORDER_CONTEXT:
              case JFapChannelConstants.SEG_STOP_SESS:
              case JFapChannelConstants.SEG_UNLOCK_ALL:
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                      SibTr.debug(this, tc, "Processing Session stop, close / Unlock All");
  
                  try {
                      dispatchable = DispatchToAllNonEmptyDispatchable.getInstance();
                  } catch (Exception e) {
                      // We couldn't find the instance of the DispatchToAllNonEmptyDispatchable. This is
                      // probably a classpath or class loader problem locating the class in JFap impl.
                      FFDCFilter.processException(e, CLASS_NAME + ".getThreadContext",
                                                  CommsConstants.SERVERTRANSPORTRECEIVELISTENER_GETTHREAD_01, this);
  
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                          SibTr.debug(this, tc, "Unable to create dispatchable", e);
  
                      throw new SIErrorException(
                                      nls.getFormattedMessage("UNABLE_TO_CREATE_DISPATCH_TO_ALL_SICO2054", null, null),
                                      e);
                  }
          }
  
          if (dispatchable == null) {
              // Now switch on the segment type to obtain the transaction id (if one exists)
              switch (segmentType) {
                  case JFapChannelConstants.SEG_CREATE_UCTRANSACTION:
                      TransactionToDispatchableMap map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                      buffer.getShort(); // Skip the BIT16 ConnectionObjectId
                      int clientTxId = buffer.getInt(); // Get BIT32 Client transaction Id
                      dispatchable = map.addDispatchableForLocalTransaction(clientTxId);
                      break;
  
                  case JFapChannelConstants.SEG_XAOPEN:
                  case JFapChannelConstants.SEG_XARECOVER:
                      dispatchable = null;
                      break;
  
                  case JFapChannelConstants.SEG_XASTART:
                      map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                      int clientXAResourceId = buffer.getInt(); // BIT32 ClientTransactionId
                      Xid xid = buffer.getXid();
                      dispatchable = map.addEnlistedDispatchableForGlobalTransaction(clientXAResourceId,
                                                                                     (XidProxy) xid);
  
                      if (dispatchable == null) {
                          final SIErrorException exception = new SIErrorException(CommsConstants.SERVERTRANSPORTRECEIVELISTENER_GETTHREAD_02);
                          FFDCFilter.processException(exception, CLASS_NAME + ".getThreadContext",
                                                      CommsConstants.SERVERTRANSPORTRECEIVELISTENER_GETTHREAD_02, new Object[] { map, this });
                          if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                              SibTr.exception(this, tc, exception);
                          throw exception;
                      }
                      break;
  
                  case JFapChannelConstants.SEG_XAPREPARE:
                      map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                      clientXAResourceId = buffer.getInt(); // BIT32 ClientTransactionId
                      xid = buffer.getXid();
                      dispatchable = map.getDispatchable(clientXAResourceId);
                      break;
  
                  case JFapChannelConstants.SEG_XACOMMIT:
                  case JFapChannelConstants.SEG_XAROLLBACK:
                  case JFapChannelConstants.SEG_XAFORGET:
                      map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                      clientXAResourceId = buffer.getInt(); // BIT32 ClientTransactionId
                      xid = buffer.getXid();
                      dispatchable = map.removeDispatchableForGlobalTransaction(clientXAResourceId,
                                                                                (XidProxy) xid);
                      break;
  
                  case JFapChannelConstants.SEG_XAEND:
                      map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                      clientXAResourceId = buffer.getInt(); // BIT32 ClientTransactionId
                      xid = buffer.getXid();
                      dispatchable = map.getDispatchable(clientXAResourceId);
                      break;
  
                  case JFapChannelConstants.SEG_XA_GETTXTIMEOUT:
                  case JFapChannelConstants.SEG_XA_SETTXTIMEOUT:
                      map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                      clientXAResourceId = buffer.getInt(); // BIT32 ClientTransactionId
                      dispatchable = map.getDispatchable(clientXAResourceId);
                      break;
  
                  case JFapChannelConstants.SEG_SEND_TO_EXCEPTION_DESTINATION:
                  case JFapChannelConstants.SEG_SEND_CHUNKED_TO_EXCEPTION_DESTINATION:
                  case JFapChannelConstants.SEG_RECEIVE_CONN_MSG:
                  case JFapChannelConstants.SEG_INVOKE_COMMAND_WITH_TX:
                      boolean requiresOptimizedTransactions =
                                      (handshakeProperties.getFapLevel() >= JFapChannelConstants.FAP_VERSION_5) &&
                                                      ((handshakeProperties.getCapabilites() & CommsConstants.CAPABILITIY_REQUIRES_OPTIMIZED_TX) != 0);
                      if (requiresOptimizedTransactions) {
                          map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                          buffer.getShort(); // Skip the BIT16 ConnectionObjectId
                          int txFlags = buffer.getInt(); // Transaction flags
                          buffer.getInt(); // Skip owning conversation Id
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              SibTr.debug(this, tc, "txFlags=" + txFlags);
                          // Examine the transaction flags to determine if this flow is transacted
                          // or not.
                          if ((txFlags & CommsConstants.OPTIMIZED_TX_FLAGS_TRANSACTED_BIT) == 0) {
                              dispatchable = null;
                          } else {
                              // Flow is transacted - obtain transaction ID.
                              transactionId = buffer.getInt(); // BIT32 transaction id
                              if ((txFlags & CommsConstants.OPTIMIZED_TX_FLAGS_CREATE_BIT) != 0) {
                                  // If flags indicate that the transaction should be created by this
                                  // operation - then create a new dispatchable.
                                  if ((txFlags & CommsConstants.OPTIMIZED_TX_FLAGS_LOCAL_BIT) != 0) {
                                      // local transaction
                                      dispatchable = map.addDispatchableForOptimizedLocalTransaction(transactionId);
                                  } else {
                                      // global transaction
                                      if ((txFlags & CommsConstants.OPTIMIZED_TX_END_PREVIOUS_BIT) != 0)
                                          buffer.getInt();
                                      xid = buffer.getXid();
                                      dispatchable = map.addEnlistedDispatchableForGlobalTransaction(transactionId,
                                                                                                     (XidProxy) xid);
                                  }
                              } else {
                                  // Flags do not indicate that we need to create a new transaction
                                  // (and hence allocate a new dispatchable).  Find the existing
                                  // dispatchable.
                                  dispatchable = map.getDispatchable(transactionId);
                              }
                          }
                      } else {
                          // Code for processing non-optimized (version 6) transacted flows.
  
                          buffer.getShort(); // Skip the BIT16 ConnectionObjectId
                          clientXAResourceId = buffer.getInt(); // BIT32 ClientTransactionId
                          if (clientXAResourceId == CommsConstants.NO_TRANSACTION) {
                              dispatchable = null;
                          } else {
                              map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                              dispatchable = map.getDispatchable(clientXAResourceId);
                              if (dispatchable == null) {
                                  final SIErrorException exception = new SIErrorException(CommsConstants.SERVERTRANSPORTRECEIVELISTENER_GETTHREAD_03);
                                  FFDCFilter.processException(exception, CLASS_NAME + ".getThreadContext",
                                                              CommsConstants.SERVERTRANSPORTRECEIVELISTENER_GETTHREAD_03,
                                                              new Object[] { map, this });
                                  if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                                      SibTr.exception(this, tc, exception);
                                  throw exception;
                              }
                          }
                      }
                      break;
  
                  case JFapChannelConstants.SEG_SEND_CONN_MSG:
                  case JFapChannelConstants.SEG_SEND_CONN_MSG_NOREPLY:
                  case JFapChannelConstants.SEG_SEND_SESS_MSG:
                  case JFapChannelConstants.SEG_SEND_SESS_MSG_NOREPLY:
                  case JFapChannelConstants.SEG_RECEIVE_SESS_MSG:
                  case JFapChannelConstants.SEG_DELETE_SET:
                  case JFapChannelConstants.SEG_DELETE_SET_NOREPLY:
                  case JFapChannelConstants.SEG_READ_AND_DELETE_SET:
                  case JFapChannelConstants.SEG_SEND_CHUNKED_SESS_MSG:
                  case JFapChannelConstants.SEG_SEND_CHUNKED_SESS_MSG_NOREPLY:
                  case JFapChannelConstants.SEG_SEND_CHUNKED_CONN_MSG:
                  case JFapChannelConstants.SEG_SEND_CHUNKED_CONN_MSG_NOREPLY:
                      requiresOptimizedTransactions =
                                      (handshakeProperties.getFapLevel() >= JFapChannelConstants.FAP_VERSION_5) &&
                                                      ((handshakeProperties.getCapabilites() & CommsConstants.CAPABILITIY_REQUIRES_OPTIMIZED_TX) != 0);
                      if (requiresOptimizedTransactions) {
                          map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
  //                     data.getShort();                 // Skip the BIT16 ConnectionObjectId
  //                     data.getShort();                 // Skip the BIT16 MOId / Producer Id / Consumer Id
                          buffer.getInt(); // skip both BIT16 ConnectionObjectId and BIT16 MOId/ProducerId/ConsumerId
                          int txFlags = buffer.getInt(); // Transaction flags
                          buffer.getInt(); // Skip "owning" conversation id
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              SibTr.debug(this, tc, "txFlags=" + txFlags);
  
                          // Examine the transaction flags to determine if this flow is transacted
                          // or not.
                          if ((txFlags & CommsConstants.OPTIMIZED_TX_FLAGS_TRANSACTED_BIT) == 0) {
                              dispatchable = null;
                          } else {
                              // Flow is transacted - obtain transaction ID.
                              transactionId = buffer.getInt(); // Get the BIT32 Transaction Id
                              if ((txFlags & CommsConstants.OPTIMIZED_TX_FLAGS_CREATE_BIT) != 0) {
                                  // If flags indicate that the transaction should be created by this
                                  // operation - then create a new dispatchable.
                                  if ((txFlags & CommsConstants.OPTIMIZED_TX_FLAGS_LOCAL_BIT) != 0) {
                                      // local transaction
                                      dispatchable = map.addDispatchableForOptimizedLocalTransaction(transactionId);
                                  } else {
                                      // global transaction
                                      if ((txFlags & CommsConstants.OPTIMIZED_TX_END_PREVIOUS_BIT) != 0)
                                          buffer.getInt();
                                      xid = buffer.getXid();
                                      dispatchable = map.addEnlistedDispatchableForGlobalTransaction(transactionId,
                                                                                                     (XidProxy) xid);
                                  }
                              } else {
                                  // Flags do not indicate that we need to create a new transaction
                                  // (and hence allocate a new dispatchable).  Find the existing
                                  // dispatchable.
                                  dispatchable = map.getDispatchable(transactionId);
                              }
                          }
                      } else {
                          // Code for processing non-optimized (version 6) transacted flows.
  //                     data.getShort();                 // Skip the BIT16 ConnectionObjectId
  //                     data.getShort();                 // Skip the BIT16 MOId / Producer Id / Consumer Id
                          buffer.getInt(); // skip both BIT16 ConnectionObjectId and BIT16 MOId/ProducerId/ConsumerId
                          transactionId = buffer.getInt(); // Get the BIT32 Transaction Id
                          if (transactionId == CommsConstants.NO_TRANSACTION) {
                              dispatchable = null;
                          } else {
                              map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                              dispatchable = map.getDispatchable(transactionId);
  
                              // PK91199 It is possible for our transaction not to be in our map,
                              // if it was joined to transaction owned by a connection that has now been closed.
                              // Throwing a runtime exception here would bring down the whole socket, causing
                              // all conversations to be terminated.
                              // It is better (as is the case in V6.1 with optimized txns) to continue
                              // with a default dispatchable.
                              // If we're in a JFAPSend (rather than a JFAPExchange) this means we silently
                              // swallow the XAER_NOTA exception. However, we will throw that exception
                              // when they later attempt to commit the transaction.
                          }
                      }
                      break;
  
                  case JFapChannelConstants.SEG_COMMIT_TRANSACTION:
                  case JFapChannelConstants.SEG_ROLLBACK_TRANSACTION:
                      buffer.getShort(); // Skip the BIT16 ConnectionObjectId
                      transactionId = buffer.getInt(); // Get the BIT32 Transaction Id
                      if (transactionId == CommsConstants.NO_TRANSACTION) {
                          dispatchable = null;
                      } else {
                          map = ((ServerLinkLevelState) conversation.getLinkLevelAttachment()).getDispatchableMap();
                          dispatchable = map.removeDispatchableForLocalTransaction(transactionId);
                          if (dispatchable == null) {
                              final SIErrorException exception = new SIErrorException(CommsConstants.SERVERTRANSPORTRECEIVELISTENER_GETTHREAD_05);
                              FFDCFilter.processException(exception, CLASS_NAME + ".getThreadContext",
                                                          CommsConstants.SERVERTRANSPORTRECEIVELISTENER_GETTHREAD_05,
                                                          new Object[] { map, this });
                              if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled())
                                  SibTr.exception(this, tc, exception);
                              throw exception;
                          }
                      }
                      break;
              }
  
              // If we found a transaction - use that above all else
              // Otherwise try for a MessageOrderContextId
              if (dispatchable == null) {
                  buffer.rewind();
  
                  switch (segmentType) {
                      case JFapChannelConstants.SEG_SEND_CONN_MSG:
                      case JFapChannelConstants.SEG_SEND_CONN_MSG_NOREPLY:
                      case JFapChannelConstants.SEG_CREATE_PRODUCER_SESS:
                          buffer.getShort(); // Skip the BIT16 ConnectionObjectId
                          messageOrderId = buffer.getShort(); // Get the BIT16 MessageOrderId
                          break;
  
                      case JFapChannelConstants.SEG_REGISTER_ASYNC_CONSUMER:
                          buffer.getShort(); // Skip the BIT16 ConnectionObjectId
                          buffer.getShort(); // Skip the BIT16 ConsumerId
                          messageOrderId = buffer.getShort(); // Get the BIT16 MessageOrderId
                          break;
                  }
  
                  // If we found a message order, use that - otherwise drop out and return null
                  if (messageOrderId != CommsConstants.NO_ORDER_CONTEXT) {
                      dispatchable = (Dispatchable) convState.getObject(messageOrderId);
                  }
              }
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.exit(this, tc, "getThreadContext", dispatchable);
          return dispatchable;
      }