public static SymfonyDbFactory getInstance() {

    if (instance == null) {
      try {
        instanceLock.acquire();
        instance = new SymfonyDbFactory();
        /*
         * Explicitly register shutdown handler, so it
         * would be disposed only if class was loaded.
         *
         * We don't want static initialization code to
         * be executed during framework shutdown.
         */
        SymfonyIndex.addShutdownListener(
            new IShutdownListener() {
              public void shutdown() {
                if (instance != null) {
                  try {
                    instance.dispose();
                  } catch (SQLException e) {
                    Logger.logException(e);
                  }
                  instance = null;
                }
              }
            });

      } catch (Exception e) {
        Logger.logException(e);
      } finally {
        instanceLock.release();
      }
    }

    return instance;
  }
  private SymfonyDbFactory() throws Exception {
    try {
      Class.forName("org.h2.Driver");
    } catch (ClassNotFoundException e) {
      Logger.logException(e);
    }

    IPath dbPath = SymfonyIndex.getDefault().getStateLocation();

    String connString = getConnectionString(dbPath);

    pool = JdbcConnectionPool.create(connString, DB_USER, DB_PASS);

    Schema schema = new Schema();
    boolean initializeSchema = false;

    int tries = 2; // Tries for opening database
    Connection connection = null;
    do {
      try {
        connection = pool.getConnection();
        try {
          Statement statement = connection.createStatement();
          try {
            statement.executeQuery("SELECT COUNT(*) FROM SERVICES WHERE 1=0;");
            initializeSchema = !schema.isCompatible();

          } catch (SQLException e) {
            // Basic table doesn't exist
            initializeSchema = true;
          } finally {
            statement.close();
          }

          if (initializeSchema) {
            connection.close();
            pool.dispose();
            // Destroy schema by removing DB (if exists)
            DeleteDbFiles.execute(dbPath.toOSString(), DB_NAME, true);

            pool = JdbcConnectionPool.create(connString, DB_USER, DB_PASS);
            connection = pool.getConnection();
            schema.initialize(connection);
          }
        } finally {
          if (connection != null) {
            connection.close();
          }
        }
      } catch (SQLException e) {

        Logger.logException(e);

        // remove corrupted DB
        try {
          DeleteDbFiles.execute(dbPath.toOSString(), DB_NAME, true);

        } catch (Exception e1) {

          Logger.logException(e1);
          throw e1;
        }
      }
    } while (connection == null && --tries > 0);
  }