Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / mcr-test / src / pool107 / org / apache / commons / pool / impl / GenericObjectPool.java
diff --git a/JMCR-Stable/mcr-test/src/pool107/org/apache/commons/pool/impl/GenericObjectPool.java b/JMCR-Stable/mcr-test/src/pool107/org/apache/commons/pool/impl/GenericObjectPool.java
new file mode 100644 (file)
index 0000000..abc88b5
--- /dev/null
@@ -0,0 +1,1808 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package pool107.org.apache.commons.pool.impl;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.TimerTask;
+
+import pool107.org.apache.commons.pool.BaseObjectPool;
+import pool107.org.apache.commons.pool.ObjectPool;
+import pool107.org.apache.commons.pool.PoolableObjectFactory;
+import pool107.org.apache.commons.pool.impl.GenericKeyedObjectPool.ObjectTimestampPair;
+
+/**
+ * A configurable {@link ObjectPool} implementation.
+ * <p>
+ * When coupled with the appropriate {@link PoolableObjectFactory},
+ * <tt>GenericObjectPool</tt> provides robust pooling functionality for
+ * arbitrary objects.
+ * <p>
+ * A <tt>GenericObjectPool</tt> provides a number of configurable parameters:
+ * <ul>
+ * <li>
+ * {@link #setMaxActive <i>maxActive</i>} controls the maximum number of objects
+ * that can be borrowed from the pool at one time. When non-positive, there is
+ * no limit to the number of objects that may be active at one time. When
+ * {@link #setMaxActive <i>maxActive</i>} is exceeded, the pool is said to be
+ * exhausted. The default setting for this parameter is 8.</li>
+ * <li>
+ * {@link #setMaxIdle <i>maxIdle</i>} controls the maximum number of objects
+ * that can sit idle in the pool at any time. When negative, there is no limit
+ * to the number of objects that may be idle at one time. The default setting
+ * for this parameter is 8.</li>
+ * <li>
+ * {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} specifies the
+ * behavior of the {@link #borrowObject} method when the pool is exhausted:
+ * <ul>
+ * <li>
+ * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
+ * {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject} will throw a
+ * {@link NoSuchElementException}</li>
+ * <li>
+ * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
+ * {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject} will create a new object
+ * and return it(essentially making {@link #setMaxActive <i>maxActive</i>}
+ * meaningless.)</li>
+ * <li>
+ * When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
+ * {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject} will block (invoke
+ * {@link Object#wait()} until a new or idle object is available. If a positive
+ * {@link #setMaxWait <i>maxWait</i>} value is supplied, the
+ * {@link #borrowObject} will block for at most that many milliseconds, after
+ * which a {@link NoSuchElementException} will be thrown. If {@link #setMaxWait
+ * <i>maxWait</i>} is non-positive, the {@link #borrowObject} method will block
+ * indefinitely.</li>
+ * </ul>
+ * The default <code>whenExhaustedAction</code> setting is
+ * {@link #WHEN_EXHAUSTED_BLOCK} and the default <code>maxWait</code> setting is
+ * -1. By default, therefore, <code>borrowObject</code> will block indefinitely
+ * until an idle instance becomes available.</li>
+ * <li>
+ * When {@link #setTestOnBorrow <i>testOnBorrow</i>} is set, the pool will
+ * attempt to validate each object before it is returned from the
+ * {@link #borrowObject} method. (Using the provided factory's
+ * {@link PoolableObjectFactory#validateObject} method.) Objects that fail to
+ * validate will be dropped from the pool, and a different object will be
+ * borrowed. The default setting for this parameter is <code>false.</code></li>
+ * <li>
+ * When {@link #setTestOnReturn <i>testOnReturn</i>} is set, the pool will
+ * attempt to validate each object before it is returned to the pool in the
+ * {@link #returnObject} method. (Using the provided factory's
+ * {@link PoolableObjectFactory#validateObject} method.) Objects that fail to
+ * validate will be dropped from the pool. The default setting for this
+ * parameter is <code>false.</code></li>
+ * </ul>
+ * <p>
+ * Optionally, one may configure the pool to examine and possibly evict objects
+ * as they sit idle in the pool and to ensure that a minimum number of idle
+ * objects are available. This is performed by an "idle object eviction" thread,
+ * which runs asynchronously. Caution should be used when configuring this
+ * optional feature. Eviction runs require an exclusive synchronization lock on
+ * the pool, so if they run too frequently and / or incur excessive latency when
+ * creating, destroying or validating object instances, performance issues may
+ * result. The idle object eviction thread may be configured using the following
+ * attributes:
+ * <ul>
+ * <li>
+ * {@link #setTimeBetweenEvictionRunsMillis
+ * <i>timeBetweenEvictionRunsMillis</i>} indicates how long the eviction thread
+ * should sleep before "runs" of examining idle objects. When non-positive, no
+ * eviction thread will be launched. The default setting for this parameter is
+ * -1 (i.e., idle object eviction is disabled by default).</li>
+ * <li>
+ * {@link #setMinEvictableIdleTimeMillis <i>minEvictableIdleTimeMillis</i>}
+ * specifies the minimum amount of time that an object may sit idle in the pool
+ * before it is eligible for eviction due to idle time. When non-positive, no
+ * object will be dropped from the pool due to idle time alone. This setting has
+ * no effect unless <code>timeBetweenEvictionRunsMillis > 0.</code> The default
+ * setting for this parameter is 30 minutes.</li>
+ * <li>
+ * {@link #setTestWhileIdle <i>testWhileIdle</i>} indicates whether or not idle
+ * objects should be validated using the factory's
+ * {@link PoolableObjectFactory#validateObject} method. Objects that fail to
+ * validate will be dropped from the pool. This setting has no effect unless
+ * <code>timeBetweenEvictionRunsMillis > 0.</code> The default setting for this
+ * parameter is <code>false.</code></li>
+ * <li>
+ * {@link #setSoftMinEvictableIdleTimeMillis
+ * <i>softMinEvictableIdleTimeMillis</i>} specifies the minimum amount of time
+ * an object may sit idle in the pool before it is eligible for eviction by the
+ * idle object evictor (if any), with the extra condition that at least
+ * "minIdle" amount of object remain in the pool. When non-positive, no objects
+ * will be evicted from the pool due to idle time alone. This setting has no
+ * effect unless <code>timeBetweenEvictionRunsMillis > 0.</code> The default
+ * setting for this parameter is -1 (disabled).</li>
+ * <li>
+ * {@link #setNumTestsPerEvictionRun <i>numTestsPerEvictionRun</i>} determines
+ * the number of objects examined in each run of the idle object evictor. This
+ * setting has no effect unless <code>timeBetweenEvictionRunsMillis > 0.</code>
+ * The default setting for this parameter is 3.</li>
+ * </ul>
+ * <p>
+ * <p>
+ * The pool can be configured to behave as a LIFO queue with respect to idle
+ * objects - always returning the most recently used object from the pool, or as
+ * a FIFO queue, where borrowObject always returns the oldest object in the idle
+ * object pool.
+ * <ul>
+ * <li>
+ * {@link #setLifo <i>lifo</i>} determines whether or not the pool returns idle
+ * objects in last-in-first-out order. The default setting for this parameter is
+ * <code>true.</code></li>
+ * </ul>
+ * <p>
+ * GenericObjectPool is not usable without a {@link PoolableObjectFactory}. A
+ * non-<code>null</code> factory must be provided either as a constructor
+ * argument or via a call to {@link #setFactory} before the pool is used.
+ * 
+ * @see GenericKeyedObjectPool
+ * @author Rodney Waldhoff
+ * @author Dirk Verbeeck
+ * @author Sandy McArthur
+ * @version $Revision: 609487 $ $Date: 2008-01-06 21:36:42 -0500 (Sun, 06 Jan
+ *          2008) $
+ * @since Pool 1.0
+ */
+public class GenericObjectPool extends BaseObjectPool implements ObjectPool {
+
+       // --- public constants -------------------------------------------
+
+       /**
+        * A "when exhausted action" type indicating that when the pool is exhausted
+        * (i.e., the maximum number of active objects has been reached), the
+        * {@link #borrowObject} method should fail, throwing a
+        * {@link NoSuchElementException}.
+        * 
+        * @see #WHEN_EXHAUSTED_BLOCK
+        * @see #WHEN_EXHAUSTED_GROW
+        * @see #setWhenExhaustedAction
+        */
+       public static final byte WHEN_EXHAUSTED_FAIL = 0;
+
+       /**
+        * A "when exhausted action" type indicating that when the pool is exhausted
+        * (i.e., the maximum number of active objects has been reached), the
+        * {@link #borrowObject} method should block until a new object is
+        * available, or the {@link #getMaxWait maximum wait time} has been reached.
+        * 
+        * @see #WHEN_EXHAUSTED_FAIL
+        * @see #WHEN_EXHAUSTED_GROW
+        * @see #setMaxWait
+        * @see #getMaxWait
+        * @see #setWhenExhaustedAction
+        */
+       public static final byte WHEN_EXHAUSTED_BLOCK = 1;
+
+       /**
+        * A "when exhausted action" type indicating that when the pool is exhausted
+        * (i.e., the maximum number of active objects has been reached), the
+        * {@link #borrowObject} method should simply create a new object anyway.
+        * 
+        * @see #WHEN_EXHAUSTED_FAIL
+        * @see #WHEN_EXHAUSTED_GROW
+        * @see #setWhenExhaustedAction
+        */
+       public static final byte WHEN_EXHAUSTED_GROW = 2;
+
+       /**
+        * The default cap on the number of "sleeping" instances in the pool.
+        * 
+        * @see #getMaxIdle
+        * @see #setMaxIdle
+        */
+       public static final int DEFAULT_MAX_IDLE = 8;
+
+       /**
+        * The default minimum number of "sleeping" instances in the pool before
+        * before the evictor thread (if active) spawns new objects.
+        * 
+        * @see #getMinIdle
+        * @see #setMinIdle
+        */
+       public static final int DEFAULT_MIN_IDLE = 0;
+
+       /**
+        * The default cap on the total number of active instances from the pool.
+        * 
+        * @see #getMaxActive
+        */
+       public static final int DEFAULT_MAX_ACTIVE = 8;
+
+       /**
+        * The default "when exhausted action" for the pool.
+        * 
+        * @see #WHEN_EXHAUSTED_BLOCK
+        * @see #WHEN_EXHAUSTED_FAIL
+        * @see #WHEN_EXHAUSTED_GROW
+        * @see #setWhenExhaustedAction
+        */
+       public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
+
+       /**
+        * The default LIFO status. True means that borrowObject returns the most
+        * recently used ("last in") idle object in the pool (if there are idle
+        * instances available). False means that the pool behaves as a FIFO queue -
+        * objects are taken from the idle object pool in the order that they are
+        * returned to the pool.
+        * 
+        * @see #setLifo
+        * @since 1.4
+        */
+       public static final boolean DEFAULT_LIFO = true;
+
+       /**
+        * The default maximum amount of time (in milliseconds) the
+        * {@link #borrowObject} method should block before throwing an exception
+        * when the pool is exhausted and the {@link #getWhenExhaustedAction
+        * "when exhausted" action} is {@link #WHEN_EXHAUSTED_BLOCK}.
+        * 
+        * @see #getMaxWait
+        * @see #setMaxWait
+        */
+       public static final long DEFAULT_MAX_WAIT = -1L;
+
+       /**
+        * The default "test on borrow" value.
+        * 
+        * @see #getTestOnBorrow
+        * @see #setTestOnBorrow
+        */
+       public static final boolean DEFAULT_TEST_ON_BORROW = false;
+
+       /**
+        * The default "test on return" value.
+        * 
+        * @see #getTestOnReturn
+        * @see #setTestOnReturn
+        */
+       public static final boolean DEFAULT_TEST_ON_RETURN = false;
+
+       /**
+        * The default "test while idle" value.
+        * 
+        * @see #getTestWhileIdle
+        * @see #setTestWhileIdle
+        * @see #getTimeBetweenEvictionRunsMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
+
+       /**
+        * The default "time between eviction runs" value.
+        * 
+        * @see #getTimeBetweenEvictionRunsMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
+
+       /**
+        * The default number of objects to examine per run in the idle object
+        * evictor.
+        * 
+        * @see #getNumTestsPerEvictionRun
+        * @see #setNumTestsPerEvictionRun
+        * @see #getTimeBetweenEvictionRunsMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
+
+       /**
+        * The default value for {@link #getMinEvictableIdleTimeMillis}.
+        * 
+        * @see #getMinEvictableIdleTimeMillis
+        * @see #setMinEvictableIdleTimeMillis
+        */
+       public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
+
+       /**
+        * The default value for {@link #getSoftMinEvictableIdleTimeMillis}.
+        * 
+        * @see #getSoftMinEvictableIdleTimeMillis
+        * @see #setSoftMinEvictableIdleTimeMillis
+        */
+       public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
+
+       // --- constructors -----------------------------------------------
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt>.
+        */
+       public GenericObjectPool() {
+               this(null, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION,
+                               DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, DEFAULT_MIN_IDLE,
+                               DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN,
+                               DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
+                               DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
+                               DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        */
+       public GenericObjectPool(PoolableObjectFactory factory) {
+               this(factory, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION,
+                               DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, DEFAULT_MIN_IDLE,
+                               DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN,
+                               DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
+                               DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
+                               DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param config
+        *            a non-<tt>null</tt> {@link GenericObjectPool.Config}
+        *            describing my configuration
+        */
+       public GenericObjectPool(PoolableObjectFactory factory,
+                       GenericObjectPool.Config config) {
+               this(factory, config.maxActive, config.whenExhaustedAction,
+                               config.maxWait, config.maxIdle, config.minIdle,
+                               config.testOnBorrow, config.testOnReturn,
+                               config.timeBetweenEvictionRunsMillis,
+                               config.numTestsPerEvictionRun,
+                               config.minEvictableIdleTimeMillis, config.testWhileIdle,
+                               config.softMinEvictableIdleTimeMillis, config.lifo);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive) {
+               this(factory, maxActive, DEFAULT_WHEN_EXHAUSTED_ACTION,
+                               DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, DEFAULT_MIN_IDLE,
+                               DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN,
+                               DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
+                               DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
+                               DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #getWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #getMaxWait})
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait) {
+               this(factory, maxActive, whenExhaustedAction, maxWait,
+                               DEFAULT_MAX_IDLE, DEFAULT_MIN_IDLE, DEFAULT_TEST_ON_BORROW,
+                               DEFAULT_TEST_ON_RETURN,
+                               DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
+                               DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
+                               DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #getWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #getMaxWait})
+        * @param testOnBorrow
+        *            whether or not to validate objects before they are returned by
+        *            the {@link #borrowObject} method (see {@link #getTestOnBorrow}
+        *            )
+        * @param testOnReturn
+        *            whether or not to validate objects after they are returned to
+        *            the {@link #returnObject} method (see {@link #getTestOnReturn}
+        *            )
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait, boolean testOnBorrow,
+                       boolean testOnReturn) {
+               this(factory, maxActive, whenExhaustedAction, maxWait,
+                               DEFAULT_MAX_IDLE, DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn,
+                               DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
+                               DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
+                               DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #getWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #getMaxWait})
+        * @param maxIdle
+        *            the maximum number of idle objects in my pool (see
+        *            {@link #getMaxIdle})
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait, int maxIdle) {
+               this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle,
+                               DEFAULT_MIN_IDLE, DEFAULT_TEST_ON_BORROW,
+                               DEFAULT_TEST_ON_RETURN,
+                               DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
+                               DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
+                               DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #getWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #getMaxWait})
+        * @param maxIdle
+        *            the maximum number of idle objects in my pool (see
+        *            {@link #getMaxIdle})
+        * @param testOnBorrow
+        *            whether or not to validate objects before they are returned by
+        *            the {@link #borrowObject} method (see {@link #getTestOnBorrow}
+        *            )
+        * @param testOnReturn
+        *            whether or not to validate objects after they are returned to
+        *            the {@link #returnObject} method (see {@link #getTestOnReturn}
+        *            )
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait, int maxIdle,
+                       boolean testOnBorrow, boolean testOnReturn) {
+               this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle,
+                               DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn,
+                               DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
+                               DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
+                               DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #setWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #setMaxWait})
+        * @param maxIdle
+        *            the maximum number of idle objects in my pool (see
+        *            {@link #setMaxIdle})
+        * @param testOnBorrow
+        *            whether or not to validate objects before they are returned by
+        *            the {@link #borrowObject} method (see {@link #setTestOnBorrow}
+        *            )
+        * @param testOnReturn
+        *            whether or not to validate objects after they are returned to
+        *            the {@link #returnObject} method (see {@link #setTestOnReturn}
+        *            )
+        * @param timeBetweenEvictionRunsMillis
+        *            the amount of time (in milliseconds) to sleep between
+        *            examining idle objects for eviction (see
+        *            {@link #setTimeBetweenEvictionRunsMillis})
+        * @param numTestsPerEvictionRun
+        *            the number of idle objects to examine per run within the idle
+        *            object eviction thread (if any) (see
+        *            {@link #setNumTestsPerEvictionRun})
+        * @param minEvictableIdleTimeMillis
+        *            the minimum number of milliseconds an object can sit idle in
+        *            the pool before it is eligible for eviction (see
+        *            {@link #setMinEvictableIdleTimeMillis})
+        * @param testWhileIdle
+        *            whether or not to validate objects in the idle object eviction
+        *            thread, if any (see {@link #setTestWhileIdle})
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait, int maxIdle,
+                       boolean testOnBorrow, boolean testOnReturn,
+                       long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun,
+                       long minEvictableIdleTimeMillis, boolean testWhileIdle) {
+               this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle,
+                               DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn,
+                               timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
+                               minEvictableIdleTimeMillis, testWhileIdle);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #setWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #setMaxWait})
+        * @param maxIdle
+        *            the maximum number of idle objects in my pool (see
+        *            {@link #setMaxIdle})
+        * @param minIdle
+        *            the minimum number of idle objects in my pool (see
+        *            {@link #setMinIdle})
+        * @param testOnBorrow
+        *            whether or not to validate objects before they are returned by
+        *            the {@link #borrowObject} method (see {@link #setTestOnBorrow}
+        *            )
+        * @param testOnReturn
+        *            whether or not to validate objects after they are returned to
+        *            the {@link #returnObject} method (see {@link #setTestOnReturn}
+        *            )
+        * @param timeBetweenEvictionRunsMillis
+        *            the amount of time (in milliseconds) to sleep between
+        *            examining idle objects for eviction (see
+        *            {@link #setTimeBetweenEvictionRunsMillis})
+        * @param numTestsPerEvictionRun
+        *            the number of idle objects to examine per run within the idle
+        *            object eviction thread (if any) (see
+        *            {@link #setNumTestsPerEvictionRun})
+        * @param minEvictableIdleTimeMillis
+        *            the minimum number of milliseconds an object can sit idle in
+        *            the pool before it is eligible for eviction (see
+        *            {@link #setMinEvictableIdleTimeMillis})
+        * @param testWhileIdle
+        *            whether or not to validate objects in the idle object eviction
+        *            thread, if any (see {@link #setTestWhileIdle})
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle,
+                       boolean testOnBorrow, boolean testOnReturn,
+                       long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun,
+                       long minEvictableIdleTimeMillis, boolean testWhileIdle) {
+               this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle,
+                               minIdle, testOnBorrow, testOnReturn,
+                               timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
+                               minEvictableIdleTimeMillis, testWhileIdle,
+                               DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #setWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #setMaxWait})
+        * @param maxIdle
+        *            the maximum number of idle objects in my pool (see
+        *            {@link #setMaxIdle})
+        * @param minIdle
+        *            the minimum number of idle objects in my pool (see
+        *            {@link #setMinIdle})
+        * @param testOnBorrow
+        *            whether or not to validate objects before they are returned by
+        *            the {@link #borrowObject} method (see {@link #setTestOnBorrow}
+        *            )
+        * @param testOnReturn
+        *            whether or not to validate objects after they are returned to
+        *            the {@link #returnObject} method (see {@link #setTestOnReturn}
+        *            )
+        * @param timeBetweenEvictionRunsMillis
+        *            the amount of time (in milliseconds) to sleep between
+        *            examining idle objects for eviction (see
+        *            {@link #setTimeBetweenEvictionRunsMillis})
+        * @param numTestsPerEvictionRun
+        *            the number of idle objects to examine per run within the idle
+        *            object eviction thread (if any) (see
+        *            {@link #setNumTestsPerEvictionRun})
+        * @param minEvictableIdleTimeMillis
+        *            the minimum number of milliseconds an object can sit idle in
+        *            the pool before it is eligible for eviction (see
+        *            {@link #setMinEvictableIdleTimeMillis})
+        * @param testWhileIdle
+        *            whether or not to validate objects in the idle object eviction
+        *            thread, if any (see {@link #setTestWhileIdle})
+        * @param softMinEvictableIdleTimeMillis
+        *            the minimum number of milliseconds an object can sit idle in
+        *            the pool before it is eligible for eviction with the extra
+        *            condition that at least "minIdle" amount of object remain in
+        *            the pool. (see {@link #setSoftMinEvictableIdleTimeMillis})
+        * @since Pool 1.3
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle,
+                       boolean testOnBorrow, boolean testOnReturn,
+                       long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun,
+                       long minEvictableIdleTimeMillis, boolean testWhileIdle,
+                       long softMinEvictableIdleTimeMillis) {
+               this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle,
+                               minIdle, testOnBorrow, testOnReturn,
+                               timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
+                               minEvictableIdleTimeMillis, testWhileIdle,
+                               softMinEvictableIdleTimeMillis, DEFAULT_LIFO);
+       }
+
+       /**
+        * Create a new <tt>GenericObjectPool</tt> using the specified values.
+        * 
+        * @param factory
+        *            the (possibly <tt>null</tt>)PoolableObjectFactory to use to
+        *            create, validate and destroy objects
+        * @param maxActive
+        *            the maximum number of objects that can be borrowed from me at
+        *            one time (see {@link #setMaxActive})
+        * @param whenExhaustedAction
+        *            the action to take when the pool is exhausted (see
+        *            {@link #setWhenExhaustedAction})
+        * @param maxWait
+        *            the maximum amount of time to wait for an idle object when the
+        *            pool is exhausted an and <i>whenExhaustedAction</i> is
+        *            {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see
+        *            {@link #setMaxWait})
+        * @param maxIdle
+        *            the maximum number of idle objects in my pool (see
+        *            {@link #setMaxIdle})
+        * @param minIdle
+        *            the minimum number of idle objects in my pool (see
+        *            {@link #setMinIdle})
+        * @param testOnBorrow
+        *            whether or not to validate objects before they are returned by
+        *            the {@link #borrowObject} method (see {@link #setTestOnBorrow}
+        *            )
+        * @param testOnReturn
+        *            whether or not to validate objects after they are returned to
+        *            the {@link #returnObject} method (see {@link #setTestOnReturn}
+        *            )
+        * @param timeBetweenEvictionRunsMillis
+        *            the amount of time (in milliseconds) to sleep between
+        *            examining idle objects for eviction (see
+        *            {@link #setTimeBetweenEvictionRunsMillis})
+        * @param numTestsPerEvictionRun
+        *            the number of idle objects to examine per run within the idle
+        *            object eviction thread (if any) (see
+        *            {@link #setNumTestsPerEvictionRun})
+        * @param minEvictableIdleTimeMillis
+        *            the minimum number of milliseconds an object can sit idle in
+        *            the pool before it is eligible for eviction (see
+        *            {@link #setMinEvictableIdleTimeMillis})
+        * @param testWhileIdle
+        *            whether or not to validate objects in the idle object eviction
+        *            thread, if any (see {@link #setTestWhileIdle})
+        * @param softMinEvictableIdleTimeMillis
+        *            the minimum number of milliseconds an object can sit idle in
+        *            the pool before it is eligible for eviction with the extra
+        *            condition that at least "minIdle" amount of object remain in
+        *            the pool. (see {@link #setSoftMinEvictableIdleTimeMillis})
+        * @param lifo
+        *            whether or not objects are returned in last-in-first-out order
+        *            from the idle object pool (see {@link #setLifo})
+        * @since Pool 1.4
+        */
+       public GenericObjectPool(PoolableObjectFactory factory, int maxActive,
+                       byte whenExhaustedAction, long maxWait, int maxIdle, int minIdle,
+                       boolean testOnBorrow, boolean testOnReturn,
+                       long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun,
+                       long minEvictableIdleTimeMillis, boolean testWhileIdle,
+                       long softMinEvictableIdleTimeMillis, boolean lifo) {
+               _factory = factory;
+               _maxActive = maxActive;
+               _lifo = lifo;
+               switch (whenExhaustedAction) {
+               case WHEN_EXHAUSTED_BLOCK:
+               case WHEN_EXHAUSTED_FAIL:
+               case WHEN_EXHAUSTED_GROW:
+                       _whenExhaustedAction = whenExhaustedAction;
+                       break;
+               default:
+                       throw new IllegalArgumentException("whenExhaustedAction "
+                                       + whenExhaustedAction + " not recognized.");
+               }
+               _maxWait = maxWait;
+               _maxIdle = maxIdle;
+               _minIdle = minIdle;
+               _testOnBorrow = testOnBorrow;
+               _testOnReturn = testOnReturn;
+               _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+               _numTestsPerEvictionRun = numTestsPerEvictionRun;
+               _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+               _softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
+               _testWhileIdle = testWhileIdle;
+
+               _pool = new CursorableLinkedList();
+               startEvictor(_timeBetweenEvictionRunsMillis);
+       }
+
+       // --- public methods ---------------------------------------------
+
+       // --- configuration methods --------------------------------------
+
+       /**
+        * Returns the cap on the total number of active instances from the pool.
+        * 
+        * @return the cap on the total number of active instances from the pool.
+        * @see #setMaxActive
+        */
+       public synchronized int getMaxActive() {
+               return _maxActive;
+       }
+
+       /**
+        * Sets the cap on the total number of active instances from the pool.
+        * 
+        * @param maxActive
+        *            The cap on the total number of active instances from the pool.
+        *            Use a negative value for no limit.
+        * @see #getMaxActive
+        */
+       public synchronized void setMaxActive(int maxActive) {
+               _maxActive = maxActive;
+               notifyAll();
+       }
+
+       /**
+        * Returns the action to take when the {@link #borrowObject} method is
+        * invoked when the pool is exhausted (the maximum number of "active"
+        * objects has been reached).
+        * 
+        * @return one of {@link #WHEN_EXHAUSTED_BLOCK},
+        *         {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW}
+        * @see #setWhenExhaustedAction
+        */
+       public synchronized byte getWhenExhaustedAction() {
+               return _whenExhaustedAction;
+       }
+
+       /**
+        * Sets the action to take when the {@link #borrowObject} method is invoked
+        * when the pool is exhausted (the maximum number of "active" objects has
+        * been reached).
+        * 
+        * @param whenExhaustedAction
+        *            the action code, which must be one of
+        *            {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL},
+        *            or {@link #WHEN_EXHAUSTED_GROW}
+        * @see #getWhenExhaustedAction
+        */
+       public synchronized void setWhenExhaustedAction(byte whenExhaustedAction) {
+               switch (whenExhaustedAction) {
+               case WHEN_EXHAUSTED_BLOCK:
+               case WHEN_EXHAUSTED_FAIL:
+               case WHEN_EXHAUSTED_GROW:
+                       _whenExhaustedAction = whenExhaustedAction;
+                       notifyAll();
+                       break;
+               default:
+                       throw new IllegalArgumentException("whenExhaustedAction "
+                                       + whenExhaustedAction + " not recognized.");
+               }
+       }
+
+       /**
+        * Returns the maximum amount of time (in milliseconds) the
+        * {@link #borrowObject} method should block before throwing an exception
+        * when the pool is exhausted and the {@link #setWhenExhaustedAction
+        * "when exhausted" action} is {@link #WHEN_EXHAUSTED_BLOCK}.
+        * 
+        * When less than or equal to 0, the {@link #borrowObject} method may block
+        * indefinitely.
+        * 
+        * @return maximum number of milliseconds to block when borrowing an object.
+        * @see #setMaxWait
+        * @see #setWhenExhaustedAction
+        * @see #WHEN_EXHAUSTED_BLOCK
+        */
+       public synchronized long getMaxWait() {
+               return _maxWait;
+       }
+
+       /**
+        * Sets the maximum amount of time (in milliseconds) the
+        * {@link #borrowObject} method should block before throwing an exception
+        * when the pool is exhausted and the {@link #setWhenExhaustedAction
+        * "when exhausted" action} is {@link #WHEN_EXHAUSTED_BLOCK}.
+        * 
+        * When less than or equal to 0, the {@link #borrowObject} method may block
+        * indefinitely.
+        * 
+        * @param maxWait
+        *            maximum number of milliseconds to block when borrowing an
+        *            object.
+        * @see #getMaxWait
+        * @see #setWhenExhaustedAction
+        * @see #WHEN_EXHAUSTED_BLOCK
+        */
+       public synchronized void setMaxWait(long maxWait) {
+               _maxWait = maxWait;
+               notifyAll();
+       }
+
+       /**
+        * Returns the cap on the number of "idle" instances in the pool.
+        * 
+        * @return the cap on the number of "idle" instances in the pool.
+        * @see #setMaxIdle
+        */
+       public synchronized int getMaxIdle() {
+               return _maxIdle;
+       }
+
+       /**
+        * Sets the cap on the number of "idle" instances in the pool.
+        * 
+        * @param maxIdle
+        *            The cap on the number of "idle" instances in the pool. Use a
+        *            negative value to indicate an unlimited number of idle
+        *            instances.
+        * @see #getMaxIdle
+        */
+       public synchronized void setMaxIdle(int maxIdle) {
+               _maxIdle = maxIdle;
+               notifyAll();
+       }
+
+       /**
+        * Sets the minimum number of objects allowed in the pool before the evictor
+        * thread (if active) spawns new objects. Note that no objects are created
+        * when <code>numActive + numIdle >= maxActive.</code> This setting has no
+        * effect if the idle object evictor is disabled (i.e. if
+        * <code>timeBetweenEvictionRunsMillis <= 0</code>).
+        * 
+        * @param minIdle
+        *            The minimum number of objects.
+        * @see #getMinIdle
+        * @see #getTimeBetweenEvictionRunsMillis()
+        */
+       public synchronized void setMinIdle(int minIdle) {
+               _minIdle = minIdle;
+               notifyAll();
+       }
+
+       /**
+        * Returns the minimum number of objects allowed in the pool before the
+        * evictor thread (if active) spawns new objects. (Note no objects are
+        * created when: numActive + numIdle >= maxActive)
+        * 
+        * @return The minimum number of objects.
+        * @see #setMinIdle
+        */
+       public synchronized int getMinIdle() {
+               return _minIdle;
+       }
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} before being
+        * returned by the {@link #borrowObject} method. If the object fails to
+        * validate, it will be dropped from the pool, and we will attempt to borrow
+        * another.
+        * 
+        * @return <code>true</code> if objects are validated before being borrowed.
+        * @see #setTestOnBorrow
+        */
+       public boolean getTestOnBorrow() {
+               return _testOnBorrow;
+       }
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} before being
+        * returned by the {@link #borrowObject} method. If the object fails to
+        * validate, it will be dropped from the pool, and we will attempt to borrow
+        * another.
+        * 
+        * @param testOnBorrow
+        *            <code>true</code> if objects should be validated before being
+        *            borrowed.
+        * @see #getTestOnBorrow
+        */
+       public void setTestOnBorrow(boolean testOnBorrow) {
+               _testOnBorrow = testOnBorrow;
+       }
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} before being
+        * returned to the pool within the {@link #returnObject}.
+        * 
+        * @return <code>true</code> when objects will be validated after returned
+        *         to {@link #returnObject}.
+        * @see #setTestOnReturn
+        */
+       public boolean getTestOnReturn() {
+               return _testOnReturn;
+       }
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} before being
+        * returned to the pool within the {@link #returnObject}.
+        * 
+        * @param testOnReturn
+        *            <code>true</code> so objects will be validated after returned
+        *            to {@link #returnObject}.
+        * @see #getTestOnReturn
+        */
+       public void setTestOnReturn(boolean testOnReturn) {
+               _testOnReturn = testOnReturn;
+       }
+
+       /**
+        * Returns the number of milliseconds to sleep between runs of the idle
+        * object evictor thread. When non-positive, no idle object evictor thread
+        * will be run.
+        * 
+        * @return number of milliseconds to sleep between evictor runs.
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public synchronized long getTimeBetweenEvictionRunsMillis() {
+               return _timeBetweenEvictionRunsMillis;
+       }
+
+       /**
+        * Sets the number of milliseconds to sleep between runs of the idle object
+        * evictor thread. When non-positive, no idle object evictor thread will be
+        * run.
+        * 
+        * @param timeBetweenEvictionRunsMillis
+        *            number of milliseconds to sleep between evictor runs.
+        * @see #getTimeBetweenEvictionRunsMillis
+        */
+       public synchronized void setTimeBetweenEvictionRunsMillis(
+                       long timeBetweenEvictionRunsMillis) {
+               _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+               startEvictor(_timeBetweenEvictionRunsMillis);
+       }
+
+       /**
+        * Returns the max number of objects to examine during each run of the idle
+        * object evictor thread (if any).
+        * 
+        * @return max number of objects to examine during each evictor run.
+        * @see #setNumTestsPerEvictionRun
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public synchronized int getNumTestsPerEvictionRun() {
+               return _numTestsPerEvictionRun;
+       }
+
+       /**
+        * Sets the max number of objects to examine during each run of the idle
+        * object evictor thread (if any).
+        * <p>
+        * When a negative value is supplied,
+        * <tt>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</tt>
+        * tests will be run. I.e., when the value is <i>-n</i>, roughly one
+        * <i>n</i>th of the idle objects will be tested per run.
+        * 
+        * @param numTestsPerEvictionRun
+        *            max number of objects to examine during each evictor run.
+        * @see #getNumTestsPerEvictionRun
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public synchronized void setNumTestsPerEvictionRun(
+                       int numTestsPerEvictionRun) {
+               _numTestsPerEvictionRun = numTestsPerEvictionRun;
+       }
+
+       /**
+        * Returns the minimum amount of time an object may sit idle in the pool
+        * before it is eligible for eviction by the idle object evictor (if any).
+        * 
+        * @return minimum amount of time an object may sit idle in the pool before
+        *         it is eligible for eviction.
+        * @see #setMinEvictableIdleTimeMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public synchronized long getMinEvictableIdleTimeMillis() {
+               return _minEvictableIdleTimeMillis;
+       }
+
+       /**
+        * Sets the minimum amount of time an object may sit idle in the pool before
+        * it is eligible for eviction by the idle object evictor (if any). When
+        * non-positive, no objects will be evicted from the pool due to idle time
+        * alone.
+        * 
+        * @param minEvictableIdleTimeMillis
+        *            minimum amount of time an object may sit idle in the pool
+        *            before it is eligible for eviction.
+        * @see #getMinEvictableIdleTimeMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public synchronized void setMinEvictableIdleTimeMillis(
+                       long minEvictableIdleTimeMillis) {
+               _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+       }
+
+       /**
+        * Returns the minimum amount of time an object may sit idle in the pool
+        * before it is eligible for eviction by the idle object evictor (if any),
+        * with the extra condition that at least "minIdle" amount of object remain
+        * in the pool.
+        * 
+        * @return minimum amount of time an object may sit idle in the pool before
+        *         it is eligible for eviction.
+        * @since Pool 1.3
+        * @see #setSoftMinEvictableIdleTimeMillis
+        */
+       public synchronized long getSoftMinEvictableIdleTimeMillis() {
+               return _softMinEvictableIdleTimeMillis;
+       }
+
+       /**
+        * Sets the minimum amount of time an object may sit idle in the pool before
+        * it is eligible for eviction by the idle object evictor (if any), with the
+        * extra condition that at least "minIdle" amount of object remain in the
+        * pool. When non-positive, no objects will be evicted from the pool due to
+        * idle time alone.
+        * 
+        * @param softMinEvictableIdleTimeMillis
+        *            minimum amount of time an object may sit idle in the pool
+        *            before it is eligible for eviction.
+        * @since Pool 1.3
+        * @see #getSoftMinEvictableIdleTimeMillis
+        */
+       public synchronized void setSoftMinEvictableIdleTimeMillis(
+                       long softMinEvictableIdleTimeMillis) {
+               _softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
+       }
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} by the idle object
+        * evictor (if any). If an object fails to validate, it will be dropped from
+        * the pool.
+        * 
+        * @return <code>true</code> when objects will be validated by the evictor.
+        * @see #setTestWhileIdle
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public synchronized boolean getTestWhileIdle() {
+               return _testWhileIdle;
+       }
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} by the idle object
+        * evictor (if any). If an object fails to validate, it will be dropped from
+        * the pool.
+        * 
+        * @param testWhileIdle
+        *            <code>true</code> so objects will be validated by the evictor.
+        * @see #getTestWhileIdle
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       public synchronized void setTestWhileIdle(boolean testWhileIdle) {
+               _testWhileIdle = testWhileIdle;
+       }
+
+       /**
+        * Whether or not the idle object pool acts as a LIFO queue. True means that
+        * borrowObject returns the most recently used ("last in") idle object in
+        * the pool (if there are idle instances available). False means that the
+        * pool behaves as a FIFO queue - objects are taken from the idle object
+        * pool in the order that they are returned to the pool.
+        * 
+        * @return <code>true</true> if the pool is configured to act as a LIFO queue
+        * @since 1.4
+        */
+       public synchronized boolean getLifo() {
+               return _lifo;
+       }
+
+       /**
+        * Sets the LIFO property of the pool. True means that borrowObject returns
+        * the most recently used ("last in") idle object in the pool (if there are
+        * idle instances available). False means that the pool behaves as a FIFO
+        * queue - objects are taken from the idle object pool in the order that
+        * they are returned to the pool.
+        * 
+        * @param lifo
+        *            the new value for the LIFO property
+        * @since 1.4
+        */
+       public synchronized void setLifo(boolean lifo) {
+               this._lifo = lifo;
+       }
+
+       /**
+        * Sets my configuration.
+        * 
+        * @param conf
+        *            configuration to use.
+        * @see GenericObjectPool.Config
+        */
+       public synchronized void setConfig(GenericObjectPool.Config conf) {
+               setMaxIdle(conf.maxIdle);
+               setMinIdle(conf.minIdle);
+               setMaxActive(conf.maxActive);
+               setMaxWait(conf.maxWait);
+               setWhenExhaustedAction(conf.whenExhaustedAction);
+               setTestOnBorrow(conf.testOnBorrow);
+               setTestOnReturn(conf.testOnReturn);
+               setTestWhileIdle(conf.testWhileIdle);
+               setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
+               setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
+               setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
+               setSoftMinEvictableIdleTimeMillis(conf.softMinEvictableIdleTimeMillis);
+               setLifo(conf.lifo);
+               notifyAll();
+       }
+
+       // -- ObjectPool methods ------------------------------------------
+
+       public Object borrowObject() throws Exception {
+               ObjectTimestampPair pair = null;
+
+               synchronized (this) {
+                       try {
+                               pair = (ObjectTimestampPair) (_pool.removeFirst());
+                       } catch (NoSuchElementException e) {
+                               ; /* ignored */
+                       }
+                       _numActive++;
+               }
+
+               // create new object when needed
+               if (null == pair) {
+                       Object obj = _factory.makeObject();
+                       pair = new ObjectTimestampPair(obj);
+               }
+
+               // activate & validate the object
+               return pair.value;
+       }
+
+       public void invalidateObject(Object obj) throws Exception {
+               try {
+                       if (_factory != null) {
+                               _factory.destroyObject(obj);
+                       }
+               } finally {
+                       synchronized (this) {
+                               _numActive--;
+                               notifyAll(); // _numActive has changed
+                       }
+               }
+       }
+
+       /**
+        * Clears any objects sitting idle in the pool.
+        */
+       public synchronized void clear() {
+               for (Iterator it = _pool.iterator(); it.hasNext();) {
+                       try {
+                               _factory.destroyObject(((ObjectTimestampPair) (it.next())).value);
+                       } catch (Exception e) {
+                               // ignore error, keep destroying the rest
+                       }
+                       it.remove();
+               }
+               _pool.clear();
+               notifyAll(); // num sleeping has changed
+       }
+
+       /**
+        * Return the number of instances currently borrowed from this pool.
+        * 
+        * @return the number of instances currently borrowed from this pool
+        */
+       public synchronized int getNumActive() {
+               return _numActive;
+       }
+
+       /**
+        * Return the number of instances currently idle in this pool.
+        * 
+        * @return the number of instances currently idle in this pool
+        */
+       public synchronized int getNumIdle() {
+               return _pool.size();
+       }
+
+       /**
+        * {@inheritDoc}
+        * <p>
+        * <strong>Note: </strong> There is no guard to prevent an object being
+        * returned to the pool multiple times. Clients are expected to discard
+        * references to returned objects and ensure that an object is not returned
+        * to the pool multiple times in sequence (i.e., without being borrowed
+        * again between returns). Violating this contract will result in the same
+        * object appearing multiple times in the pool and pool counters (numActive,
+        * numIdle) returning incorrect values.
+        * </p>
+        */
+       public void returnObject(Object obj) throws Exception {
+               try {
+                       addObjectToPool(obj, true);
+               } catch (Exception e) {
+                       if (_factory != null) {
+                               try {
+                                       _factory.destroyObject(obj);
+                               } catch (Exception e2) {
+                                       // swallowed
+                               }
+                               // TODO: Correctness here depends on control in addObjectToPool.
+                               // These two methods should be refactored, removing the
+                               // "behavior flag",decrementNumActive, from addObjectToPool.
+                               synchronized (this) {
+                                       _numActive--;
+                                       notifyAll();
+                               }
+                       }
+               }
+       }
+
+       private void addObjectToPool(Object obj, boolean decrementNumActive)
+                       throws Exception {
+               boolean success = true;
+               if (_testOnReturn && !(_factory.validateObject(obj))) {
+                       success = false;
+               } else {
+                       _factory.passivateObject(obj);
+               }
+
+               boolean shouldDestroy = !success;
+
+               // Add instance to pool if there is room and it has passed validation
+               // (if testOnreturn is set)
+               synchronized (this) {
+                       if (isClosed()) {
+                               shouldDestroy = true;
+                       } else {
+                               if ((_maxIdle >= 0) && (_pool.size() >= _maxIdle)) {
+                                       shouldDestroy = true;
+                               } else if (success) {
+                                       // borrowObject always takes the first element from the
+                                       // queue,
+                                       // so for LIFO, push on top, FIFO add to end
+                                       if (_lifo) {
+                                               _pool.addFirst(new ObjectTimestampPair(obj));
+                                       } else {
+                                               _pool.addLast(new ObjectTimestampPair(obj));
+                                       }
+                               }
+                       }
+               }
+
+               // Destroy the instance if necessary
+               if (shouldDestroy) {
+                       try {
+                               _factory.destroyObject(obj);
+                       } catch (Exception e) {
+                               // ignored
+                       }
+               }
+
+               // Decrement active count *after* destroy if applicable
+               if (decrementNumActive) {
+                       synchronized (this) {
+                               _numActive--;
+                               notifyAll();
+                       }
+               }
+       }
+
+       public void close() throws Exception {
+               super.close();
+               synchronized (this) {
+                       clear();
+                       startEvictor(-1L);
+               }
+       }
+
+       /**
+        * Sets the {@link PoolableObjectFactory factory} this pool uses to create
+        * new instances. Trying to change the <code>factory</code> while there are
+        * borrowed objects will throw an {@link IllegalStateException}.
+        * 
+        * @param factory
+        *            the {@link PoolableObjectFactory} used to create new
+        *            instances.
+        * @throws IllegalStateException
+        *             when the factory cannot be set at this time
+        */
+       public synchronized void setFactory(PoolableObjectFactory factory)
+                       throws IllegalStateException {
+               assertOpen();
+               if (0 < getNumActive()) {
+                       throw new IllegalStateException("Objects are already active");
+               } else {
+                       clear();
+                       _factory = factory;
+               }
+       }
+
+       /**
+        * <p>
+        * Perform <code>numTests</code> idle object eviction tests, evicting
+        * examined objects that meet the criteria for eviction. If
+        * <code>testWhileIdle</code> is true, examined objects are validated when
+        * visited (and removed if invalid); otherwise only objects that have been
+        * idle for more than <code>minEvicableIdletimeMillis</code> are removed.
+        * </p>
+        * 
+        * <p>
+        * Successive activations of this method examine objects in in sequence,
+        * cycling through objects in oldest-to-youngest order.
+        * </p>
+        * 
+        * @throws Exception
+        *             if the pool is closed or eviction fails.
+        */
+       public synchronized void evict() throws Exception {
+               assertOpen();
+               if (!_pool.isEmpty()) {
+                       if (null == _evictionCursor) {
+                               _evictionCursor = (_pool.cursor(_lifo ? _pool.size() : 0));
+                       }
+                       for (int i = 0, m = getNumTests(); i < m; i++) {
+                               if ((_lifo && !_evictionCursor.hasPrevious()) || !_lifo
+                                               && !_evictionCursor.hasNext()) {
+                                       _evictionCursor.close();
+                                       _evictionCursor = _pool.cursor(_lifo ? _pool.size() : 0);
+                               }
+                               boolean removeObject = false;
+                               final ObjectTimestampPair pair = _lifo ? (ObjectTimestampPair) _evictionCursor
+                                               .previous() : (ObjectTimestampPair) _evictionCursor
+                                               .next();
+                               final long idleTimeMilis = System.currentTimeMillis()
+                                               - pair.tstamp;
+                               if ((_minEvictableIdleTimeMillis > 0)
+                                               && (idleTimeMilis > _minEvictableIdleTimeMillis)) {
+                                       removeObject = true;
+                               } else if ((_softMinEvictableIdleTimeMillis > 0)
+                                               && (idleTimeMilis > _softMinEvictableIdleTimeMillis)
+                                               && (getNumIdle() > getMinIdle())) {
+                                       removeObject = true;
+                               }
+                               if (_testWhileIdle && !removeObject) {
+                                       boolean active = false;
+                                       try {
+                                               _factory.activateObject(pair.value);
+                                               active = true;
+                                       } catch (Exception e) {
+                                               removeObject = true;
+                                       }
+                                       if (active) {
+                                               if (!_factory.validateObject(pair.value)) {
+                                                       removeObject = true;
+                                               } else {
+                                                       try {
+                                                               _factory.passivateObject(pair.value);
+                                                       } catch (Exception e) {
+                                                               removeObject = true;
+                                                       }
+                                               }
+                                       }
+                               }
+                               if (removeObject) {
+                                       try {
+                                               _evictionCursor.remove();
+                                               _factory.destroyObject(pair.value);
+                                       } catch (Exception e) {
+                                               // ignored
+                                       }
+                               }
+                       }
+               } // if !empty
+       }
+
+       /**
+        * Check to see if we are below our minimum number of objects if so enough
+        * to bring us back to our minimum.
+        * 
+        * @throws Exception
+        *             when {@link #addObject()} fails.
+        */
+       public void ensureMinIdle() throws Exception {
+               // this method isn't synchronized so the
+               // calculateDeficit is done at the beginning
+               // as a loop limit and a second time inside the loop
+               // to stop when another thread already returned the
+               // needed objects
+               int objectDeficit = calculateDeficit();
+               for (int j = 0; j < objectDeficit; j++) {
+                       addObject();
+               }
+       }
+
+       private synchronized int calculateDeficit() {
+               //int objectDeficit = getMinIdle() - getNumIdle();
+               int objectDeficit = 1 - getNumIdle();
+//             int growLimit = Math.max(0, getMaxActive() - getNumActive()
+//                             - getNumIdle());
+               int growLimit = Math.max(0, 2 - getNumActive() - getNumIdle());
+               objectDeficit = Math.min(objectDeficit, growLimit);
+               return objectDeficit;
+       }
+
+       /**
+        * Create an object, and place it into the pool. addObject() is useful for
+        * "pre-loading" a pool with idle objects.
+        */
+       public synchronized void addObject() throws Exception {
+               Object obj = _factory.makeObject();
+               try {
+                       _pool.addFirst(new ObjectTimestampPair(obj));
+               } catch (IllegalStateException ex) { // Pool closed
+                       throw ex;
+               }
+       }
+
+       // --- non-public methods ----------------------------------------
+
+       /**
+        * Start the eviction thread or service, or when <i>delay</i> is
+        * non-positive, stop it if it is already running.
+        * 
+        * @param delay
+        *            milliseconds between evictor runs.
+        */
+       protected synchronized void startEvictor(long delay) {
+               if (null != _evictor) {
+                       EvictionTimer.cancel(_evictor);
+                       _evictor = null;
+               }
+               if (delay > 0) {
+                       _evictor = new Evictor();
+                       EvictionTimer.schedule(_evictor, delay, delay);
+               }
+       }
+
+       synchronized String debugInfo() {
+               StringBuffer buf = new StringBuffer();
+               buf.append("Active: ").append(getNumActive()).append("\n");
+               buf.append("Idle: ").append(getNumIdle()).append("\n");
+               buf.append("Idle Objects:\n");
+               Iterator it = _pool.iterator();
+               long time = System.currentTimeMillis();
+               while (it.hasNext()) {
+                       ObjectTimestampPair pair = (ObjectTimestampPair) (it.next());
+                       buf.append("\t").append(pair.value).append("\t")
+                                       .append(time - pair.tstamp).append("\n");
+               }
+               return buf.toString();
+       }
+
+       private int getNumTests() {
+               if (_numTestsPerEvictionRun >= 0) {
+                       return Math.min(_numTestsPerEvictionRun, _pool.size());
+               } else {
+                       return (int) (Math.ceil((double) _pool.size()
+                                       / Math.abs((double) _numTestsPerEvictionRun)));
+               }
+       }
+
+       // --- inner classes ----------------------------------------------
+
+       /**
+        * The idle object evictor {@link TimerTask}.
+        * 
+        * @see GenericObjectPool#setTimeBetweenEvictionRunsMillis
+        */
+       private class Evictor extends TimerTask {
+               public void run() {
+                       try {
+                               evict();
+                       } catch (Exception e) {
+                               // ignored
+                       }
+                       try {
+                               ensureMinIdle();
+                       } catch (Exception e) {
+                               // ignored
+                       }
+               }
+       }
+
+       /**
+        * A simple "struct" encapsulating the configuration information for a
+        * {@link GenericObjectPool}.
+        * 
+        * @see GenericObjectPool#GenericObjectPool(org.apache.commons.pool.PoolableObjectFactory,org.apache.commons.pool.impl.GenericObjectPool.Config)
+        * @see GenericObjectPool#setConfig
+        */
+       public static class Config {
+               /**
+                * @see GenericObjectPool#setMaxIdle
+                */
+               public int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
+               /**
+                * @see GenericObjectPool#setMinIdle
+                */
+               public int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;
+               /**
+                * @see GenericObjectPool#setMaxActive
+                */
+               public int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;
+               /**
+                * @see GenericObjectPool#setMaxWait
+                */
+               public long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;
+               /**
+                * @see GenericObjectPool#setWhenExhaustedAction
+                */
+               public byte whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
+               /**
+                * @see GenericObjectPool#setTestOnBorrow
+                */
+               public boolean testOnBorrow = GenericObjectPool.DEFAULT_TEST_ON_BORROW;
+               /**
+                * @see GenericObjectPool#setTestOnReturn
+                */
+               public boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN;
+               /**
+                * @see GenericObjectPool#setTestWhileIdle
+                */
+               public boolean testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE;
+               /**
+                * @see GenericObjectPool#setTimeBetweenEvictionRunsMillis
+                */
+               public long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
+               /**
+                * @see GenericObjectPool#setNumTestsPerEvictionRun
+                */
+               public int numTestsPerEvictionRun = GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
+               /**
+                * @see GenericObjectPool#setMinEvictableIdleTimeMillis
+                */
+               public long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+               /**
+                * @see GenericObjectPool#setSoftMinEvictableIdleTimeMillis
+                */
+               public long softMinEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+               /**
+                * @see GenericObjectPool#setLifo
+                */
+               public boolean lifo = GenericObjectPool.DEFAULT_LIFO;
+
+       }
+
+       // --- private attributes ---------------------------------------
+
+       /**
+        * The cap on the number of idle instances in the pool.
+        * 
+        * @see #setMaxIdle
+        * @see #getMaxIdle
+        */
+       private int _maxIdle = DEFAULT_MAX_IDLE;
+
+       /**
+        * The cap on the minimum number of idle instances in the pool.
+        * 
+        * @see #setMinIdle
+        * @see #getMinIdle
+        */
+       private int _minIdle = DEFAULT_MIN_IDLE;
+
+       /**
+        * The cap on the total number of active instances from the pool.
+        * 
+        * @see #setMaxActive
+        * @see #getMaxActive
+        */
+       private int _maxActive = DEFAULT_MAX_ACTIVE;
+
+       /**
+        * The maximum amount of time (in millis) the {@link #borrowObject} method
+        * should block before throwing an exception when the pool is exhausted and
+        * the {@link #getWhenExhaustedAction "when exhausted" action} is
+        * {@link #WHEN_EXHAUSTED_BLOCK}.
+        * 
+        * When less than or equal to 0, the {@link #borrowObject} method may block
+        * indefinitely.
+        * 
+        * @see #setMaxWait
+        * @see #getMaxWait
+        * @see #WHEN_EXHAUSTED_BLOCK
+        * @see #setWhenExhaustedAction
+        * @see #getWhenExhaustedAction
+        */
+       private long _maxWait = DEFAULT_MAX_WAIT;
+
+       /**
+        * The action to take when the {@link #borrowObject} method is invoked when
+        * the pool is exhausted (the maximum number of "active" objects has been
+        * reached).
+        * 
+        * @see #WHEN_EXHAUSTED_BLOCK
+        * @see #WHEN_EXHAUSTED_FAIL
+        * @see #WHEN_EXHAUSTED_GROW
+        * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
+        * @see #setWhenExhaustedAction
+        * @see #getWhenExhaustedAction
+        */
+       private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} before being
+        * returned by the {@link #borrowObject} method. If the object fails to
+        * validate, it will be dropped from the pool, and we will attempt to borrow
+        * another.
+        * 
+        * @see #setTestOnBorrow
+        * @see #getTestOnBorrow
+        */
+       private volatile boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} before being
+        * returned to the pool within the {@link #returnObject}.
+        * 
+        * @see #getTestOnReturn
+        * @see #setTestOnReturn
+        */
+       private volatile boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
+
+       /**
+        * When <tt>true</tt>, objects will be
+        * {@link PoolableObjectFactory#validateObject validated} by the idle object
+        * evictor (if any). If an object fails to validate, it will be dropped from
+        * the pool.
+        * 
+        * @see #setTestWhileIdle
+        * @see #getTestWhileIdle
+        * @see #getTimeBetweenEvictionRunsMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
+
+       /**
+        * The number of milliseconds to sleep between runs of the idle object
+        * evictor thread. When non-positive, no idle object evictor thread will be
+        * run.
+        * 
+        * @see #setTimeBetweenEvictionRunsMillis
+        * @see #getTimeBetweenEvictionRunsMillis
+        */
+       private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
+
+       /**
+        * The max number of objects to examine during each run of the idle object
+        * evictor thread (if any).
+        * <p>
+        * When a negative value is supplied,
+        * <tt>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</tt>
+        * tests will be run. I.e., when the value is <i>-n</i>, roughly one
+        * <i>n</i>th of the idle objects will be tested per run.
+        * 
+        * @see #setNumTestsPerEvictionRun
+        * @see #getNumTestsPerEvictionRun
+        * @see #getTimeBetweenEvictionRunsMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       private int _numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
+
+       /**
+        * The minimum amount of time an object may sit idle in the pool before it
+        * is eligible for eviction by the idle object evictor (if any). When
+        * non-positive, no objects will be evicted from the pool due to idle time
+        * alone.
+        * 
+        * @see #setMinEvictableIdleTimeMillis
+        * @see #getMinEvictableIdleTimeMillis
+        * @see #getTimeBetweenEvictionRunsMillis
+        * @see #setTimeBetweenEvictionRunsMillis
+        */
+       private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+
+       /**
+        * The minimum amount of time an object may sit idle in the pool before it
+        * is eligible for eviction by the idle object evictor (if any), with the
+        * extra condition that at least "minIdle" amount of object remain in the
+        * pool. When non-positive, no objects will be evicted from the pool due to
+        * idle time alone.
+        * 
+        * @see #setSoftMinEvictableIdleTimeMillis
+        * @see #getSoftMinEvictableIdleTimeMillis
+        */
+       private long _softMinEvictableIdleTimeMillis = DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+
+       /** Whether or not the pool behaves as a LIFO queue (last in first out) */
+       private boolean _lifo = DEFAULT_LIFO;
+
+       /** My pool. */
+       private CursorableLinkedList _pool = null;
+
+       /** Eviction cursor - keeps track of idle object evictor position */
+       private CursorableLinkedList.Cursor _evictionCursor = null;
+
+       /** My {@link PoolableObjectFactory}. */
+       private PoolableObjectFactory _factory = null;
+
+       /**
+        * The number of objects {@link #borrowObject} borrowed from the pool, but
+        * not yet returned.
+        */
+       public int _numActive = 0;
+
+       /**
+        * My idle object eviction {@link TimerTask}, if any.
+        */
+       private Evictor _evictor = null;
+
+}