@Override
  public <DB extends ODatabase> DB open(final String iUserName, final String iUserPassword) {
    setCurrentDatabaseinThreadLocal();

    try {
      super.open(iUserName, iUserPassword);
      level1Cache.startup();

      metadata = new OMetadata();
      metadata.load();

      recordFormat = DEF_RECORD_FORMAT;

      if (getStorage() instanceof OStorageEmbedded) {
        user = getMetadata().getSecurity().authenticate(iUserName, iUserPassword);
        registerHook(new OUserTrigger());
        registerHook(new OClassIndexManager());
      } else
        // CREATE DUMMY USER
        user =
            new OUser(iUserName, OUser.encryptPassword(iUserPassword))
                .addRole(new ORole("passthrough", null, ORole.ALLOW_MODES.ALLOW_ALL_BUT));

      checkSecurity(ODatabaseSecurityResources.DATABASE, ORole.PERMISSION_READ);
    } catch (OException e) {
      close();
      throw e;
    } catch (Exception e) {
      close();
      throw new ODatabaseException("Cannot open database", e);
    }
    return (DB) this;
  }
  @Override
  public <DB extends ODatabase> DB create() {
    setCurrentDatabaseinThreadLocal();

    try {
      super.create();

      level1Cache.startup();

      getStorage().getConfiguration().update();

      if (getStorage() instanceof OStorageEmbedded) {
        registerHook(new OUserTrigger());
        registerHook(new OClassIndexManager());
      }

      // CREATE THE DEFAULT SCHEMA WITH DEFAULT USER
      metadata = new OMetadata();
      metadata.create();

      user = getMetadata().getSecurity().getUser(OUser.ADMIN);
    } catch (Exception e) {
      throw new ODatabaseException("Cannot create database", e);
    }
    return (DB) this;
  }
  @Override
  public void close() {
    setCurrentDatabaseinThreadLocal();

    if (metadata != null) {
      metadata.close();
      metadata = null;
    }

    super.close();

    hooks.clear();
    dictionary = null;

    user = null;
    level1Cache.shutdown();
  }