/** Alarm listener. */
  @Override
  public void handleAlarm(Alarm alarm) {
    if (!_lifecycle.isActive()) return;

    try {
      _alarmConnections.clear();

      synchronized (_connectionPool) {
        _alarmConnections.addAll(_connectionPool);
      }

      for (int i = _alarmConnections.size() - 1; i >= 0; i--) {
        ManagedPoolItem item = _alarmConnections.get(i);

        if (!item.isValid()) item.destroy();
      }

      _alarmConnections.clear();

      fillIdlePool();
    } finally {
      if (!_lifecycle.isActive()) {
      } else if (0 < _idleTimeout && _idleTimeout < 1000) _alarm.queue(1000);
      else if (1000 < _idleTimeout && _idleTimeout < 60000) _alarm.queue(_idleTimeout);
      else _alarm.queue(60000);
    }
  }
  /** 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);
      }
    }
  }
  /*
   * Removes a connection from the pool.
   */
  public void markForPoolRemoval(ManagedConnection mConn) {
    synchronized (_connectionPool) {
      for (int i = _connectionPool.size() - 1; i >= 0; i--) {
        ManagedPoolItem poolItem = _connectionPool.get(i);

        if (poolItem.getManagedConnection() == mConn) {
          poolItem.setConnectionError();
          return;
        }
      }
    }
  }
  private ManagedPoolItem findPoolItem(ManagedConnection mConn) {
    synchronized (_connectionPool) {
      for (int i = _connectionPool.size() - 1; i >= 0; i--) {
        ManagedPoolItem testPoolItem = _connectionPool.get(i);

        if (testPoolItem.getManagedConnection() == mConn) {
          return testPoolItem;
        }
      }

      return null;
    }
  }
  /** Finds the pool item joined to this one. return null. */
  ManagedPoolItem findJoin(UserTransactionImpl uTrans, ManagedPoolItem item) {
    if (!uTrans.isActive()) return null;

    ArrayList<ManagedXAResource> poolItems = uTrans.getXaResources();
    int length = poolItems.size();

    for (int i = 0; i < length; i++) {
      ManagedXAResource resource = poolItems.get(i);

      if (resource instanceof ManagedPoolItem) {
        ManagedPoolItem poolItem = (ManagedPoolItem) resource;

        if (poolItem.isJoin(item)) return poolItem;
      }
    }

    return null;
  }
  /** Allocates a resource matching the parameters. If none matches, return null. */
  private UserPoolItem allocateShared(
      UserTransactionImpl transaction,
      ManagedConnectionFactory mcf,
      Subject subject,
      ConnectionRequestInfo info) {
    if (!transaction.isActive()) return null;

    ArrayList<ManagedXAResource> poolItems = transaction.getXaResources();
    int length = poolItems.size();

    for (int i = 0; i < length; i++) {
      ManagedXAResource xaResource = poolItems.get(i);

      if (xaResource instanceof ManagedPoolItem) {
        ManagedPoolItem poolItem = (ManagedPoolItem) xaResource;

        UserPoolItem item = poolItem.allocateXA(mcf, subject, info);

        if (item != null) return item;
      }
    }

    return null;
  }
  /** 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);
      }
    }
  }