docs: public void associate(CredentialsService credService, WSSecurityService securityService, UnauthenticatedSubjectService unauthSubjService, AuthenticationService authService,
                            WorkContext workCtx, String providerId)
                      throws WorkCompletedException {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.entry(tc, "associate", new Object[] { J2CSecurityHelper.objectId(workCtx), providerId });
          }
          // Check if application security is enabled and only in that case
          // do the security context association.
          if (WSSecurityHelper.isServerSecurityEnabled()) {
              TraceNLS nls = J2CSecurityHelper.getNLS();
              try {
                  UserRegistry registry = securityService.getUserRegistry(null);
                  final String appRealm = registry != null ? registry.getRealm() : null;
                  // The code below extracts the security work context and invokes
                  // setupSecurityContext on it passing in the callback handler and the
                  // execution and server subjects. 
                  SecurityContext sc = (SecurityContext) workCtx;
                  final Subject executionSubject = new Subject();
                  J2CSecurityCallbackHandler handler = new J2CSecurityCallbackHandler(executionSubject, appRealm, credService.getUnauthenticatedUserid()); // Change from twas - jms - Setting to null for now - //cm.getUnauthenticatedString());
  
                  Subject serverSubject = null;
                  sc.setupSecurityContext(handler, executionSubject, serverSubject);
                  SubjectHelper subjectHelper = new SubjectHelper();
                  WSCredential credential = subjectHelper.getWSCredential(executionSubject);
                  // check if the Subject is already authenticated i.e it contains WebSphere credentials.
                  if (credential != null) {
                      if (handler.getInvocations()[0] == Invocation.CALLERPRINCIPALCALLBACK || // Begin 673415
                          handler.getInvocations()[1] == Invocation.GROUPPRINCIPALCALLBACK ||
                          handler.getInvocations()[2] == Invocation.PASSWORDVALIDATIONCALLBACK) {
  
                          String message = nls.getString("AUTHENTICATED_SUBJECT_AND_CALLBACK_NOT_SUPPORTED_J2CA0677",
                                                         "J2CA0677E: " +
                                                                         "An authenticated JAAS Subject and one or more JASPIC callbacks were passed to the application server " +
                                                                         "by the resource adapter."); // End 673415
                          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                              Tr.exit(tc, "associate");
                          }
                          throw new WSSecurityException(message);
                      } else if (appRealm.equals(credential.getRealmName()) || RegistryHelper.isRealmInboundTrusted(credential.getRealmName(), appRealm)) { // Begin 673415 
                          J2CSecurityHelper.setRunAsSubject(executionSubject);
                          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                              Tr.exit(tc, "associate");
                          }
                          return;
                      } else {
                          String message = nls.getFormattedMessage("REALM_IS_NOT_TRUSTED_J2CA0685", new Object[] { null }, "REALM_IS_NOT_TRUSTED_J2CA0685"); // Change from twas - jms - TODO check on this - credential.getRealmName() changed to null
                          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                              Tr.exit(tc, "associate");
                          }
                          throw new WSSecurityException(message);
                      }
                  }
                  // After the invocation of the setupSecurityContext the execution subject will be
                  // populated with the result of handling the callbacks that are passed in to the
                  // handle method of the callback handler. The result is a custom hashtable that can
                  // be used for security to do a hashtable login. The resource adapter can also modify
                  // the execution subject by adding a principal. The code below checks for the result and
                  // if the result is null or empty after the invocation of the callbacks throws an Exception
                  // See JCA 1.6 Spec 16.4.1.
                  Hashtable<String, Object> cred = J2CSecurityHelper.getCustomCredentials(executionSubject, handler.getCacheKey());
                  Set<Principal> principals = executionSubject.getPrincipals(); // 675546
                  if (handler.getInvocations()[0] == Invocation.CALLERPRINCIPALCALLBACK) {
                      if (cred == null || !cred.containsKey(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME)) {
                          String message = nls.getString("CUSTOM_CREDENTIALS_MISSING_J2CA0668",
                                                         "J2CA0668E: The WorkManager was unable to "
                                                                         +
                                                                         "populate the execution subject with the caller principal or credentials necessary to establish the security "
                                                                         +
                                                                         "context for this Work instance.");
                          throw new WSSecurityException(message);
                      }
                  } else if ((handler.getInvocations()[1] == Invocation.GROUPPRINCIPALCALLBACK // Begin 673415
                             || handler.getInvocations()[2] == Invocation.PASSWORDVALIDATIONCALLBACK)
                             && principals.size() != 1) { //675546
                      // If CallerPrincipalCallback was not provided but other callbacks were provided then do not 
                      // allow the security context to be setup. See next comment for the reason
                      String message = nls.getString("CALLERPRINCIPAL_NOT_PROVIDED_J2CA0669",
                                                     "J2CA0669E: The resource adapter " +
                                                                     "did not provide a CallerPrincipalCallback, an execution subject containing a single principal, or an empty " +
                                                                     "execution subject.");
                      throw new WSSecurityException(message);
  
                  } else { // End 673415
                      // As per the JCA 1.6 Spec(16.4.5) the CallerPrincipalCallback should always be called except if the
                      // Resource Adapter wants to establish the UNAUTHENTICATED Identity by passing in an empty
                      // subject or when it passes a single principal in the principal set of the subject in which 
                      // case we handle it like a CallerPrincipalCallback is passed with that principal.
                      if (principals.isEmpty()) {
                          CallerPrincipalCallback cpCallback = new CallerPrincipalCallback(executionSubject, (String) null);
                          handler.handle(new Callback[] { cpCallback });
                      } else if (principals.size() == 1) {
                          CallerPrincipalCallback cpCallback = new CallerPrincipalCallback(executionSubject, principals.iterator().next());
                          executionSubject.getPrincipals().clear(); // 673415
                          handler.handle(new Callback[] { cpCallback });
                      } else {
                          String message = nls.getString("CALLERPRINCIPAL_NOT_PROVIDED_J2CA0669",
                                                         "J2CA0669E: The resource adapter "
                                                                         +
                                                                         "did not provide a CallerPrincipalCallback, an execution subject containing a single principal, or an empty "
                                                                         +
                                                                         "execution subject.");
                          throw new WSSecurityException(message);
                      }
                      // Refresh the cred variable since we are calling the handler here.
                      cred = J2CSecurityHelper.getCustomCredentials(executionSubject, handler.getCacheKey());
                  }
                  // Do a custom hashtable login to get the runAs subject and set it on a ThreadLocal
                  // so that we can retrieve it later in the WorkProxy to establish as the RunAs and Caller
                  // subject.
                  final String userName = (String) cred.get(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME);
                  Subject runAsSubject = null;
                  if (userName.equals(credService.getUnauthenticatedUserid())) {
                      runAsSubject = unauthSubjService.getUnauthenticatedSubject();
                  } else {
                      final AuthenticationService authServ = authService;
                      PrivilegedExceptionAction<Subject> loginAction = new PrivilegedExceptionAction<Subject>() {
                          @Override
                          public Subject run() throws Exception {
                              return authServ.authenticate(JaasLoginConfigConstants.SYSTEM_DEFAULT, executionSubject);
                          }
                      };
                      runAsSubject = AccessController.doPrivileged(loginAction);
                  }
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(tc, "The RunAs subject is created after a successful login.");
                  }
                  J2CSecurityHelper.setRunAsSubject(runAsSubject);
              } catch (RuntimeException e) {
                  Tr.error(tc, "SECURITY_CONTEXT_NOT_ASSOCIATED_J2CA0671", e);
                  String message = nls.getString("SECURITY_CONTEXT_NOT_ASSOCIATED_J2CA0671",
                                                 "J2CA0671E: The WorkManager was unable to associate the inflown SecurityContext to the Work instance.");
                  WorkCompletedException workCompEx = new WorkCompletedException(
                                  message, WorkException.INTERNAL);
                  workCompEx.initCause(e);
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                      Tr.exit(tc, "associate");
                  }
                  throw workCompEx;
              } catch (Exception e) {
                  Tr.error(tc, "SECURITY_CONTEXT_NOT_ASSOCIATED_J2CA0671", e);
                  String message = nls.getString("SECURITY_CONTEXT_NOT_ASSOCIATED_J2CA0671",
                                                 "J2CA0671E: The WorkManager was unable to associate the inflown SecurityContext to the Work instance.");
                  WorkCompletedException workCompEx = new WorkCompletedException(
                                  message, WorkException.INTERNAL);
                  workCompEx.initCause(e);
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                      Tr.exit(tc, "associate");
                  }
                  throw workCompEx;
              }
              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                  Tr.exit(tc, "associate");
              }
          } else {
              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                  Tr.exit(tc, "associate", "Application security is not enabled for the application server.");
              }
          }
      }