@POST
  @Path("authorize")
  @Produces(MediaType.TEXT_HTML)
  public Viewable handleAuthorizeForm(
      @Context UriInfo ui,
      @FormParam("response_type") String response_type,
      @FormParam("client_id") String client_id,
      @FormParam("redirect_uri") String redirect_uri,
      @FormParam("scope") String scope,
      @FormParam("state") String state,
      @FormParam("username") String username,
      @FormParam("password") String password) {

    try {
      responseType = response_type;
      clientId = client_id;
      redirectUri = redirect_uri;
      this.scope = scope;
      this.state = state;

      User user = null;
      String errorDescription = "Username or password do not match";
      try {
        user =
            management.verifyAppUserPasswordCredentials(
                services.getApplicationId(), username, password);
      } catch (UnactivatedAdminUserException uaue) {
        errorDescription = "user not activated";
      } catch (DisabledAdminUserException daue) {
        errorDescription = "user disabled";
      } catch (Exception e1) {
      }
      if ((user != null) && isNotBlank(redirect_uri)) {
        if (!redirect_uri.contains("?")) {
          redirect_uri += "?";
        } else {
          redirect_uri += "&";
        }
        redirect_uri +=
            "code="
                + management.getAccessTokenForAppUser(
                    services.getApplicationId(), user.getUuid(), 0);
        if (isNotBlank(state)) {
          redirect_uri += "&state=" + URLEncoder.encode(state, "UTF-8");
        }
        throw new RedirectionException(state);
      } else {
        errorMsg = errorDescription;
      }

      ApplicationInfo app = management.getApplicationInfo(applicationId);
      applicationName = app.getName();

      return handleViewable("authorize_form", this);
    } catch (RedirectionException e) {
      throw e;
    } catch (Exception e) {
      return handleViewable("error", e);
    }
  }
  @GET
  @Path("foursquare")
  public Response authFQ(
      @Context UriInfo ui,
      @QueryParam("fq_access_token") String fq_access_token,
      @QueryParam("ttl") long ttl,
      @QueryParam("callback") @DefaultValue("") String callback)
      throws Exception {

    logger.info("AuthResource.authFQ");

    try {
      if (StringUtils.isEmpty(fq_access_token)) {
        return missingTokenFail(callback);
      }
      SignInAsProvider foursquareProvider =
          signInProviderFactory.foursquare(services.getApplication());
      User user = foursquareProvider.createOrAuthenticate(fq_access_token);

      if (user == null) {
        return findAndCreateFail(callback);
      }

      String token =
          management.getAccessTokenForAppUser(services.getApplicationId(), user.getUuid(), ttl);

      AccessInfo access_info =
          new AccessInfo()
              .withExpiresIn(tokens.getMaxTokenAge(token) / 1000)
              .withAccessToken(token)
              .withProperty("user", user);

      return Response.status(SC_OK)
          .type(jsonMediaType(callback))
          .entity(wrapWithCallback(access_info, callback))
          .build();
    } catch (Exception e) {
      return generalAuthError(callback, e);
    }
  }
  @Test
  public void runtimeTypeCorrect() throws Exception {

    UUID applicationId = createApplication("testOrganization", "runtimeTypeCorrect");
    assertNotNull(applicationId);

    EntityManager em = emf.getEntityManager(applicationId);
    assertNotNull(em);

    int size = 20;
    List<User> createdEntities = new ArrayList<User>();

    for (int i = 0; i < size; i++) {
      User user = new User();
      user.setEmail(String.format("*****@*****.**", i));
      user.setUsername(String.format("test%d", i));
      user.setName(String.format("test%d", i));

      User created = em.create(user);

      createdEntities.add(created);
    }

    Results r =
        em.getCollection(em.getApplicationRef(), "users", null, 50, Level.ALL_PROPERTIES, false);

    logger.info(JsonUtils.mapToFormattedJsonString(r.getEntities()));

    assertEquals(size, r.size());

    // check they're all the same before deletion
    for (int i = 0; i < size; i++) {
      assertEquals(createdEntities.get(i).getUuid(), r.getEntities().get(i).getUuid());
      assertTrue(r.getEntities().get(i) instanceof User);
    }
  }
  @GET
  @Path("token")
  public Response getAccessToken(
      @Context UriInfo ui,
      @HeaderParam("Authorization") String authorization,
      @QueryParam("grant_type") String grant_type,
      @QueryParam("username") String username,
      @QueryParam("password") String password,
      @QueryParam("pin") String pin,
      @QueryParam("client_id") String client_id,
      @QueryParam("client_secret") String client_secret,
      @QueryParam("code") String code,
      @QueryParam("ttl") long ttl,
      @QueryParam("redirect_uri") String redirect_uri,
      @QueryParam("callback") @DefaultValue("") String callback)
      throws Exception {

    logger.debug("ApplicationResource.getAccessToken");

    User user = null;

    try {

      if (authorization != null) {
        String type = stringOrSubstringBeforeFirst(authorization, ' ').toUpperCase();
        if ("BASIC".equals(type)) {
          String token = stringOrSubstringAfterFirst(authorization, ' ');
          String[] values = Base64.decodeToString(token).split(":");
          if (values.length >= 2) {
            client_id = values[0].toLowerCase();
            client_secret = values[1];
          }
        }
      }

      // do checking for different grant types
      String errorDescription = "invalid username or password";
      if (GrantType.PASSWORD.toString().equals(grant_type)) {
        try {
          user =
              management.verifyAppUserPasswordCredentials(
                  services.getApplicationId(), username, password);
        } catch (UnactivatedAppUserException uaue) {
          errorDescription = "user not activated";
        } catch (DisabledAppUserException daue) {
          errorDescription = "user disabled";
        } catch (Exception e1) {
        }
      } else if ("pin".equals(grant_type)) {
        try {
          user = management.verifyAppUserPinCredentials(services.getApplicationId(), username, pin);
        } catch (Exception e1) {
        }
      } else if ("client_credentials".equals(grant_type)) {
        try {
          AccessInfo access_info = management.authorizeClient(client_id, client_secret, ttl);
          if (access_info != null) {
            return Response.status(SC_OK)
                .type(jsonMediaType(callback))
                .entity(wrapWithCallback(access_info, callback))
                .build();
          }
        } catch (Exception e1) {
        }
      } else if ("authorization_code".equals(grant_type)) {
        AccessInfo access_info = new AccessInfo();
        access_info.setAccessToken(code);
        return Response.status(SC_OK)
            .type(jsonMediaType(callback))
            .entity(wrapWithCallback(access_info, callback))
            .build();
      }

      if (user == null) {
        OAuthResponse response =
            OAuthResponse.errorResponse(SC_BAD_REQUEST)
                .setError(OAuthError.TokenResponse.INVALID_GRANT)
                .setErrorDescription(errorDescription)
                .buildJSONMessage();
        return Response.status(response.getResponseStatus())
            .type(jsonMediaType(callback))
            .entity(wrapWithCallback(response.getBody(), callback))
            .build();
      }

      String token =
          management.getAccessTokenForAppUser(services.getApplicationId(), user.getUuid(), ttl);

      AccessInfo access_info =
          new AccessInfo()
              .withExpiresIn(tokens.getMaxTokenAge(token) / 1000)
              .withAccessToken(token)
              .withProperty("user", user);

      return Response.status(SC_OK)
          .type(jsonMediaType(callback))
          .entity(wrapWithCallback(access_info, callback))
          .build();

    } catch (OAuthProblemException e) {
      logger.error("OAuth Error", e);
      OAuthResponse res = OAuthResponse.errorResponse(SC_BAD_REQUEST).error(e).buildJSONMessage();
      return Response.status(res.getResponseStatus())
          .type(jsonMediaType(callback))
          .entity(wrapWithCallback(res.getBody(), callback))
          .build();
    }
  }