/**
   * @param name the name of the entity manager factory
   * @param parser the persistence parser
   * @since 2.0.0
   */
  public EntityManagerFactoryImpl(String name, PersistenceParser parser) {
    super();

    this.classloader = parser.getClassloader();
    this.prepareProperties(parser);

    final boolean hasValidators = parser.hasValidators();
    if (hasValidators) {
      this.validationFactory = this.createValidationFactory();
      this.persistValidators = this.getValidatorsFor(parser, JPASettings.PERSIST_VALIDATION_GROUP);
      this.updateValidators = this.getValidatorsFor(parser, JPASettings.UPDATE_VALIDATION_GROUP);
      this.removeValidators = this.getValidatorsFor(parser, JPASettings.REMOVE_VALIDATION_GROUP);
    } else {
      this.validationFactory = null;
      this.persistValidators = null;
      this.updateValidators = null;
      this.removeValidators = null;
    }

    try {
      this.maxFetchJoinDepth =
          this.getProperty(BJPASettings.MAX_FETCH_JOIN_DEPTH) != null
              ? //
              Integer.valueOf(((String) this.getProperty(BJPASettings.MAX_FETCH_JOIN_DEPTH)))
              : //
              BJPASettings.DEFAULT_MAX_FETCH_JOIN_DEPTH;
    } catch (final Exception e) {
      throw new IllegalArgumentException(
          "Illegal value "
              + this.getProperty(BJPASettings.SQL_LOGGING)
              + " for "
              + BJPASettings.SQL_LOGGING);
    }

    this.dataSource = this.createDatasource(name, parser);

    this.ddlMode = this.readDdlMode();

    this.jdbcAdaptor = this.createJdbcAdaptor();
    this.metamodel = new MetamodelImpl(this, this.jdbcAdaptor, parser.getMetadata());

    LinkManager.perform(this.metamodel);

    this.metamodel.checkTables();

    // drop all tables if ddl mode is drop
    if (this.ddlMode == DDLMode.DROP) {
      this.metamodel.dropAllTables(this.dataSource);
    }

    DdlManager.perform(this.dataSource, this.metamodel, this.ddlMode);

    this.metamodel.performSequencesDdl(this.dataSource, this.ddlMode);
    this.metamodel.performTableGeneratorsDdl(this.dataSource, this.ddlMode);

    this.metamodel.preFillGenerators(this.dataSource);
    this.criteriaBuilder = new CriteriaBuilderImpl(this.metamodel);

    NamedQueriesManager.perform(this.metamodel, this.criteriaBuilder);

    this.persistenceUtil = new PersistenceUnitUtilImpl(this);

    this.jdbcAdaptor.importSql(
        this.classloader,
        this.dataSource,
        (String) this.getProperties().get(BJPASettings.IMPORT_SQL));

    this.open = true;
  }