/**
   * Impersonate the user
   *
   * @param id User id
   * @return
   */
  @Path("{id}/impersonation")
  @POST
  @NoCache
  @Produces(MediaType.APPLICATION_JSON)
  public Map<String, Object> impersonate(final @PathParam("id") String id) {
    auth.init(RealmAuth.Resource.IMPERSONATION);
    auth.requireManage();
    UserModel user = session.users().getUserById(id, realm);
    if (user == null) {
      throw new NotFoundException("User not found");
    }
    RealmModel authenticatedRealm = auth.getAuth().getRealm();
    // if same realm logout before impersonation
    boolean sameRealm = false;
    if (authenticatedRealm.getId().equals(realm.getId())) {
      sameRealm = true;
      UserSessionModel userSession =
          session
              .sessions()
              .getUserSession(authenticatedRealm, auth.getAuth().getToken().getSessionState());
      AuthenticationManager.expireIdentityCookie(realm, uriInfo, clientConnection);
      AuthenticationManager.expireRememberMeCookie(realm, uriInfo, clientConnection);
      AuthenticationManager.backchannelLogout(
          session, authenticatedRealm, userSession, uriInfo, clientConnection, headers, true);
    }
    EventBuilder event = new EventBuilder(realm, session, clientConnection);

    UserSessionModel userSession =
        session
            .sessions()
            .createUserSession(
                realm,
                user,
                user.getUsername(),
                clientConnection.getRemoteAddr(),
                "impersonate",
                false,
                null,
                null);
    AuthenticationManager.createLoginCookie(
        realm, userSession.getUser(), userSession, uriInfo, clientConnection);
    URI redirect = AccountService.accountServiceApplicationPage(uriInfo).build(realm.getName());
    Map<String, Object> result = new HashMap<>();
    result.put("sameRealm", sameRealm);
    result.put("redirect", redirect.toString());
    event
        .event(EventType.IMPERSONATE)
        .session(userSession)
        .user(user)
        .detail(Details.IMPERSONATOR_REALM, authenticatedRealm.getName())
        .detail(Details.IMPERSONATOR, auth.getAuth().getUser().getUsername())
        .success();

    return result;
  }
  /**
   * protocol independent registration page entry point
   *
   * @param code
   * @return
   */
  @Path(REGISTRATION_PATH)
  @GET
  public Response registerPage(
      @QueryParam("code") String code, @QueryParam("execution") String execution) {
    event.event(EventType.REGISTER);
    if (!realm.isRegistrationAllowed()) {
      event.error(Errors.REGISTRATION_DISABLED);
      return ErrorPage.error(session, Messages.REGISTRATION_NOT_ALLOWED);
    }

    Checks checks = new Checks();
    if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name())) {
      return checks.response;
    }
    event.detail(Details.CODE_ID, code);
    ClientSessionCode clientSessionCode = checks.clientCode;
    ClientSessionModel clientSession = clientSessionCode.getClientSession();

    authManager.expireIdentityCookie(realm, uriInfo, clientConnection);

    return processRegistration(execution, clientSession, null);
  }