class BloombergBpipeApplicationUserIdentityProvider {

  public Identity getIdentity() {

    Session session = _sessionProvider.getSession();
    BloombergConnector bloombergConnector = _sessionProvider.getConnector();

    s_logger.debug("Attempting to authorize application using authentication option: {}", bloombergConnector.getSessionOptions().authenticationOptions());
    try {
      EventQueue tokenEventQueue = new EventQueue();
      session.generateToken(new CorrelationID(), tokenEventQueue);
      String token = null;
      //Generate token responses will come on this dedicated queue. There would be no other messages on that queue.
      Event event = tokenEventQueue.nextEvent(WAIT_TIME_MS);
      if (Event.EventType.TOKEN_STATUS.equals(event.eventType()) || Event.EventType.REQUEST_STATUS.equals(event.eventType())) {
        for (Message msg : event) {
          if (TOKEN_SUCCESS.equals(msg.messageType())) {
            token = msg.getElementAsString(TOKEN_ELEMENT);
          }
          if (TOKEN_FAILURE.equals(msg.messageType())) {
            String description = "";
            Element reasonElem = msg.getElement("reason");
            if (reasonElem != null) {
              description = reasonElem.getElementAsString("description");
            }
            SessionOptions sessionOptions = bloombergConnector.getSessionOptions();
            String message = String.format("Failure to get application token from Host:%s port:%s authentication option:%s reason:%s", 
                sessionOptions.getServerHost(), sessionOptions.getServerPort(), sessionOptions.authenticationOptions(), description);
            throw new UnauthenticatedException(message);
          }
        }
      }
      s_logger.debug("Token: {} generated for application: {}", token, bloombergConnector.getSessionOptions().authenticationOptions());

      Service apiAuthSvc = _sessionProvider.getService(BloombergConstants.AUTH_SVC_NAME);
      Request authRequest = apiAuthSvc.createAuthorizationRequest();
      authRequest.set(TOKEN_ELEMENT, token);

      final Identity appIdentity = session.createIdentity();
      EventQueue authEventQueue = new EventQueue();
      session.sendAuthorizationRequest(authRequest, appIdentity, authEventQueue, new CorrelationID());

      event = authEventQueue.nextEvent(WAIT_TIME_MS);
      if (event.eventType().equals(Event.EventType.RESPONSE) || event.eventType().equals(Event.EventType.REQUEST_STATUS)) {
        for (Message msg : event) {
          if (msg.messageType().equals(AUTHORIZATION_SUCCESS)) {
            s_logger.debug("Application authorization SUCCESS");
            return appIdentity;
          }
        }
      }
    } catch (IOException | InterruptedException ex) {
      throw new UnauthenticatedException(String.format("Bloomberg authorization failed using authentication option: %s", bloombergConnector.getSessionOptions().authenticationOptions()));
    }
    throw new UnauthenticatedException(String.format("Bloomberg authorization failed using authentication option: %s", bloombergConnector.getSessionOptions().authenticationOptions()));
  }

  public  BloombergBpipeApplicationUserIdentityProvider(SessionProvider sessionProvider);

}