/**
   * Initialize the schema Manager by loading the schema LDIF files
   *
   * @param instanceLayout the instance layout
   * @throws Exception in case of any problems while extracting and writing the schema files
   */
  private void initSchemaManager(InstanceLayout instanceLayout) throws Exception {
    File schemaPartitionDirectory = new File(instanceLayout.getPartitionsDirectory(), "schema");

    // Extract the schema on disk (a brand new one) and load the registries
    if (schemaPartitionDirectory.exists()) {
      LOG.info("schema partition already exists, skipping schema extraction");
    } else {
      SchemaLdifExtractor extractor =
          new DefaultSchemaLdifExtractor(instanceLayout.getPartitionsDirectory());
      extractor.extractOrCopy();
      isSchemaPartitionFirstExtraction = true;
    }

    SchemaLoader loader = new LdifSchemaLoader(schemaPartitionDirectory);
    schemaManager = new DefaultSchemaManager(loader);

    // We have to load the schema now, otherwise we won't be able
    // to initialize the Partitions, as we won't be able to parse
    // and normalize their suffix Dn
    schemaManager.loadAllEnabled();

    List<Throwable> errors = schemaManager.getErrors();

    if (errors.size() != 0) {
      throw new Exception(I18n.err(I18n.ERR_317, Exceptions.printErrors(errors)));
    }
  }
  /**
   * starts various services configured according to the configuration present in the given
   * instance's layout
   *
   * @param instanceLayout the on disk location's layout of the intance to be started
   * @throws Exception
   */
  public void start(InstanceLayout instanceLayout, CacheService cacheService) throws Exception {
    File partitionsDir = instanceLayout.getPartitionsDirectory();

    if (!partitionsDir.exists()) {
      LOG.info("partition directory doesn't exist, creating {}", partitionsDir.getAbsolutePath());
      if (!partitionsDir.mkdirs()) {
        throw new IOException(I18n.err(I18n.ERR_112_COULD_NOT_CREATE_DIRECORY, partitionsDir));
      }
    }

    LOG.info("using partition dir {}", partitionsDir.getAbsolutePath());

    initSchemaManager(instanceLayout);
    initSchemaLdifPartition(instanceLayout);
    initConfigPartition(instanceLayout);

    // Read the configuration
    cpReader = new ConfigPartitionReader(configPartition);

    ConfigBean configBean = cpReader.readConfig();

    DirectoryServiceBean directoryServiceBean = configBean.getDirectoryServiceBean();

    // Initialize the DirectoryService now
    DirectoryService directoryService =
        initDirectoryService(instanceLayout, directoryServiceBean, cacheService);

    // start the LDAP server
    startLdap(directoryServiceBean.getLdapServerBean(), directoryService);

    // start the NTP server
    startNtp(directoryServiceBean.getNtpServerBean(), directoryService);

    // Initialize the DNS server (Not ready yet)
    // initDns( configBean );

    // Initialize the DHCP server (Not ready yet)
    // initDhcp( configBean );

    // start the ChangePwd server (Not ready yet)
    // startChangePwd( directoryServiceBean.getChangePasswordServerBean(), directoryService );

    // start the Kerberos server
    startKerberos(directoryServiceBean.getKdcServerBean(), directoryService);

    // start the jetty http server
    // startHttpServer( directoryServiceBean.getHttpServerBean(), directoryService );
  }
  /** {@inheritDoc} */
  public void init(String name) throws Exception {
    if ((directoryService != null) && directoryService.isStarted()) {
      return;
    }

    directoryService.setInstanceId(name);

    // instance layout
    InstanceLayout instanceLayout =
        new InstanceLayout(System.getProperty("java.io.tmpdir") + "/server-work-" + name);
    if (instanceLayout.getInstanceDirectory().exists()) {
      try {
        FileUtils.deleteDirectory(instanceLayout.getInstanceDirectory());
      } catch (IOException e) {
        LOG.warn(
            "couldn't delete the instance directory before initializing the DirectoryService", e);
      }
    }
    directoryService.setInstanceLayout(instanceLayout);

    // EhCache in disabled-like-mode
    Configuration ehCacheConfig = new Configuration();
    CacheConfiguration defaultCache =
        new CacheConfiguration("default", 1)
            .eternal(false)
            .timeToIdleSeconds(30)
            .timeToLiveSeconds(30)
            .overflowToDisk(false);
    ehCacheConfig.addDefaultCache(defaultCache);
    CacheService cacheService = new CacheService(new CacheManager(ehCacheConfig));
    directoryService.setCacheService(cacheService);

    // Init the schema
    // SchemaLoader loader = new SingleLdifSchemaLoader();
    SchemaLoader loader = new JarLdifSchemaLoader();
    SchemaManager schemaManager = new DefaultSchemaManager(loader);
    schemaManager.loadAllEnabled();
    ComparatorRegistry comparatorRegistry = schemaManager.getComparatorRegistry();
    for (LdapComparator<?> comparator : comparatorRegistry) {
      if (comparator instanceof NormalizingComparator) {
        ((NormalizingComparator) comparator).setOnServer();
      }
    }
    directoryService.setSchemaManager(schemaManager);
    InMemorySchemaPartition inMemorySchemaPartition = new InMemorySchemaPartition(schemaManager);

    SchemaPartition schemaPartition = new SchemaPartition(schemaManager);
    schemaPartition.setWrappedPartition(inMemorySchemaPartition);
    directoryService.setSchemaPartition(schemaPartition);
    List<Throwable> errors = schemaManager.getErrors();
    if (errors.size() != 0) {
      throw new Exception(I18n.err(I18n.ERR_317, Exceptions.printErrors(errors)));
    }

    // Init system partition
    Partition systemPartition =
        partitionFactory.createPartition(
            directoryService.getSchemaManager(),
            "system",
            ServerDNConstants.SYSTEM_DN,
            500,
            new File(directoryService.getInstanceLayout().getPartitionsDirectory(), "system"));
    systemPartition.setSchemaManager(directoryService.getSchemaManager());
    partitionFactory.addIndex(systemPartition, SchemaConstants.OBJECT_CLASS_AT, 100);
    directoryService.setSystemPartition(systemPartition);

    directoryService.startup();
  }