@Override
  public Promise<ResourceResponse, ResourceException> createInstance(
      Context context, CreateRequest request) {
    TokenGenerationServiceInvocationState invocationState;
    try {
      invocationState = TokenGenerationServiceInvocationState.fromJson(request.getContent());
    } catch (Exception e) {
      logger.error(
          "Exception caught marshalling json into TokenGenerationServiceInvocationState instance: "
              + e);
      return new BadRequestException(e.getMessage(), e).asPromise();
    }
    SSOToken subjectToken;
    try {
      subjectToken = validateAssertionSubjectSession(invocationState);
    } catch (ForbiddenException e) {
      return e.asPromise();
    }

    STSInstanceState stsInstanceState;
    try {
      stsInstanceState = getSTSInstanceState(invocationState);
    } catch (ResourceException e) {
      return e.asPromise();
    }

    if (TokenType.SAML2.equals(invocationState.getTokenType())) {
      try {
        final String assertion =
            saml2TokenGeneration.generate(subjectToken, stsInstanceState, invocationState);
        return newResultPromise(issuedTokenResource(assertion));
      } catch (TokenCreationException e) {
        logger.error("Exception caught generating saml2 token: " + e, e);
        return e.asPromise();
      } catch (Exception e) {
        logger.error("Exception caught generating saml2 token: " + e, e);
        return new InternalServerErrorException(e.toString(), e).asPromise();
      }
    } else if (TokenType.OPENIDCONNECT.equals(invocationState.getTokenType())) {
      try {
        final String assertion =
            openIdConnectTokenGeneration.generate(subjectToken, stsInstanceState, invocationState);
        return newResultPromise(issuedTokenResource(assertion));
      } catch (TokenCreationException e) {
        logger.error("Exception caught generating OpenIdConnect token: " + e, e);
        return e.asPromise();
      } catch (Exception e) {
        logger.error("Exception caught generating OpenIdConnect token: " + e, e);
        return new InternalServerErrorException(e.toString(), e).asPromise();
      }
    } else {
      String message = "Bad request: unexpected token type:" + invocationState.getTokenType();
      logger.error(message);
      return new BadRequestException(message).asPromise();
    }
  }
  @SuppressWarnings("unchecked")
  public TokenTransform<?, ? extends TokenTypeId> buildTokenTransform(
      TokenTransformConfig tokenTransformConfig) throws STSInitializationException {
    TokenTypeId inputTokenType = tokenTransformConfig.getInputTokenType();
    TokenTypeId outputTokenType = tokenTransformConfig.getOutputTokenType();
    RestTokenTransformValidator<?> tokenValidator;
    if (TokenType.USERNAME.getId().equals(inputTokenType.getId())) {
      tokenValidator =
          buildUsernameTokenValidator(tokenTransformConfig.invalidateInterimOpenAMSession());
    } else if (TokenType.OPENAM.getId().equals(inputTokenType.getId())) {
      tokenValidator =
          buildOpenAMTokenValidator(tokenTransformConfig.invalidateInterimOpenAMSession());
    } else if (TokenType.OPENIDCONNECT.getId().equals(inputTokenType.getId())) {
      tokenValidator =
          buildOpenIdConnectValidator(tokenTransformConfig.invalidateInterimOpenAMSession());
    } else if (TokenType.X509.getId().equals(inputTokenType.getId())) {
      tokenValidator =
          buildX509TokenValidator(tokenTransformConfig.invalidateInterimOpenAMSession());
    } else {
      tokenValidator =
          buildCustomTokenValidator(
              inputTokenType,
              ValidationInvocationContext.REST_TOKEN_TRANSFORMATION,
              tokenTransformConfig.invalidateInterimOpenAMSession());
    }

    RestTokenProvider<?> tokenProvider;
    if (TokenType.SAML2.getId().equals(outputTokenType.getId())) {
      tokenProvider = buildOpenSAMLTokenProvider();
    } else if (TokenType.OPENIDCONNECT.getId().equals(outputTokenType.getId())) {
      tokenProvider = buildOpenIdConnectTokenProvider();
    } else {
      tokenProvider = buildCustomTokenProvider(outputTokenType);
    }
    return new TokenTransformImpl(tokenValidator, tokenProvider, inputTokenType, outputTokenType);
  }