/**
   * Get authenticator configuration
   *
   * @param id Configuration id
   */
  @Path("config/{id}")
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  @NoCache
  public AuthenticatorConfigRepresentation getAuthenticatorConfig(@PathParam("id") String id) {
    auth.requireView();

    AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
    if (config == null) {
      throw new NotFoundException("Could not find authenticator config");
    }
    return ModelToRepresentation.toRepresentation(config);
  }
  /**
   * Update authenticator configuration
   *
   * @param id Configuration id
   * @param rep JSON describing new state of authenticator configuration
   */
  @Path("config/{id}")
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  @NoCache
  public void updateAuthenticatorConfig(
      @PathParam("id") String id, AuthenticatorConfigRepresentation rep) {
    auth.requireManage();

    AuthenticatorConfigModel exists = realm.getAuthenticatorConfigById(id);
    if (exists == null) {
      throw new NotFoundException("Could not find authenticator config");
    }
    exists.setAlias(rep.getAlias());
    exists.setConfig(rep.getConfig());
    realm.updateAuthenticatorConfig(exists);
    adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
  }
  /**
   * Delete authenticator configuration
   *
   * @param id Configuration id
   */
  @Path("config/{id}")
  @DELETE
  @NoCache
  public void removeAuthenticatorConfig(@PathParam("id") String id) {
    auth.requireManage();

    AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
    if (config == null) {
      throw new NotFoundException("Could not find authenticator config");
    }
    List<AuthenticationFlowModel> flows = new LinkedList<>();
    for (AuthenticationFlowModel flow : realm.getAuthenticationFlows()) {
      for (AuthenticationExecutionModel exe : realm.getAuthenticationExecutions(flow.getId())) {
        if (id.equals(exe.getAuthenticatorConfig())) {
          exe.setAuthenticatorConfig(null);
          realm.updateAuthenticatorExecution(exe);
        }
      }
    }

    realm.removeAuthenticatorConfig(config);

    adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
  }
  public void recurseExecutions(
      AuthenticationFlowModel flow,
      List<AuthenticationExecutionInfoRepresentation> result,
      int level) {
    int index = 0;
    List<AuthenticationExecutionModel> executions = realm.getAuthenticationExecutions(flow.getId());
    for (AuthenticationExecutionModel execution : executions) {
      AuthenticationExecutionInfoRepresentation rep =
          new AuthenticationExecutionInfoRepresentation();
      rep.setLevel(level);
      rep.setIndex(index++);
      rep.setRequirementChoices(new LinkedList<String>());
      if (execution.isAuthenticatorFlow()) {
        AuthenticationFlowModel flowRef = realm.getAuthenticationFlowById(execution.getFlowId());
        if (AuthenticationFlow.BASIC_FLOW.equals(flowRef.getProviderId())) {
          rep.getRequirementChoices()
              .add(AuthenticationExecutionModel.Requirement.ALTERNATIVE.name());
          rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.REQUIRED.name());
          rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.DISABLED.name());
        } else if (AuthenticationFlow.FORM_FLOW.equals(flowRef.getProviderId())) {
          rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.REQUIRED.name());
          rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.DISABLED.name());
          rep.setProviderId(execution.getAuthenticator());
          rep.setAuthenticationConfig(execution.getAuthenticatorConfig());
        } else if (AuthenticationFlow.CLIENT_FLOW.equals(flowRef.getProviderId())) {
          rep.getRequirementChoices()
              .add(AuthenticationExecutionModel.Requirement.ALTERNATIVE.name());
          rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.REQUIRED.name());
          rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.DISABLED.name());
        }
        rep.setDisplayName(flowRef.getAlias());
        rep.setConfigurable(false);
        rep.setId(execution.getId());
        rep.setAuthenticationFlow(execution.isAuthenticatorFlow());
        rep.setRequirement(execution.getRequirement().name());
        rep.setFlowId(execution.getFlowId());
        result.add(rep);
        AuthenticationFlowModel subFlow = realm.getAuthenticationFlowById(execution.getFlowId());
        recurseExecutions(subFlow, result, level + 1);
      } else {
        String providerId = execution.getAuthenticator();
        ConfigurableAuthenticatorFactory factory =
            CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
        rep.setDisplayName(factory.getDisplayType());
        rep.setConfigurable(factory.isConfigurable());
        for (AuthenticationExecutionModel.Requirement choice : factory.getRequirementChoices()) {
          rep.getRequirementChoices().add(choice.name());
        }
        rep.setId(execution.getId());

        if (factory.isConfigurable()) {
          AuthenticatorConfigModel authenticatorConfig =
              realm.getAuthenticatorConfigById(execution.getAuthenticatorConfig());

          if (authenticatorConfig != null) {
            rep.setAlias(authenticatorConfig.getAlias());
          }
        }

        rep.setRequirement(execution.getRequirement().name());
        rep.setProviderId(execution.getAuthenticator());
        rep.setAuthenticationConfig(execution.getAuthenticatorConfig());
        result.add(rep);
      }
    }
  }