class EmbeddedConnectionProvider implements ConnectionProvider {

    private static final Logger Log = LoggerFactory.getLogger(EmbeddedConnectionProvider.class);

    private String serverURL;
    private PoolingDataSource<PoolableConnection> dataSource;

    public EmbeddedConnectionProvider() {
    }

    @Override
    public boolean isPooled() {
        return true;
    }

    @Override
    public Connection getConnection() throws SQLException {
        if (dataSource == null) {
            throw new SQLException("Check HSQLDB properties; data source was not be initialised");
        }
        return dataSource.getConnection();
    }

    @Override
    public void start() {<FILL_FUNCTION_BODY>}

    @Override
    public void restart() {
        // Kill off pool.
        destroy();
        // Start a new pool.
        start();
    }

    @Override
    public void destroy() {
        // Shutdown the database.
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = getConnection();
            pstmt = con.prepareStatement("SHUTDOWN");
            pstmt.execute();
        }
        catch (SQLException sqle) {
            Log.error(sqle.getMessage(), sqle);
        }
        finally {
            DbConnectionManager.closeConnection(pstmt, con);
        }
    }

    @Override
    public void finalize() throws Throwable {
        destroy();
        super.finalize();
    }
}

        final Path databaseDir = JiveGlobals.getHomePath().resolve("embedded-db");
        try {
            // If the database doesn't exist, create it.
            if (!Files.exists(databaseDir)) {
                Files.createDirectory(databaseDir);
            }
        } catch (IOException e) {
            Log.error("Unable to create 'embedded-db' directory", e);
        }

        serverURL = "jdbc:hsqldb:" + databaseDir.resolve("openfire");
        final ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(serverURL, "sa", "");
        final PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
        poolableConnectionFactory.setMaxConnLifetimeMillis(Duration.ofHours(12).toMillis());

        final GenericObjectPoolConfig<PoolableConnection> poolConfig = new GenericObjectPoolConfig<>();
        poolConfig.setMinIdle(3);
        poolConfig.setMaxTotal(25);
        final GenericObjectPool<PoolableConnection> connectionPool = new GenericObjectPool<>(poolableConnectionFactory, poolConfig);
        poolableConnectionFactory.setPool(connectionPool);
        dataSource = new PoolingDataSource<>(connectionPool);
    
<no_super_class>