/** Clears the idle connections in the pool. */
  @Override
  public void clear() {
    ArrayList<ManagedPoolItem> pool = _connectionPool;

    if (pool == null) return;

    ArrayList<ManagedPoolItem> clearItems = new ArrayList<ManagedPoolItem>();

    synchronized (_connectionPool) {
      _idlePool.clear();

      clearItems.addAll(pool);

      pool.clear();
    }

    for (int i = 0; i < clearItems.size(); i++) {
      ManagedPoolItem poolItem = clearItems.get(i);

      try {
        poolItem.destroy();
      } catch (Throwable e) {
        log.log(Level.WARNING, e.toString(), e);
      }
    }
  }
  /** Initialize the connection manager. */
  public Object init(ManagedConnectionFactory mcf) throws ConfigException, ResourceException {
    if (!_lifecycle.toInit()) return null;

    _mcf = mcf;

    if (_name == null) {
      int v = _idGen.incrementAndGet();

      _name = mcf.getClass().getSimpleName() + "-" + v;
    }

    if (_tm == null)
      throw new ConfigException(L.l("the connection manager needs a transaction manager."));

    _idlePool = new IdlePoolSet(_maxIdleCount);

    _connectionTime = MeterService.createActiveTimeMeter("Resin|Database|Connection");
    _idleTime = MeterService.createActiveTimeMeter("Resin|Database|Idle");
    _queryTime = MeterService.createActiveTimeMeter("Resin|Database|Query");

    registerSelf();

    _alarm = new WeakAlarm(this);

    if (!(mcf instanceof ValidatingManagedConnectionFactory)) {
      // never check
      _lastValidCheckTime = Long.MAX_VALUE / 2;
    }

    // recover any resources on startup
    if (_isEnableXA) {
      Subject subject = null;
      ManagedConnection mConn = mcf.createManagedConnection(subject, null);

      try {
        XAResource xa = mConn.getXAResource();

        _tm.recover(xa);
      } catch (NotSupportedException e) {
        log.finer(e.toString());
      } catch (Throwable e) {
        log.log(Level.FINER, e.toString(), e);
      } finally {
        mConn.destroy();
      }
    }

    return mcf.createConnectionFactory(this);
  }
  /** Destroys the manager. */
  public void destroy() {
    stop();

    if (!_lifecycle.toDestroy()) return;

    ArrayList<ManagedPoolItem> pool;

    synchronized (_connectionPool) {
      pool = new ArrayList<ManagedPoolItem>(_connectionPool);
      _connectionPool.clear();

      if (_idlePool != null) _idlePool.clear();
    }

    for (int i = 0; i < pool.size(); i++) {
      ManagedPoolItem poolItem = pool.get(i);

      try {
        poolItem.destroy();
      } catch (Throwable e) {
        log.log(Level.WARNING, e.toString(), e);
      }
    }
  }