// create tenant from configuration properties. We do not overwrite existing
  // tenants.
  private static void processTenant(CasIdmClient idmClient, String tenantName) throws Exception {
    // create tenant
    Tenant tenantToCreate = new Tenant(tenantName);
    tenantToCreate._issuerName = ServerConfig.getTenantEntityId(tenantName);
    IdmDataRemover.addTenant(tenantName);

    Tenant existingTenant = null;
    try {
      existingTenant = idmClient.getTenant(tenantName);
      assert (existingTenant != null);
      return;
    } catch (NoSuchTenantException ex) {
      idmClient.addTenant(
          tenantToCreate,
          ServerConfig.getTenantAdminUsername(),
          ServerConfig.getTenantAdminPassword().toCharArray());
    }

    existingTenant = idmClient.getTenant(tenantName);
    assert (existingTenant != null);

    // add entity ID, clock tolerance, certificates and keys
    try {
      idmClient.setEntityID(tenantName, ServerConfig.getTenantEntityId(tenantName));
      idmClient.setClockTolerance(tenantName, ServerConfig.getTenantClockTolerance(tenantName));
      idmClient.setDelegationCount(tenantName, ServerConfig.getTenantDelegationCount(tenantName));
      idmClient.setBrandName(tenantName, ServerConfig.getTenantBrandName(tenantName));
      idmClient.setRenewCount(tenantName, ServerConfig.getTenantRenewCount(tenantName));
      idmClient.setMaximumBearerTokenLifetime(
          tenantName, ServerConfig.getTenantMaximumBearerTokenLifetime(tenantName));
      idmClient.setMaximumHoKTokenLifetime(
          tenantName, ServerConfig.getTenantMaximumHokTokenLifetime(tenantName));
      KeyPair kp = readKeyStore(ServerConfig.getTenantCredentialDescriptor(tenantName));
      idmClient.setTenantCredentials(tenantName, kp.getCertificateChain(), kp.getPrivateKey());
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }

    // create relying parties
    int i = 0;
    String rpName = ServerConfig.getRelyingParty(tenantName, i);
    while (rpName != null) {
      RelyingParty rp = processRelyingParty(idmClient, rpName);
      // add relying party info
      idmClient.addRelyingParty(tenantName, rp);
      i++;
      rpName = ServerConfig.getRelyingParty(tenantName, i);
    }

    // create identity stores
    int j = 0;
    String adProviderName = ServerConfig.getADProvider(tenantName, j);
    while (adProviderName != null) {
      IdentityStoreData adStore = processADProvider(idmClient, adProviderName);
      // add store info
      idmClient.addProvider(tenantName, adStore);
      j++;
      adProviderName = ServerConfig.getADProvider(tenantName, j);
    }
  }
  public User userRegistered(
      String aTenantName,
      String aTenantDescription,
      FullName anAdministorName,
      EmailAddress anEmailAddress,
      PostalAddress aPostalAddress,
      Telephone aPrimaryTelephone,
      Telephone aSecondaryTelephone) {

    try {
      Tenant tenant =
          new Tenant(
              this.tenantRepository().nextIdentity(),
              aTenantName,
              aTenantDescription,
              true); // must be active to register admin

      this.tenantRepository().add(tenant);

      this.registerAdministratorFor(
          tenant,
          anAdministorName,
          anEmailAddress,
          aPostalAddress,
          aPrimaryTelephone,
          aSecondaryTelephone);

      DomainEventPublisher.instance().publish(new TenantProvisioned(tenant.tenantId()));

      return tenant;

    } catch (Throwable t) {
      throw new IllegalStateException("Cannot provision tenant because: " + t.getMessage());
    }
  }
  public UserDescriptor authenticate(TenantId aTenantId, String aUsername, String aPassword) {

    this.assertArgumentNotNull(aTenantId, "TenantId must not be null.");
    this.assertArgumentNotEmpty(aUsername, "Username must be provided.");
    this.assertArgumentNotEmpty(aPassword, "Password must be provided.");

    UserDescriptor userDescriptor = UserDescriptor.nullDescriptorInstance();

    Tenant tenant = this.tenantRepository().tenantOfId(aTenantId);

    if (tenant != null && tenant.isActive()) {
      String encryptedPassword = this.encryptionService().encryptedValue(aPassword);

      User user =
          this.userRepository()
              .userFromAuthenticCredentials(aTenantId, aUsername, encryptedPassword);

      if (user != null && user.isEnabled()) {
        userDescriptor = user.userDescriptor();
      }
    }

    return userDescriptor;
  }
  private void registerAdministratorFor(
      Tenant aTenant,
      FullName anAdministorName,
      EmailAddress anEmailAddress,
      PostalAddress aPostalAddress,
      Telephone aPrimaryTelephone,
      Telephone aSecondaryTelephone) {

    RegistrationInvitation invitation = aTenant.offerRegistrationInvitation("init").openEnded();

    String strongPassword = DomainRegistry.passwordService().generateStrongPassword();

    User admin =
        aTenant.registerUser(
            invitation.invitationId(),
            "admin",
            strongPassword,
            Enablement.indefiniteEnablement(),
            new Person(
                aTenant.tenantId(),
                anAdministorName,
                new ContactInformation(
                    anEmailAddress, aPostalAddress, aPrimaryTelephone, aSecondaryTelephone)));

    aTenant.withdrawInvitation(invitation.invitationId());

    this.userRepository().add(admin);

    Role adminRole =
        aTenant.provisionRole("Administrator", "Default " + aTenant.name() + " administrator.");

    adminRole.assignUser(admin);

    this.roleRepository().add(adminRole);

    DomainEventPublisher.instance()
        .publish(
            new TenantAdministratorRegistered(
                aTenant.tenantId(),
                aTenant.name(),
                anAdministorName,
                anEmailAddress,
                admin.username(),
                strongPassword));
  }