class DataSourceFactory {

    public static GenericObjectPoolConfig setupPoolConfig() {
        
        // setup config vars for the object pool
        // ie. min and max idle instances, and max total instances of arbitrary objects
        
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();

        // The maximum number of active connections that can be allocated from
        // this pool at the same time, or negative for no limit. Default: 8
        config.setMaxTotal(retrieveConfigSetting(ATHENZ_PROP_DBPOOL_MAX_TOTAL,
                GenericObjectPoolConfig.DEFAULT_MAX_TOTAL));
        if (config.getMaxTotal() == 0) {
            config.setMaxTotal(-1); // -1 means no limit
        }
        
        //  The maximum number of connections that can remain idle in the pool,
        // without extra ones being released, or negative for no limit. Default 8
        config.setMaxIdle(retrieveConfigSetting(ATHENZ_PROP_DBPOOL_MAX_IDLE,
                GenericObjectPoolConfig.DEFAULT_MAX_IDLE));
        if (config.getMaxIdle() == 0) {
            config.setMaxIdle(-1); // -1 means no limit
        }
        
        // The minimum number of connections that can remain idle in the pool,
        // without extra ones being created, or zero to create none. Default 0
        config.setMinIdle(retrieveConfigSetting(ATHENZ_PROP_DBPOOL_MIN_IDLE,
                GenericObjectPoolConfig.DEFAULT_MIN_IDLE));
        
        // The maximum number of milliseconds that the pool will wait (when
        // there are no available connections) for a connection to be returned
        // before throwing an exception, or -1 to wait indefinitely. Default -1
        config.setMaxWaitMillis(retrieveConfigSetting(ATHENZ_PROP_DBPOOL_MAX_WAIT,
                GenericObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS));
        
        // setup the configuration to cleanup idle connections
        //
        // Minimum time an object can be idle in the pool before being eligible
        // for eviction by the idle object evictor.
        // The default value is 30 minutes (1000 * 60 * 30).
        config.setMinEvictableIdleTimeMillis(retrieveConfigSetting(ATHENZ_PROP_DBPOOL_EVICT_IDLE_TIMEOUT,
                BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS));
        
        // Number of milliseconds to sleep between runs of idle object evictor thread.
        // Not using DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS since it is -1
        // meaning it will not run the evictor thread and instead we're using
        // the default min value for evictable idle connections (Default 30 minutes)
        config.setTimeBetweenEvictionRunsMillis(retrieveConfigSetting(ATHENZ_PROP_DBPOOL_EVICT_IDLE_INTERVAL,
                BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS));
        
        if (LOG.isDebugEnabled()) {
            LOG.debug("Config settings for idle object eviction: " +
                    "time interval between eviction thread runs (" +
                    config.getTimeBetweenEvictionRunsMillis() +
                    " millis): minimum timeout for idle objects (" +
                    config.getMinEvictableIdleTimeMillis() + " millis)");
        }
        
        // Validate objects by the idle object evictor. If invalid, gets dropped
        // from the pool.
        config.setTestWhileIdle(true);
        
        // Validate object before borrowing from pool and returning to the pool.
        // If invalid, gets dropped from the pool and an attempt to borrow
        // another one will occur.
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);
        return config;
    }

}