You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/07/31 13:23:23 UTC

[commons-dbutils] 02/25: Sort members

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-dbutils.git

commit abb021d114da2628ca10758f47c70310b2b56c05
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Jul 31 09:01:10 2023 -0400

    Sort members
---
 .../commons/dbutils/AbstractQueryRunner.java       |   44 +-
 .../apache/commons/dbutils/AsyncQueryRunner.java   |  654 +++++-----
 .../commons/dbutils/BaseResultSetHandler.java      |  316 ++---
 .../apache/commons/dbutils/BasicRowProcessor.java  |  194 +--
 .../org/apache/commons/dbutils/BeanProcessor.java  |  488 ++++----
 .../org/apache/commons/dbutils/ColumnHandler.java  |   18 +-
 .../java/org/apache/commons/dbutils/DbUtils.java   |  232 ++--
 .../org/apache/commons/dbutils/OutParameter.java   |   54 +-
 .../apache/commons/dbutils/PropertyHandler.java    |   16 +-
 .../org/apache/commons/dbutils/ProxyFactory.java   |   24 +-
 .../org/apache/commons/dbutils/QueryRunner.java    |  992 +++++++--------
 .../apache/commons/dbutils/ResultSetIterator.java  |   34 +-
 .../commons/dbutils/StatementConfiguration.java    |  196 +--
 .../dbutils/handlers/AbstractKeyedHandler.java     |   44 +-
 .../commons/dbutils/handlers/BeanMapHandler.java   |   42 +-
 .../dbutils/handlers/ColumnListHandler.java        |   20 +-
 .../commons/dbutils/handlers/KeyedHandler.java     |   32 +-
 .../commons/dbutils/handlers/ScalarHandler.java    |   20 +-
 .../handlers/columns/BooleanColumnHandler.java     |    8 +-
 .../handlers/columns/ByteColumnHandler.java        |    8 +-
 .../handlers/columns/DoubleColumnHandler.java      |    8 +-
 .../handlers/columns/FloatColumnHandler.java       |    8 +-
 .../handlers/columns/IntegerColumnHandler.java     |    8 +-
 .../handlers/columns/LongColumnHandler.java        |    8 +-
 .../handlers/columns/SQLXMLColumnHandler.java      |    8 +-
 .../handlers/columns/ShortColumnHandler.java       |    8 +-
 .../handlers/columns/StringColumnHandler.java      |    8 +-
 .../handlers/columns/TimestampColumnHandler.java   |    8 +-
 .../handlers/properties/DatePropertyHandler.java   |   38 +-
 .../properties/StringEnumPropertyHandler.java      |   10 +-
 .../commons/dbutils/AsyncQueryRunnerTest.java      |  490 ++++----
 .../commons/dbutils/BaseResultSetHandlerTest.java  |   40 +-
 .../org/apache/commons/dbutils/BaseTestCase.java   |   14 +-
 .../commons/dbutils/BasicRowProcessorTest.java     |   32 +-
 .../apache/commons/dbutils/BeanProcessorTest.java  |  286 ++---
 .../org/apache/commons/dbutils/DbUtilsTest.java    |  266 ++--
 .../commons/dbutils/GenerousBeanProcessorTest.java |  100 +-
 .../commons/dbutils/MockResultSetMetaData.java     |    6 +-
 .../apache/commons/dbutils/OutParameterTest.java   |   18 +-
 .../apache/commons/dbutils/ProxyFactoryTest.java   |    8 +-
 .../apache/commons/dbutils/QueryRunnerTest.java    | 1272 ++++++++++----------
 .../commons/dbutils/ResultSetIteratorTest.java     |   18 +-
 .../apache/commons/dbutils/ServiceLoaderTest.java  |   52 +-
 .../dbutils/StatementConfigurationTest.java        |   28 +-
 .../java/org/apache/commons/dbutils/TestBean.java  |   72 +-
 .../commons/dbutils/handlers/ArrayHandlerTest.java |   14 +-
 .../dbutils/handlers/ArrayListHandlerTest.java     |   16 +-
 .../commons/dbutils/handlers/BeanHandlerTest.java  |   38 +-
 .../dbutils/handlers/BeanListHandlerTest.java      |   62 +-
 .../dbutils/handlers/BeanMapHandlerTest.java       |   18 +-
 .../dbutils/handlers/ColumnListHandlerTest.java    |   22 +-
 .../commons/dbutils/handlers/KeyedHandlerTest.java |   76 +-
 .../commons/dbutils/handlers/MapHandlerTest.java   |   14 +-
 .../dbutils/handlers/MapListHandlerTest.java       |   16 +-
 .../dbutils/handlers/ScalarHandlerTest.java        |   14 +-
 .../handlers/columns/ColumnHandlerTestBase.java    |    6 +-
 .../handlers/columns/IntegerColumnHandlerTest.java |   10 +-
 .../handlers/columns/TestColumnHandler.java        |    8 +-
 .../properties/DatePropertyHandlerTest.java        |   32 +-
 .../handlers/properties/PropertyHandlerTest.java   |   26 +-
 .../handlers/properties/TestPropertyHandler.java   |    8 +-
 .../wrappers/SqlNullCheckedResultSetTest.java      |  448 +++----
 .../wrappers/StringTrimmedResultSetTest.java       |    8 +-
 63 files changed, 3543 insertions(+), 3543 deletions(-)

diff --git a/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java b/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
index a904e5c..f39330e 100644
--- a/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
+++ b/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
@@ -258,28 +258,6 @@ public abstract class AbstractQueryRunner {
         }
     }
 
-    /**
-     * Get the {@code ParameterMetaData} of the prepared statement, if the {@code pmdKnownBroken}
-     * is set to false.
-     *
-     * @param stmt
-     *            PreparedStatement of which to query the metadata of parameters
-     * @return the metadata of parameters
-     * @throws SQLException
-     *            if a database access error occurs
-     */
-    public ParameterMetaData getParameterMetaData(final PreparedStatement stmt) throws SQLException {
-        ParameterMetaData pmd = null;
-        if (!pmdKnownBroken) {
-            try {
-                pmd = stmt.getParameterMetaData();
-            } catch (final SQLFeatureNotSupportedException ex) {
-                pmdKnownBroken = true;
-            }
-        }
-        return pmd;
-    }
-
     /**
      * Fill the {@code PreparedStatement} replacement parameters with the
      * given objects.
@@ -471,6 +449,28 @@ public abstract class AbstractQueryRunner {
         return this.ds;
     }
 
+    /**
+     * Get the {@code ParameterMetaData} of the prepared statement, if the {@code pmdKnownBroken}
+     * is set to false.
+     *
+     * @param stmt
+     *            PreparedStatement of which to query the metadata of parameters
+     * @return the metadata of parameters
+     * @throws SQLException
+     *            if a database access error occurs
+     */
+    public ParameterMetaData getParameterMetaData(final PreparedStatement stmt) throws SQLException {
+        ParameterMetaData pmd = null;
+        if (!pmdKnownBroken) {
+            try {
+                pmd = stmt.getParameterMetaData();
+            } catch (final SQLFeatureNotSupportedException ex) {
+                pmdKnownBroken = true;
+            }
+        }
+        return pmd;
+    }
+
     /**
      * Some drivers don't support
      * {@link ParameterMetaData#getParameterType(int) }; if
diff --git a/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java b/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java
index c9aaa67..8aa65c1 100644
--- a/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java
+++ b/src/main/java/org/apache/commons/dbutils/AsyncQueryRunner.java
@@ -35,78 +35,6 @@ import javax.sql.DataSource;
  */
 public class AsyncQueryRunner extends AbstractQueryRunner {
 
-    private final ExecutorService executorService;
-    private final QueryRunner queryRunner;
-
-    /**
-     * Constructor for AsyncQueryRunner which uses a provided ExecutorService and underlying QueryRunner.
-     *
-     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
-     * @param queryRunner the {@code QueryRunner} instance to use for the queries.
-     * @since 1.5
-     */
-    public AsyncQueryRunner(final ExecutorService executorService, final QueryRunner queryRunner) {
-        this.executorService = executorService;
-        this.queryRunner = queryRunner;
-    }
-
-    /**
-     * Constructor for AsyncQueryRunner.
-     *
-     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
-     */
-    public AsyncQueryRunner(final ExecutorService executorService) {
-        this(null, false, executorService);
-    }
-
-    /**
-     * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
-     * Constructor for AsyncQueryRunner that controls the use of {@code ParameterMetaData}.
-     *
-     * @param pmdKnownBroken Some drivers don't support {@link java.sql.ParameterMetaData#getParameterType(int) };
-     * if {@code pmdKnownBroken} is set to true, we won't even try it; if false, we'll try it,
-     * and if it breaks, we'll remember not to use it again.
-     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
-     */
-    @Deprecated
-    public AsyncQueryRunner(final boolean pmdKnownBroken, final ExecutorService executorService) {
-        this(null, pmdKnownBroken, executorService);
-    }
-
-    /**
-     * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
-     * Constructor for AsyncQueryRunner that takes a {@code DataSource}.
-     *
-     * Methods that do not take a {@code Connection} parameter will retrieve connections from this
-     * {@code DataSource}.
-     *
-     * @param ds The {@code DataSource} to retrieve connections from.
-     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
-     */
-    @Deprecated
-    public AsyncQueryRunner(final DataSource ds, final ExecutorService executorService) {
-        this(ds, false, executorService);
-    }
-
-    /**
-     * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
-     * Constructor for AsyncQueryRunner that take a {@code DataSource} and controls the use of {@code ParameterMetaData}.
-     * Methods that do not take a {@code Connection} parameter will retrieve connections from this
-     * {@code DataSource}.
-     *
-     * @param ds The {@code DataSource} to retrieve connections from.
-     * @param pmdKnownBroken Some drivers don't support {@link java.sql.ParameterMetaData#getParameterType(int) };
-     * if {@code pmdKnownBroken} is set to true, we won't even try it; if false, we'll try it,
-     * and if it breaks, we'll remember not to use it again.
-     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
-     */
-    @Deprecated
-    public AsyncQueryRunner(final DataSource ds, final boolean pmdKnownBroken, final ExecutorService executorService) {
-        super(ds, pmdKnownBroken);
-        this.executorService = executorService;
-        this.queryRunner = new QueryRunner(ds, pmdKnownBroken);
-    }
-
     /**
      * @deprecated No longer used by this class. Will be removed in a future version.
      * Class that encapsulates the continuation for batch calls.
@@ -162,52 +90,6 @@ public class AsyncQueryRunner extends AbstractQueryRunner {
             return ret;
         }
     }
-
-    /**
-     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.
-     *
-     * @param conn The {@code Connection} to use to run the query.  The caller is
-     * responsible for closing this Connection.
-     * @param sql The SQL to execute.
-     * @param params An array of query replacement parameters.  Each row in
-     * this array is one set of batch replacement values.
-     * @return A {@code Future} which returns the number of rows updated per statement.
-     * @throws SQLException if a database access error occurs
-     */
-    public Future<int[]> batch(final Connection conn, final String sql, final Object[][] params) throws SQLException {
-        return executorService.submit(new Callable<int[]>() {
-
-            @Override
-            public int[] call() throws Exception {
-                return queryRunner.batch(conn, sql, params);
-            }
-
-        });
-    }
-
-    /**
-     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.  The
-     * {@code Connection} is retrieved from the {@code DataSource}
-     * set in the constructor.  This {@code Connection} must be in
-     * auto-commit mode or the update will not be saved.
-     *
-     * @param sql The SQL to execute.
-     * @param params An array of query replacement parameters.  Each row in
-     * this array is one set of batch replacement values.
-     * @return A {@code Future} which returns the number of rows updated per statement.
-     * @throws SQLException if a database access error occurs
-     */
-    public Future<int[]> batch(final String sql, final Object[][] params) throws SQLException {
-        return executorService.submit(new Callable<int[]>() {
-
-            @Override
-            public int[] call() throws Exception {
-                return queryRunner.batch(sql, params);
-            }
-
-        });
-    }
-
     /**
      * Class that encapsulates the continuation for query calls.
      * @param <T> The type of the result from the call to handle.
@@ -275,25 +157,314 @@ public class AsyncQueryRunner extends AbstractQueryRunner {
     }
 
     /**
-     * Execute an SQL SELECT query with replacement parameters.  The
-     * caller is responsible for closing the connection.
-     * @param <T> The type of object that the handler returns
-     * @param conn The connection to execute the query in.
-     * @param sql The query to execute.
-     * @param rsh The handler that converts the results into an object.
-     * @param params The replacement parameters.
-     * @return A {@code Future} which returns the result of the query call.
+     * @deprecated No longer used by this class. Will be removed in a future version.
+     * Class that encapsulates the continuation for update calls.
+     */
+    @Deprecated
+    protected class UpdateCallableStatement implements Callable<Integer> {
+        private final String sql;
+        private final Object[] params;
+        private final Connection conn;
+        private final boolean closeConn;
+        private final PreparedStatement ps;
+
+        /**
+         *
+         *
+         * @param conn The connection to use for the batch call.
+         * @param closeConn True if the connection should be closed, false otherwise.
+         * @param ps The {@link PreparedStatement} to be executed.
+         * @param sql The SQL statement to execute.
+         * @param params An array of query replacement parameters.  Each row in
+         *        this array is one set of batch replacement values.
+         */
+        public UpdateCallableStatement(final Connection conn, final boolean closeConn, final PreparedStatement ps, final String sql, final Object... params) {
+            this.sql = sql;
+            this.params = params;
+            this.conn = conn;
+            this.closeConn = closeConn;
+            this.ps = ps;
+        }
+
+        /**
+         * The actual call to {@code executeUpdate()} method.
+         *
+         * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or
+         *                (2) 0 for SQL statements that return nothing
+         * @throws SQLException if a database access error occurs.
+         * @see PreparedStatement#executeUpdate()
+         */
+        @Override
+        public Integer call() throws SQLException {
+            int rows = 0;
+
+            try {
+                rows = ps.executeUpdate();
+            } catch (final SQLException e) {
+                rethrow(e, sql, params);
+            } finally {
+                close(ps);
+                if (closeConn) {
+                    close(conn);
+                }
+            }
+
+            return Integer.valueOf(rows);
+        }
+
+    }
+
+    private final ExecutorService executorService;
+
+    private final QueryRunner queryRunner;
+
+    /**
+     * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
+     * Constructor for AsyncQueryRunner that controls the use of {@code ParameterMetaData}.
+     *
+     * @param pmdKnownBroken Some drivers don't support {@link java.sql.ParameterMetaData#getParameterType(int) };
+     * if {@code pmdKnownBroken} is set to true, we won't even try it; if false, we'll try it,
+     * and if it breaks, we'll remember not to use it again.
+     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
+     */
+    @Deprecated
+    public AsyncQueryRunner(final boolean pmdKnownBroken, final ExecutorService executorService) {
+        this(null, pmdKnownBroken, executorService);
+    }
+
+    /**
+     * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
+     * Constructor for AsyncQueryRunner that take a {@code DataSource} and controls the use of {@code ParameterMetaData}.
+     * Methods that do not take a {@code Connection} parameter will retrieve connections from this
+     * {@code DataSource}.
+     *
+     * @param ds The {@code DataSource} to retrieve connections from.
+     * @param pmdKnownBroken Some drivers don't support {@link java.sql.ParameterMetaData#getParameterType(int) };
+     * if {@code pmdKnownBroken} is set to true, we won't even try it; if false, we'll try it,
+     * and if it breaks, we'll remember not to use it again.
+     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
+     */
+    @Deprecated
+    public AsyncQueryRunner(final DataSource ds, final boolean pmdKnownBroken, final ExecutorService executorService) {
+        super(ds, pmdKnownBroken);
+        this.executorService = executorService;
+        this.queryRunner = new QueryRunner(ds, pmdKnownBroken);
+    }
+
+    /**
+     * @deprecated Use {@link #AsyncQueryRunner(ExecutorService, QueryRunner)} instead.
+     * Constructor for AsyncQueryRunner that takes a {@code DataSource}.
+     *
+     * Methods that do not take a {@code Connection} parameter will retrieve connections from this
+     * {@code DataSource}.
+     *
+     * @param ds The {@code DataSource} to retrieve connections from.
+     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
+     */
+    @Deprecated
+    public AsyncQueryRunner(final DataSource ds, final ExecutorService executorService) {
+        this(ds, false, executorService);
+    }
+
+    /**
+     * Constructor for AsyncQueryRunner.
+     *
+     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
+     */
+    public AsyncQueryRunner(final ExecutorService executorService) {
+        this(null, false, executorService);
+    }
+
+    /**
+     * Constructor for AsyncQueryRunner which uses a provided ExecutorService and underlying QueryRunner.
+     *
+     * @param executorService the {@code ExecutorService} instance used to run JDBC invocations concurrently.
+     * @param queryRunner the {@code QueryRunner} instance to use for the queries.
+     * @since 1.5
+     */
+    public AsyncQueryRunner(final ExecutorService executorService, final QueryRunner queryRunner) {
+        this.executorService = executorService;
+        this.queryRunner = queryRunner;
+    }
+
+    /**
+     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.
+     *
+     * @param conn The {@code Connection} to use to run the query.  The caller is
+     * responsible for closing this Connection.
+     * @param sql The SQL to execute.
+     * @param params An array of query replacement parameters.  Each row in
+     * this array is one set of batch replacement values.
+     * @return A {@code Future} which returns the number of rows updated per statement.
+     * @throws SQLException if a database access error occurs
+     */
+    public Future<int[]> batch(final Connection conn, final String sql, final Object[][] params) throws SQLException {
+        return executorService.submit(new Callable<int[]>() {
+
+            @Override
+            public int[] call() throws Exception {
+                return queryRunner.batch(conn, sql, params);
+            }
+
+        });
+    }
+
+    /**
+     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.  The
+     * {@code Connection} is retrieved from the {@code DataSource}
+     * set in the constructor.  This {@code Connection} must be in
+     * auto-commit mode or the update will not be saved.
+     *
+     * @param sql The SQL to execute.
+     * @param params An array of query replacement parameters.  Each row in
+     * this array is one set of batch replacement values.
+     * @return A {@code Future} which returns the number of rows updated per statement.
+     * @throws SQLException if a database access error occurs
+     */
+    public Future<int[]> batch(final String sql, final Object[][] params) throws SQLException {
+        return executorService.submit(new Callable<int[]>() {
+
+            @Override
+            public int[] call() throws Exception {
+                return queryRunner.batch(sql, params);
+            }
+
+        });
+    }
+
+    /**
+     * Executes {@link QueryRunner#insert(Connection, String, ResultSetHandler)} asynchronously.
+     *
+     * @param <T> Return type expected
+     * @param conn {@link Connection} to use to execute the SQL statement
+     * @param sql SQL insert statement to execute
+     * @param rsh {@link ResultSetHandler} for handling the results
+     * @return {@link Future} that executes a query runner insert
+     * @see QueryRunner#insert(Connection, String, ResultSetHandler)
+     * @throws SQLException if a database access error occurs
+     * @since 1.6
+     */
+    public <T> Future<T> insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh) throws SQLException {
+        return executorService.submit(new Callable<T>() {
+
+            @Override
+            public T call() throws Exception {
+                return queryRunner.insert(conn, sql, rsh);
+            }
+        });
+    }
+
+    /**
+     * Executes {@link QueryRunner#insert(Connection, String, ResultSetHandler, Object...)} asynchronously.
+     *
+     * @param <T> Return type expected
+     * @param conn {@link Connection} to use to execute the SQL statement
+     * @param sql SQL insert statement to execute
+     * @param rsh {@link ResultSetHandler} for handling the results
+     * @param params Parameter values for substitution in the SQL statement
+     * @return {@link Future} that executes a query runner insert
+     * @see QueryRunner#insert(Connection, String, ResultSetHandler, Object...)
+     * @throws SQLException if a database access error occurs
+     * @since 1.6
+     */
+    public <T> Future<T> insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+        return executorService.submit(new Callable<T>() {
+
+            @Override
+            public T call() throws Exception {
+                return queryRunner.insert(conn, sql, rsh, params);
+            }
+        });
+    }
+
+    /**
+     * Executes {@link QueryRunner#insert(String, ResultSetHandler)} asynchronously.
+     *
+     * @param <T> Return type expected
+     * @param sql SQL insert statement to execute
+     * @param rsh {@link ResultSetHandler} for handling the results
+     * @return {@link Future} that executes a query runner insert
+     * @see QueryRunner#insert(String, ResultSetHandler)
+     * @throws SQLException if a database access error occurs
+     * @since 1.6
+     */
+    public <T> Future<T> insert(final String sql, final ResultSetHandler<T> rsh) throws SQLException {
+        return executorService.submit(new Callable<T>() {
+
+            @Override
+            public T call() throws Exception {
+                return queryRunner.insert(sql, rsh);
+            }
+
+        });
+    }
+
+    /**
+     * Executes {@link QueryRunner#insert(String, ResultSetHandler, Object...)} asynchronously.
+     *
+     * @param <T> Return type expected
+     * @param sql SQL insert statement to execute
+     * @param rsh {@link ResultSetHandler} for handling the results
+     * @param params Parameter values for substitution in the SQL statement
+     * @return {@link Future} that executes a query runner insert
+     * @see QueryRunner#insert(String, ResultSetHandler, Object...)
+     * @throws SQLException if a database access error occurs
+     * @since 1.6
+     */
+    public <T> Future<T> insert(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+        return executorService.submit(new Callable<T>() {
+
+            @Override
+            public T call() throws Exception {
+                return queryRunner.insert(sql, rsh, params);
+            }
+        });
+    }
+
+    /**
+     * {@link QueryRunner#insertBatch(Connection, String, ResultSetHandler, Object[][])} asynchronously.
+     *
+     * @param <T> Return type expected
+     * @param conn {@link Connection} to use to execute the SQL statement
+     * @param sql SQL insert statement to execute
+     * @param rsh {@link ResultSetHandler} for handling the results
+     * @param params An array of query replacement parameters.  Each row in
+     *        this array is one set of batch replacement values.
+     * @return {@link Future} that executes a query runner batch insert
+     * @see QueryRunner#insertBatch(Connection, String, ResultSetHandler, Object[][])
+     * @throws SQLException if a database access error occurs
+     * @since 1.6
+     */
+    public <T> Future<T> insertBatch(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
+        return executorService.submit(new Callable<T>() {
+
+            @Override
+            public T call() throws Exception {
+                return queryRunner.insertBatch(conn, sql, rsh, params);
+            }
+        });
+    }
+
+    /**
+     * {@link QueryRunner#insertBatch(String, ResultSetHandler, Object[][])} asynchronously.
+     *
+     * @param <T> Return type expected
+     * @param sql SQL insert statement to execute
+     * @param rsh {@link ResultSetHandler} for handling the results
+     * @param params An array of query replacement parameters.  Each row in
+     *        this array is one set of batch replacement values.
+     * @return {@link Future} that executes a query runner batch insert
+     * @see QueryRunner#insertBatch(String, ResultSetHandler, Object[][])
      * @throws SQLException if a database access error occurs
+     * @since 1.6
      */
-    public <T> Future<T> query(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params)
-            throws SQLException {
+    public <T> Future<T> insertBatch(final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
         return executorService.submit(new Callable<T>() {
 
             @Override
             public T call() throws Exception {
-                return queryRunner.query(conn, sql, rsh, params);
+                return queryRunner.insertBatch(sql, rsh, params);
             }
-
         });
     }
 
@@ -319,24 +490,23 @@ public class AsyncQueryRunner extends AbstractQueryRunner {
     }
 
     /**
-     * Executes the given SELECT SQL query and returns a result object.
-     * The {@code Connection} is retrieved from the
-     * {@code DataSource} set in the constructor.
+     * Execute an SQL SELECT query with replacement parameters.  The
+     * caller is responsible for closing the connection.
      * @param <T> The type of object that the handler returns
-     * @param sql The SQL statement to execute.
-     * @param rsh The handler used to create the result object from
-     * the {@code ResultSet}.
-     * @param params Initialize the PreparedStatement's IN parameters with
-     * this array.
+     * @param conn The connection to execute the query in.
+     * @param sql The query to execute.
+     * @param rsh The handler that converts the results into an object.
+     * @param params The replacement parameters.
      * @return A {@code Future} which returns the result of the query call.
      * @throws SQLException if a database access error occurs
      */
-    public <T> Future<T> query(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+    public <T> Future<T> query(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params)
+            throws SQLException {
         return executorService.submit(new Callable<T>() {
 
             @Override
             public T call() throws Exception {
-                return queryRunner.query(sql, rsh, params);
+                return queryRunner.query(conn, sql, rsh, params);
             }
 
         });
@@ -366,61 +536,27 @@ public class AsyncQueryRunner extends AbstractQueryRunner {
     }
 
     /**
-     * @deprecated No longer used by this class. Will be removed in a future version.
-     * Class that encapsulates the continuation for update calls.
+     * Executes the given SELECT SQL query and returns a result object.
+     * The {@code Connection} is retrieved from the
+     * {@code DataSource} set in the constructor.
+     * @param <T> The type of object that the handler returns
+     * @param sql The SQL statement to execute.
+     * @param rsh The handler used to create the result object from
+     * the {@code ResultSet}.
+     * @param params Initialize the PreparedStatement's IN parameters with
+     * this array.
+     * @return A {@code Future} which returns the result of the query call.
+     * @throws SQLException if a database access error occurs
      */
-    @Deprecated
-    protected class UpdateCallableStatement implements Callable<Integer> {
-        private final String sql;
-        private final Object[] params;
-        private final Connection conn;
-        private final boolean closeConn;
-        private final PreparedStatement ps;
-
-        /**
-         *
-         *
-         * @param conn The connection to use for the batch call.
-         * @param closeConn True if the connection should be closed, false otherwise.
-         * @param ps The {@link PreparedStatement} to be executed.
-         * @param sql The SQL statement to execute.
-         * @param params An array of query replacement parameters.  Each row in
-         *        this array is one set of batch replacement values.
-         */
-        public UpdateCallableStatement(final Connection conn, final boolean closeConn, final PreparedStatement ps, final String sql, final Object... params) {
-            this.sql = sql;
-            this.params = params;
-            this.conn = conn;
-            this.closeConn = closeConn;
-            this.ps = ps;
-        }
-
-        /**
-         * The actual call to {@code executeUpdate()} method.
-         *
-         * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or
-         *                (2) 0 for SQL statements that return nothing
-         * @throws SQLException if a database access error occurs.
-         * @see PreparedStatement#executeUpdate()
-         */
-        @Override
-        public Integer call() throws SQLException {
-            int rows = 0;
+    public <T> Future<T> query(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+        return executorService.submit(new Callable<T>() {
 
-            try {
-                rows = ps.executeUpdate();
-            } catch (final SQLException e) {
-                rethrow(e, sql, params);
-            } finally {
-                close(ps);
-                if (closeConn) {
-                    close(conn);
-                }
+            @Override
+            public T call() throws Exception {
+                return queryRunner.query(sql, rsh, params);
             }
 
-            return Integer.valueOf(rows);
-        }
-
+        });
     }
 
     /**
@@ -552,140 +688,4 @@ public class AsyncQueryRunner extends AbstractQueryRunner {
         });
     }
 
-    /**
-     * Executes {@link QueryRunner#insert(String, ResultSetHandler)} asynchronously.
-     *
-     * @param <T> Return type expected
-     * @param sql SQL insert statement to execute
-     * @param rsh {@link ResultSetHandler} for handling the results
-     * @return {@link Future} that executes a query runner insert
-     * @see QueryRunner#insert(String, ResultSetHandler)
-     * @throws SQLException if a database access error occurs
-     * @since 1.6
-     */
-    public <T> Future<T> insert(final String sql, final ResultSetHandler<T> rsh) throws SQLException {
-        return executorService.submit(new Callable<T>() {
-
-            @Override
-            public T call() throws Exception {
-                return queryRunner.insert(sql, rsh);
-            }
-
-        });
-    }
-
-    /**
-     * Executes {@link QueryRunner#insert(String, ResultSetHandler, Object...)} asynchronously.
-     *
-     * @param <T> Return type expected
-     * @param sql SQL insert statement to execute
-     * @param rsh {@link ResultSetHandler} for handling the results
-     * @param params Parameter values for substitution in the SQL statement
-     * @return {@link Future} that executes a query runner insert
-     * @see QueryRunner#insert(String, ResultSetHandler, Object...)
-     * @throws SQLException if a database access error occurs
-     * @since 1.6
-     */
-    public <T> Future<T> insert(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        return executorService.submit(new Callable<T>() {
-
-            @Override
-            public T call() throws Exception {
-                return queryRunner.insert(sql, rsh, params);
-            }
-        });
-    }
-
-    /**
-     * Executes {@link QueryRunner#insert(Connection, String, ResultSetHandler)} asynchronously.
-     *
-     * @param <T> Return type expected
-     * @param conn {@link Connection} to use to execute the SQL statement
-     * @param sql SQL insert statement to execute
-     * @param rsh {@link ResultSetHandler} for handling the results
-     * @return {@link Future} that executes a query runner insert
-     * @see QueryRunner#insert(Connection, String, ResultSetHandler)
-     * @throws SQLException if a database access error occurs
-     * @since 1.6
-     */
-    public <T> Future<T> insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh) throws SQLException {
-        return executorService.submit(new Callable<T>() {
-
-            @Override
-            public T call() throws Exception {
-                return queryRunner.insert(conn, sql, rsh);
-            }
-        });
-    }
-
-    /**
-     * Executes {@link QueryRunner#insert(Connection, String, ResultSetHandler, Object...)} asynchronously.
-     *
-     * @param <T> Return type expected
-     * @param conn {@link Connection} to use to execute the SQL statement
-     * @param sql SQL insert statement to execute
-     * @param rsh {@link ResultSetHandler} for handling the results
-     * @param params Parameter values for substitution in the SQL statement
-     * @return {@link Future} that executes a query runner insert
-     * @see QueryRunner#insert(Connection, String, ResultSetHandler, Object...)
-     * @throws SQLException if a database access error occurs
-     * @since 1.6
-     */
-    public <T> Future<T> insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        return executorService.submit(new Callable<T>() {
-
-            @Override
-            public T call() throws Exception {
-                return queryRunner.insert(conn, sql, rsh, params);
-            }
-        });
-    }
-
-    /**
-     * {@link QueryRunner#insertBatch(String, ResultSetHandler, Object[][])} asynchronously.
-     *
-     * @param <T> Return type expected
-     * @param sql SQL insert statement to execute
-     * @param rsh {@link ResultSetHandler} for handling the results
-     * @param params An array of query replacement parameters.  Each row in
-     *        this array is one set of batch replacement values.
-     * @return {@link Future} that executes a query runner batch insert
-     * @see QueryRunner#insertBatch(String, ResultSetHandler, Object[][])
-     * @throws SQLException if a database access error occurs
-     * @since 1.6
-     */
-    public <T> Future<T> insertBatch(final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
-        return executorService.submit(new Callable<T>() {
-
-            @Override
-            public T call() throws Exception {
-                return queryRunner.insertBatch(sql, rsh, params);
-            }
-        });
-    }
-
-    /**
-     * {@link QueryRunner#insertBatch(Connection, String, ResultSetHandler, Object[][])} asynchronously.
-     *
-     * @param <T> Return type expected
-     * @param conn {@link Connection} to use to execute the SQL statement
-     * @param sql SQL insert statement to execute
-     * @param rsh {@link ResultSetHandler} for handling the results
-     * @param params An array of query replacement parameters.  Each row in
-     *        this array is one set of batch replacement values.
-     * @return {@link Future} that executes a query runner batch insert
-     * @see QueryRunner#insertBatch(Connection, String, ResultSetHandler, Object[][])
-     * @throws SQLException if a database access error occurs
-     * @since 1.6
-     */
-    public <T> Future<T> insertBatch(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
-        return executorService.submit(new Callable<T>() {
-
-            @Override
-            public T call() throws Exception {
-                return queryRunner.insertBatch(conn, sql, rsh, params);
-            }
-        });
-    }
-
 }
diff --git a/src/main/java/org/apache/commons/dbutils/BaseResultSetHandler.java b/src/main/java/org/apache/commons/dbutils/BaseResultSetHandler.java
index 1059bf6..e47cf2b 100644
--- a/src/main/java/org/apache/commons/dbutils/BaseResultSetHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/BaseResultSetHandler.java
@@ -58,33 +58,6 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
      */
     private ResultSet rs;
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public final T handle(final ResultSet rs) throws SQLException {
-        if (this.rs != null) {
-            throw new IllegalStateException("Re-entry not allowed!");
-        }
-
-        this.rs = rs;
-
-        try {
-            return handle();
-        } finally {
-            this.rs = null;
-        }
-    }
-
-    /**
-     * Turn the {@code ResultSet} into an Object.
-     *
-     * @return An Object initialized with {@code ResultSet} data
-     * @throws SQLException if a database access error occurs
-     * @see ResultSetHandler#handle(ResultSet)
-     */
-    protected abstract T handle() throws SQLException;
-
     /**
      * {@inheritDoc}
      */
@@ -148,6 +121,10 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         return rs.first();
     }
 
+    protected final ResultSet getAdaptedResultSet() {
+        return rs;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -176,6 +153,13 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         return rs.getAsciiStream(columnLabel);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    protected final BigDecimal getBigDecimal(final int columnIndex) throws SQLException {
+        return rs.getBigDecimal(columnIndex);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -187,8 +171,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final BigDecimal getBigDecimal(final int columnIndex) throws SQLException {
-        return rs.getBigDecimal(columnIndex);
+    protected final BigDecimal getBigDecimal(final String columnLabel) throws SQLException {
+        return rs.getBigDecimal(columnLabel);
     }
 
     /**
@@ -199,13 +183,6 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         return rs.getBigDecimal(columnLabel, scale);
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    protected final BigDecimal getBigDecimal(final String columnLabel) throws SQLException {
-        return rs.getBigDecimal(columnLabel);
-    }
-
     /**
      * {@inheritDoc}
      */
@@ -321,29 +298,29 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final Date getDate(final int columnIndex, final Calendar cal) throws SQLException {
-        return rs.getDate(columnIndex, cal);
+    protected final Date getDate(final int columnIndex) throws SQLException {
+        return rs.getDate(columnIndex);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final Date getDate(final int columnIndex) throws SQLException {
-        return rs.getDate(columnIndex);
+    protected final Date getDate(final int columnIndex, final Calendar cal) throws SQLException {
+        return rs.getDate(columnIndex, cal);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final Date getDate(final String columnLabel, final Calendar cal) throws SQLException {
-        return rs.getDate(columnLabel, cal);
+    protected final Date getDate(final String columnLabel) throws SQLException {
+        return rs.getDate(columnLabel);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final Date getDate(final String columnLabel) throws SQLException {
-        return rs.getDate(columnLabel);
+    protected final Date getDate(final String columnLabel, final Calendar cal) throws SQLException {
+        return rs.getDate(columnLabel, cal);
     }
 
     /**
@@ -475,29 +452,29 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final Object getObject(final int columnIndex, final Map<String, Class<?>> map) throws SQLException {
-        return rs.getObject(columnIndex, map);
+    protected final Object getObject(final int columnIndex) throws SQLException {
+        return rs.getObject(columnIndex);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final Object getObject(final int columnIndex) throws SQLException {
-        return rs.getObject(columnIndex);
+    protected final Object getObject(final int columnIndex, final Map<String, Class<?>> map) throws SQLException {
+        return rs.getObject(columnIndex, map);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final Object getObject(final String columnLabel, final Map<String, Class<?>> map) throws SQLException {
-        return rs.getObject(columnLabel, map);
+    protected final Object getObject(final String columnLabel) throws SQLException {
+        return rs.getObject(columnLabel);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final Object getObject(final String columnLabel) throws SQLException {
-        return rs.getObject(columnLabel);
+    protected final Object getObject(final String columnLabel, final Map<String, Class<?>> map) throws SQLException {
+        return rs.getObject(columnLabel, map);
     }
 
     /**
@@ -538,29 +515,29 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final SQLXML getSQLXML(final int columnIndex) throws SQLException {
-        return rs.getSQLXML(columnIndex);
+    protected final short getShort(final int columnIndex) throws SQLException {
+        return rs.getShort(columnIndex);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final SQLXML getSQLXML(final String columnLabel) throws SQLException {
-        return rs.getSQLXML(columnLabel);
+    protected final short getShort(final String columnLabel) throws SQLException {
+        return rs.getShort(columnLabel);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final short getShort(final int columnIndex) throws SQLException {
-        return rs.getShort(columnIndex);
+    protected final SQLXML getSQLXML(final int columnIndex) throws SQLException {
+        return rs.getSQLXML(columnIndex);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final short getShort(final String columnLabel) throws SQLException {
-        return rs.getShort(columnLabel);
+    protected final SQLXML getSQLXML(final String columnLabel) throws SQLException {
+        return rs.getSQLXML(columnLabel);
     }
 
     /**
@@ -584,6 +561,13 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         return rs.getString(columnLabel);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    protected final Time getTime(final int columnIndex) throws SQLException {
+        return rs.getTime(columnIndex);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -594,8 +578,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final Time getTime(final int columnIndex) throws SQLException {
-        return rs.getTime(columnIndex);
+    protected final Time getTime(final String columnLabel) throws SQLException {
+        return rs.getTime(columnLabel);
     }
 
     /**
@@ -608,8 +592,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final Time getTime(final String columnLabel) throws SQLException {
-        return rs.getTime(columnLabel);
+    protected final Timestamp getTimestamp(final int columnIndex) throws SQLException {
+        return rs.getTimestamp(columnIndex);
     }
 
     /**
@@ -622,8 +606,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final Timestamp getTimestamp(final int columnIndex) throws SQLException {
-        return rs.getTimestamp(columnIndex);
+    protected final Timestamp getTimestamp(final String columnLabel) throws SQLException {
+        return rs.getTimestamp(columnLabel);
     }
 
     /**
@@ -636,15 +620,24 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final Timestamp getTimestamp(final String columnLabel) throws SQLException {
-        return rs.getTimestamp(columnLabel);
+    protected final int getType() throws SQLException {
+        return rs.getType();
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final int getType() throws SQLException {
-        return rs.getType();
+    @Deprecated
+    protected final InputStream getUnicodeStream(final int columnIndex) throws SQLException {
+        return rs.getUnicodeStream(columnIndex);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
+    protected final InputStream getUnicodeStream(final String columnLabel) throws SQLException {
+        return rs.getUnicodeStream(columnLabel);
     }
 
     /**
@@ -664,24 +657,35 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
-    protected final InputStream getUnicodeStream(final int columnIndex) throws SQLException {
-        return rs.getUnicodeStream(columnIndex);
+    protected final SQLWarning getWarnings() throws SQLException {
+        return rs.getWarnings();
     }
 
     /**
-     * {@inheritDoc}
+     * Turn the {@code ResultSet} into an Object.
+     *
+     * @return An Object initialized with {@code ResultSet} data
+     * @throws SQLException if a database access error occurs
+     * @see ResultSetHandler#handle(ResultSet)
      */
-    @Deprecated
-    protected final InputStream getUnicodeStream(final String columnLabel) throws SQLException {
-        return rs.getUnicodeStream(columnLabel);
-    }
+    protected abstract T handle() throws SQLException;
 
     /**
      * {@inheritDoc}
      */
-    protected final SQLWarning getWarnings() throws SQLException {
-        return rs.getWarnings();
+    @Override
+    public final T handle(final ResultSet rs) throws SQLException {
+        if (this.rs != null) {
+            throw new IllegalStateException("Re-entry not allowed!");
+        }
+
+        this.rs = rs;
+
+        try {
+            return handle();
+        } finally {
+            this.rs = null;
+        }
     }
 
     /**
@@ -838,6 +842,13 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         rs.updateArray(columnLabel, x);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    protected final void updateAsciiStream(final int columnIndex, final InputStream x) throws SQLException {
+        rs.updateAsciiStream(columnIndex, x);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -855,8 +866,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateAsciiStream(final int columnIndex, final InputStream x) throws SQLException {
-        rs.updateAsciiStream(columnIndex, x);
+    protected final void updateAsciiStream(final String columnLabel, final InputStream x) throws SQLException {
+        rs.updateAsciiStream(columnLabel, x);
     }
 
     /**
@@ -876,22 +887,22 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateAsciiStream(final String columnLabel, final InputStream x) throws SQLException {
-        rs.updateAsciiStream(columnLabel, x);
+    protected final void updateBigDecimal(final int columnIndex, final BigDecimal x) throws SQLException {
+        rs.updateBigDecimal(columnIndex, x);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateBigDecimal(final int columnIndex, final BigDecimal x) throws SQLException {
-        rs.updateBigDecimal(columnIndex, x);
+    protected final void updateBigDecimal(final String columnLabel, final BigDecimal x) throws SQLException {
+        rs.updateBigDecimal(columnLabel, x);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateBigDecimal(final String columnLabel, final BigDecimal x) throws SQLException {
-        rs.updateBigDecimal(columnLabel, x);
+    protected final void updateBinaryStream(final int columnIndex, final InputStream x) throws SQLException {
+        rs.updateBinaryStream(columnIndex, x);
     }
 
     /**
@@ -911,8 +922,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateBinaryStream(final int columnIndex, final InputStream x) throws SQLException {
-        rs.updateBinaryStream(columnIndex, x);
+    protected final void updateBinaryStream(final String columnLabel, final InputStream x) throws SQLException {
+        rs.updateBinaryStream(columnLabel, x);
     }
 
     /**
@@ -929,13 +940,6 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         rs.updateBinaryStream(columnLabel, x, length);
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    protected final void updateBinaryStream(final String columnLabel, final InputStream x) throws SQLException {
-        rs.updateBinaryStream(columnLabel, x);
-    }
-
     /**
      * {@inheritDoc}
      */
@@ -946,15 +950,15 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateBlob(final int columnIndex, final InputStream inputStream, final long length) throws SQLException {
-        rs.updateBlob(columnIndex, inputStream, length);
+    protected final void updateBlob(final int columnIndex, final InputStream inputStream) throws SQLException {
+        rs.updateBlob(columnIndex, inputStream);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateBlob(final int columnIndex, final InputStream inputStream) throws SQLException {
-        rs.updateBlob(columnIndex, inputStream);
+    protected final void updateBlob(final int columnIndex, final InputStream inputStream, final long length) throws SQLException {
+        rs.updateBlob(columnIndex, inputStream, length);
     }
 
     /**
@@ -967,15 +971,15 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateBlob(final String columnLabel, final InputStream inputStream, final long length) throws SQLException {
-        rs.updateBlob(columnLabel, inputStream, length);
+    protected final void updateBlob(final String columnLabel, final InputStream inputStream) throws SQLException {
+        rs.updateBlob(columnLabel, inputStream);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateBlob(final String columnLabel, final InputStream inputStream) throws SQLException {
-        rs.updateBlob(columnLabel, inputStream);
+    protected final void updateBlob(final String columnLabel, final InputStream inputStream, final long length) throws SQLException {
+        rs.updateBlob(columnLabel, inputStream, length);
     }
 
     /**
@@ -1020,6 +1024,13 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         rs.updateBytes(columnLabel, x);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    protected final void updateCharacterStream(final int columnIndex, final Reader x) throws SQLException {
+        rs.updateCharacterStream(columnIndex, x);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -1037,8 +1048,8 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateCharacterStream(final int columnIndex, final Reader x) throws SQLException {
-        rs.updateCharacterStream(columnIndex, x);
+    protected final void updateCharacterStream(final String columnLabel, final Reader reader) throws SQLException {
+        rs.updateCharacterStream(columnLabel, reader);
     }
 
     /**
@@ -1055,13 +1066,6 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         rs.updateCharacterStream(columnLabel, reader, length);
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    protected final void updateCharacterStream(final String columnLabel, final Reader reader) throws SQLException {
-        rs.updateCharacterStream(columnLabel, reader);
-    }
-
     /**
      * {@inheritDoc}
      */
@@ -1072,15 +1076,15 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
-        rs.updateClob(columnIndex, reader, length);
+    protected final void updateClob(final int columnIndex, final Reader reader) throws SQLException {
+        rs.updateClob(columnIndex, reader);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateClob(final int columnIndex, final Reader reader) throws SQLException {
-        rs.updateClob(columnIndex, reader);
+    protected final void updateClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
+        rs.updateClob(columnIndex, reader, length);
     }
 
     /**
@@ -1093,15 +1097,15 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
-        rs.updateClob(columnLabel, reader, length);
+    protected final void updateClob(final String columnLabel, final Reader reader) throws SQLException {
+        rs.updateClob(columnLabel, reader);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateClob(final String columnLabel, final Reader reader) throws SQLException {
-        rs.updateClob(columnLabel, reader);
+    protected final void updateClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
+        rs.updateClob(columnLabel, reader, length);
     }
 
     /**
@@ -1177,29 +1181,29 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateNCharacterStream(final int columnIndex, final Reader x, final long length) throws SQLException {
-        rs.updateNCharacterStream(columnIndex, x, length);
+    protected final void updateNCharacterStream(final int columnIndex, final Reader x) throws SQLException {
+        rs.updateNCharacterStream(columnIndex, x);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateNCharacterStream(final int columnIndex, final Reader x) throws SQLException {
-        rs.updateNCharacterStream(columnIndex, x);
+    protected final void updateNCharacterStream(final int columnIndex, final Reader x, final long length) throws SQLException {
+        rs.updateNCharacterStream(columnIndex, x, length);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateNCharacterStream(final String columnLabel, final Reader reader, final long length) throws SQLException {
-        rs.updateNCharacterStream(columnLabel, reader, length);
+    protected final void updateNCharacterStream(final String columnLabel, final Reader reader) throws SQLException {
+        rs.updateNCharacterStream(columnLabel, reader);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateNCharacterStream(final String columnLabel, final Reader reader) throws SQLException {
-        rs.updateNCharacterStream(columnLabel, reader);
+    protected final void updateNCharacterStream(final String columnLabel, final Reader reader, final long length) throws SQLException {
+        rs.updateNCharacterStream(columnLabel, reader, length);
     }
 
     /**
@@ -1212,15 +1216,15 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateNClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
-        rs.updateNClob(columnIndex, reader, length);
+    protected final void updateNClob(final int columnIndex, final Reader reader) throws SQLException {
+        rs.updateNClob(columnIndex, reader);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateNClob(final int columnIndex, final Reader reader) throws SQLException {
-        rs.updateNClob(columnIndex, reader);
+    protected final void updateNClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
+        rs.updateNClob(columnIndex, reader, length);
     }
 
     /**
@@ -1233,15 +1237,15 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateNClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
-        rs.updateNClob(columnLabel, reader, length);
+    protected final void updateNClob(final String columnLabel, final Reader reader) throws SQLException {
+        rs.updateNClob(columnLabel, reader);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateNClob(final String columnLabel, final Reader reader) throws SQLException {
-        rs.updateNClob(columnLabel, reader);
+    protected final void updateNClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
+        rs.updateNClob(columnLabel, reader, length);
     }
 
     /**
@@ -1275,29 +1279,29 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateObject(final int columnIndex, final Object x, final int scaleOrLength) throws SQLException {
-        rs.updateObject(columnIndex, x, scaleOrLength);
+    protected final void updateObject(final int columnIndex, final Object x) throws SQLException {
+        rs.updateObject(columnIndex, x);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateObject(final int columnIndex, final Object x) throws SQLException {
-        rs.updateObject(columnIndex, x);
+    protected final void updateObject(final int columnIndex, final Object x, final int scaleOrLength) throws SQLException {
+        rs.updateObject(columnIndex, x, scaleOrLength);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateObject(final String columnLabel, final Object x, final int scaleOrLength) throws SQLException {
-        rs.updateObject(columnLabel, x, scaleOrLength);
+    protected final void updateObject(final String columnLabel, final Object x) throws SQLException {
+        rs.updateObject(columnLabel, x);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateObject(final String columnLabel, final Object x) throws SQLException {
-        rs.updateObject(columnLabel, x);
+    protected final void updateObject(final String columnLabel, final Object x, final int scaleOrLength) throws SQLException {
+        rs.updateObject(columnLabel, x, scaleOrLength);
     }
 
     /**
@@ -1338,29 +1342,29 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
     /**
      * {@inheritDoc}
      */
-    protected final void updateSQLXML(final int columnIndex, final SQLXML xmlObject) throws SQLException {
-        rs.updateSQLXML(columnIndex, xmlObject);
+    protected final void updateShort(final int columnIndex, final short x) throws SQLException {
+        rs.updateShort(columnIndex, x);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateSQLXML(final String columnLabel, final SQLXML xmlObject) throws SQLException {
-        rs.updateSQLXML(columnLabel, xmlObject);
+    protected final void updateShort(final String columnLabel, final short x) throws SQLException {
+        rs.updateShort(columnLabel, x);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateShort(final int columnIndex, final short x) throws SQLException {
-        rs.updateShort(columnIndex, x);
+    protected final void updateSQLXML(final int columnIndex, final SQLXML xmlObject) throws SQLException {
+        rs.updateSQLXML(columnIndex, xmlObject);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected final void updateShort(final String columnLabel, final short x) throws SQLException {
-        rs.updateShort(columnLabel, x);
+    protected final void updateSQLXML(final String columnLabel, final SQLXML xmlObject) throws SQLException {
+        rs.updateSQLXML(columnLabel, xmlObject);
     }
 
     /**
@@ -1412,8 +1416,4 @@ public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
         return rs.wasNull();
     }
 
-    protected final ResultSet getAdaptedResultSet() {
-        return rs;
-    }
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java b/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java
index 2814175..f2f310b 100644
--- a/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java
+++ b/src/main/java/org/apache/commons/dbutils/BasicRowProcessor.java
@@ -36,6 +36,102 @@ import java.util.Map;
  */
 public class BasicRowProcessor implements RowProcessor {
 
+    /**
+     * A Map that converts all keys to lowercase Strings for case insensitive
+     * lookups.  This is needed for the toMap() implementation because
+     * databases don't consistently handle the casing of column names.
+     *
+     * <p>The keys are stored as they are given [BUG #DBUTILS-34], so we maintain
+     * an internal mapping from lowercase keys to the real keys in order to
+     * achieve the case insensitive lookup.
+     *
+     * <p>Note: This implementation does not allow {@code null}
+     * for key, whereas {@link LinkedHashMap} does, because of the code:
+     * <pre>
+     * key.toString().toLowerCase()
+     * </pre>
+     */
+    private static final class CaseInsensitiveHashMap extends LinkedHashMap<String, Object> {
+
+        /**
+         * Required for serialization support.
+         *
+         * @see java.io.Serializable
+         */
+        private static final long serialVersionUID = -2848100435296897392L;
+
+        /**
+         * The internal mapping from lowercase keys to the real keys.
+         *
+         * <p>
+         * Any query operation using the key
+         * ({@link #get(Object)}, {@link #containsKey(Object)})
+         * is done in three steps:
+         * <ul>
+         * <li>convert the parameter key to lower case</li>
+         * <li>get the actual key that corresponds to the lower case key</li>
+         * <li>query the map with the actual key</li>
+         * </ul>
+         * </p>
+         */
+        private final Map<String, String> lowerCaseMap = new HashMap<>();
+
+        private CaseInsensitiveHashMap(final int initialCapacity) {
+            super(initialCapacity);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public boolean containsKey(final Object key) {
+            final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH));
+            return super.containsKey(realKey);
+            // Possible optimisation here:
+            // Since the lowerCaseMap contains a mapping for all the keys,
+            // we could just do this:
+            // return lowerCaseMap.containsKey(key.toString().toLowerCase());
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Object get(final Object key) {
+            final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH));
+            return super.get(realKey);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Object put(final String key, final Object value) {
+            /*
+             * In order to keep the map and lowerCaseMap synchronized,
+             * we have to remove the old mapping before putting the
+             * new one. Indeed, oldKey and key are not necessaliry equals.
+             * (That's why we call super.remove(oldKey) and not just
+             * super.put(key, value))
+             */
+            final Object oldKey = lowerCaseMap.put(key.toLowerCase(Locale.ENGLISH), key);
+            final Object oldValue = super.remove(oldKey);
+            super.put(key, value);
+            return oldValue;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void putAll(final Map<? extends String, ?> m) {
+            for (final Map.Entry<? extends String, ?> entry : m.entrySet()) {
+                final String key = entry.getKey();
+                final Object value = entry.getValue();
+                this.put(key, value);
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Object remove(final Object key) {
+            final Object realKey = lowerCaseMap.remove(key.toString().toLowerCase(Locale.ENGLISH));
+            return super.remove(realKey);
+        }
+    }
+
     /**
      * The default BeanProcessor instance to use if not supplied in the
      * constructor.
@@ -143,6 +239,7 @@ public class BasicRowProcessor implements RowProcessor {
         return this.convert.toBeanList(rs, type);
     }
 
+
     /**
      * Convert a {@code ResultSet} row into a {@code Map}.
      *
@@ -179,101 +276,4 @@ public class BasicRowProcessor implements RowProcessor {
         return result;
     }
 
-
-    /**
-     * A Map that converts all keys to lowercase Strings for case insensitive
-     * lookups.  This is needed for the toMap() implementation because
-     * databases don't consistently handle the casing of column names.
-     *
-     * <p>The keys are stored as they are given [BUG #DBUTILS-34], so we maintain
-     * an internal mapping from lowercase keys to the real keys in order to
-     * achieve the case insensitive lookup.
-     *
-     * <p>Note: This implementation does not allow {@code null}
-     * for key, whereas {@link LinkedHashMap} does, because of the code:
-     * <pre>
-     * key.toString().toLowerCase()
-     * </pre>
-     */
-    private static final class CaseInsensitiveHashMap extends LinkedHashMap<String, Object> {
-
-        private CaseInsensitiveHashMap(final int initialCapacity) {
-            super(initialCapacity);
-        }
-
-        /**
-         * The internal mapping from lowercase keys to the real keys.
-         *
-         * <p>
-         * Any query operation using the key
-         * ({@link #get(Object)}, {@link #containsKey(Object)})
-         * is done in three steps:
-         * <ul>
-         * <li>convert the parameter key to lower case</li>
-         * <li>get the actual key that corresponds to the lower case key</li>
-         * <li>query the map with the actual key</li>
-         * </ul>
-         * </p>
-         */
-        private final Map<String, String> lowerCaseMap = new HashMap<>();
-
-        /**
-         * Required for serialization support.
-         *
-         * @see java.io.Serializable
-         */
-        private static final long serialVersionUID = -2848100435296897392L;
-
-        /** {@inheritDoc} */
-        @Override
-        public boolean containsKey(final Object key) {
-            final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH));
-            return super.containsKey(realKey);
-            // Possible optimisation here:
-            // Since the lowerCaseMap contains a mapping for all the keys,
-            // we could just do this:
-            // return lowerCaseMap.containsKey(key.toString().toLowerCase());
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Object get(final Object key) {
-            final Object realKey = lowerCaseMap.get(key.toString().toLowerCase(Locale.ENGLISH));
-            return super.get(realKey);
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Object put(final String key, final Object value) {
-            /*
-             * In order to keep the map and lowerCaseMap synchronized,
-             * we have to remove the old mapping before putting the
-             * new one. Indeed, oldKey and key are not necessaliry equals.
-             * (That's why we call super.remove(oldKey) and not just
-             * super.put(key, value))
-             */
-            final Object oldKey = lowerCaseMap.put(key.toLowerCase(Locale.ENGLISH), key);
-            final Object oldValue = super.remove(oldKey);
-            super.put(key, value);
-            return oldValue;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void putAll(final Map<? extends String, ?> m) {
-            for (final Map.Entry<? extends String, ?> entry : m.entrySet()) {
-                final String key = entry.getKey();
-                final Object value = entry.getValue();
-                this.put(key, value);
-            }
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public Object remove(final Object key) {
-            final Object realKey = lowerCaseMap.remove(key.toString().toLowerCase(Locale.ENGLISH));
-            return super.remove(realKey);
-        }
-    }
-
 }
diff --git a/src/main/java/org/apache/commons/dbutils/BeanProcessor.java b/src/main/java/org/apache/commons/dbutils/BeanProcessor.java
index b6fb3ac..3834758 100644
--- a/src/main/java/org/apache/commons/dbutils/BeanProcessor.java
+++ b/src/main/java/org/apache/commons/dbutils/BeanProcessor.java
@@ -71,11 +71,6 @@ public class BeanProcessor {
 
     private static final List<PropertyHandler> propertyHandlers = new ArrayList<>();
 
-    /**
-     * ResultSet column to bean property name overrides.
-     */
-    private final Map<String, String> columnToPropertyOverrides;
-
     static {
         primitiveDefaults.put(Integer.TYPE, Integer.valueOf(0));
         primitiveDefaults.put(Short.TYPE, Short.valueOf((short) 0));
@@ -97,6 +92,11 @@ public class BeanProcessor {
         }
     }
 
+    /**
+     * ResultSet column to bean property name overrides.
+     */
+    private final Map<String, String> columnToPropertyOverrides;
+
     /**
      * Constructor for BeanProcessor.
      */
@@ -117,168 +117,6 @@ public class BeanProcessor {
         this.columnToPropertyOverrides = columnToPropertyOverrides;
     }
 
-    /**
-     * Convert a {@code ResultSet} row into a JavaBean.  This
-     * implementation uses reflection and {@code BeanInfo} classes to
-     * match column names to bean property names.  Properties are matched to
-     * columns based on several factors:
-     * &lt;br/&gt;
-     * &lt;ol&gt;
-     *     &lt;li&gt;
-     *     The class has a writable property with the same name as a column.
-     *     The name comparison is case insensitive.
-     *     &lt;/li&gt;
-     *
-     *     &lt;li&gt;
-     *     The column type can be converted to the property's set method
-     *     parameter type with a ResultSet.get* method.  If the conversion fails
-     *     (ie. the property was an int and the column was a Timestamp) an
-     *     SQLException is thrown.
-     *     &lt;/li&gt;
-     * &lt;/ol&gt;
-     *
-     * &lt;p&gt;
-     * Primitive bean properties are set to their defaults when SQL NULL is
-     * returned from the {@code ResultSet}.  Numeric fields are set to 0
-     * and booleans are set to false.  Object bean properties are set to
-     * {@code null} when SQL NULL is returned.  This is the same behavior
-     * as the {@code ResultSet} get* methods.
-     * &lt;/p&gt;
-     * @param <T> The type of bean to create
-     * @param rs ResultSet that supplies the bean data
-     * @param type Class from which to create the bean instance
-     * @throws SQLException if a database access error occurs
-     * @return the newly created bean
-     */
-    public <T> T toBean(final ResultSet rs, final Class<? extends T> type) throws SQLException {
-        final T bean = this.newInstance(type);
-        return this.populateBean(rs, bean);
-    }
-
-    /**
-     * Convert a {@code ResultSet} into a {@code List} of JavaBeans.
-     * This implementation uses reflection and {@code BeanInfo} classes to
-     * match column names to bean property names. Properties are matched to
-     * columns based on several factors:
-     * &lt;br/&gt;
-     * &lt;ol&gt;
-     *     &lt;li&gt;
-     *     The class has a writable property with the same name as a column.
-     *     The name comparison is case insensitive.
-     *     &lt;/li&gt;
-     *
-     *     &lt;li&gt;
-     *     The column type can be converted to the property's set method
-     *     parameter type with a ResultSet.get* method.  If the conversion fails
-     *     (ie. the property was an int and the column was a Timestamp) an
-     *     SQLException is thrown.
-     *     &lt;/li&gt;
-     * &lt;/ol&gt;
-     *
-     * <p>
-     * Primitive bean properties are set to their defaults when SQL NULL is
-     * returned from the {@code ResultSet}.  Numeric fields are set to 0
-     * and booleans are set to false.  Object bean properties are set to
-     * {@code null} when SQL NULL is returned.  This is the same behavior
-     * as the {@code ResultSet} get* methods.
-     * &lt;/p&gt;
-     * @param <T> The type of bean to create
-     * @param rs ResultSet that supplies the bean data
-     * @param type Class from which to create the bean instance
-     * @throws SQLException if a database access error occurs
-     * @return the newly created List of beans
-     */
-    public <T> List<T> toBeanList(final ResultSet rs, final Class<? extends T> type) throws SQLException {
-        final List<T> results = new ArrayList<>();
-
-        if (!rs.next()) {
-            return results;
-        }
-
-        final PropertyDescriptor[] props = this.propertyDescriptors(type);
-        final ResultSetMetaData rsmd = rs.getMetaData();
-        final int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
-
-        do {
-            results.add(this.createBean(rs, type, props, columnToProperty));
-        } while (rs.next());
-
-        return results;
-    }
-
-    /**
-     * Creates a new object and initializes its fields from the ResultSet.
-     * @param <T> The type of bean to create
-     * @param rs The result set.
-     * @param type The bean type (the return type of the object).
-     * @param props The property descriptors.
-     * @param columnToProperty The column indices in the result set.
-     * @return An initialized object.
-     * @throws SQLException if a database error occurs.
-     */
-    private <T> T createBean(final ResultSet rs, final Class<T> type,
-                             final PropertyDescriptor[] props, final int[] columnToProperty)
-    throws SQLException {
-
-        final T bean = this.newInstance(type);
-        return populateBean(rs, bean, props, columnToProperty);
-    }
-
-    /**
-     * Initializes the fields of the provided bean from the ResultSet.
-     * @param <T> The type of bean
-     * @param rs The result set.
-     * @param bean The bean to be populated.
-     * @return An initialized object.
-     * @throws SQLException if a database error occurs.
-     */
-    public <T> T populateBean(final ResultSet rs, final T bean) throws SQLException {
-        final PropertyDescriptor[] props = this.propertyDescriptors(bean.getClass());
-        final ResultSetMetaData rsmd = rs.getMetaData();
-        final int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
-
-        return populateBean(rs, bean, props, columnToProperty);
-    }
-
-    /**
-     * This method populates a bean from the ResultSet based upon the underlying meta-data.
-     *
-     * @param <T> The type of bean
-     * @param rs The result set.
-     * @param bean The bean to be populated.
-     * @param props The property descriptors.
-     * @param columnToProperty The column indices in the result set.
-     * @return An initialized object.
-     * @throws SQLException if a database error occurs.
-     */
-    private <T> T populateBean(final ResultSet rs, final T bean,
-            final PropertyDescriptor[] props, final int[] columnToProperty)
-            throws SQLException {
-
-        for (int i = 1; i < columnToProperty.length; i++) {
-
-            if (columnToProperty[i] == PROPERTY_NOT_FOUND) {
-                continue;
-            }
-
-            final PropertyDescriptor prop = props[columnToProperty[i]];
-            final Class<?> propType = prop.getPropertyType();
-
-            Object value = null;
-            if (propType != null) {
-                value = this.processColumn(rs, i, propType);
-
-                if (value == null && propType.isPrimitive()) {
-                    value = primitiveDefaults.get(propType);
-                }
-            }
-
-            this.callSetter(bean, prop, value);
-        }
-
-        return bean;
-    }
-
     /**
      * Calls the setter method on the target object for the given property.
      * If no setter method exists for the property, this method does nothing.
@@ -321,51 +159,21 @@ public class BeanProcessor {
     }
 
     /**
-     * ResultSet.getObject() returns an Integer object for an INT column.  The
-     * setter method for the property might take an Integer or a primitive int.
-     * This method returns true if the value can be successfully passed into
-     * the setter method.  Remember, Method.invoke() handles the unwrapping
-     * of Integer into an int.
-     *
-     * @param value The value to be passed into the setter method.
-     * @param type The setter's parameter type (non-null)
-     * @return boolean True if the value is compatible (null => true)
-     */
-    private boolean isCompatibleType(final Object value, final Class<?> type) {
-        // Do object check first, then primitives
-        if (value == null || type.isInstance(value) || matchesPrimitive(type, value.getClass())) {
-            return true;
-
-        }
-        return false;
-
-    }
-
-    /**
-     * Check whether a value is of the same primitive type as {@code targetType}.
-     *
-     * @param targetType The primitive type to target.
-     * @param valueType The value to match to the primitive type.
-     * @return Whether {@code valueType} can be coerced (e.g. autoboxed) into {@code targetType}.
+     * Creates a new object and initializes its fields from the ResultSet.
+     * @param <T> The type of bean to create
+     * @param rs The result set.
+     * @param type The bean type (the return type of the object).
+     * @param props The property descriptors.
+     * @param columnToProperty The column indices in the result set.
+     * @return An initialized object.
+     * @throws SQLException if a database error occurs.
      */
-    private boolean matchesPrimitive(final Class<?> targetType, final Class<?> valueType) {
-        if (!targetType.isPrimitive()) {
-            return false;
-        }
-
-        try {
-            // see if there is a "TYPE" field.  This is present for primitive wrappers.
-            final Field typeField = valueType.getField("TYPE");
-            final Object primitiveValueType = typeField.get(valueType);
+    private <T> T createBean(final ResultSet rs, final Class<T> type,
+                             final PropertyDescriptor[] props, final int[] columnToProperty)
+    throws SQLException {
 
-            if (targetType == primitiveValueType) {
-                return true;
-            }
-        } catch (final NoSuchFieldException | IllegalAccessException ignored) {
-            // an inaccessible TYPE field is a good sign that we're not working with a primitive wrapper.
-            // nothing to do.  we can't match for compatibility
-        }
-        return false;
+        final T bean = this.newInstance(type);
+        return populateBean(rs, bean, props, columnToProperty);
     }
 
     /**
@@ -383,45 +191,24 @@ public class BeanProcessor {
     }
 
     /**
-     * Factory method that returns a new instance of the given Class.  This
-     * is called at the start of the bean creation process and may be
-     * overridden to provide custom behavior like returning a cached bean
-     * instance.
-     * @param <T> The type of object to create
-     * @param c The Class to create an object from.
-     * @return A newly created object of the Class.
-     * @throws SQLException if creation failed.
-     */
-    protected <T> T newInstance(final Class<T> c) throws SQLException {
-        try {
-            return c.getDeclaredConstructor().newInstance();
-
-        } catch (final IllegalAccessException | InstantiationException | InvocationTargetException |
-            NoSuchMethodException e) {
-            throw new SQLException("Cannot create " + c.getName() + ": " + e.getMessage());
-        }
-    }
-
-    /**
-     * Returns a PropertyDescriptor[] for the given Class.
+     * ResultSet.getObject() returns an Integer object for an INT column.  The
+     * setter method for the property might take an Integer or a primitive int.
+     * This method returns true if the value can be successfully passed into
+     * the setter method.  Remember, Method.invoke() handles the unwrapping
+     * of Integer into an int.
      *
-     * @param c The Class to retrieve PropertyDescriptors for.
-     * @return A PropertyDescriptor[] describing the Class.
-     * @throws SQLException if introspection failed.
+     * @param value The value to be passed into the setter method.
+     * @param type The setter's parameter type (non-null)
+     * @return boolean True if the value is compatible (null => true)
      */
-    private PropertyDescriptor[] propertyDescriptors(final Class<?> c)
-        throws SQLException {
-        // Introspector caches BeanInfo classes for better performance
-        BeanInfo beanInfo = null;
-        try {
-            beanInfo = Introspector.getBeanInfo(c);
+    private boolean isCompatibleType(final Object value, final Class<?> type) {
+        // Do object check first, then primitives
+        if (value == null || type.isInstance(value) || matchesPrimitive(type, value.getClass())) {
+            return true;
 
-        } catch (final IntrospectionException e) {
-            throw new SQLException(
-                "Bean introspection failed: " + e.getMessage());
         }
+        return false;
 
-        return beanInfo.getPropertyDescriptors();
     }
 
     /**
@@ -489,6 +276,108 @@ public class BeanProcessor {
         return columnToProperty;
     }
 
+    /**
+     * Check whether a value is of the same primitive type as {@code targetType}.
+     *
+     * @param targetType The primitive type to target.
+     * @param valueType The value to match to the primitive type.
+     * @return Whether {@code valueType} can be coerced (e.g. autoboxed) into {@code targetType}.
+     */
+    private boolean matchesPrimitive(final Class<?> targetType, final Class<?> valueType) {
+        if (!targetType.isPrimitive()) {
+            return false;
+        }
+
+        try {
+            // see if there is a "TYPE" field.  This is present for primitive wrappers.
+            final Field typeField = valueType.getField("TYPE");
+            final Object primitiveValueType = typeField.get(valueType);
+
+            if (targetType == primitiveValueType) {
+                return true;
+            }
+        } catch (final NoSuchFieldException | IllegalAccessException ignored) {
+            // an inaccessible TYPE field is a good sign that we're not working with a primitive wrapper.
+            // nothing to do.  we can't match for compatibility
+        }
+        return false;
+    }
+
+    /**
+     * Factory method that returns a new instance of the given Class.  This
+     * is called at the start of the bean creation process and may be
+     * overridden to provide custom behavior like returning a cached bean
+     * instance.
+     * @param <T> The type of object to create
+     * @param c The Class to create an object from.
+     * @return A newly created object of the Class.
+     * @throws SQLException if creation failed.
+     */
+    protected <T> T newInstance(final Class<T> c) throws SQLException {
+        try {
+            return c.getDeclaredConstructor().newInstance();
+
+        } catch (final IllegalAccessException | InstantiationException | InvocationTargetException |
+            NoSuchMethodException e) {
+            throw new SQLException("Cannot create " + c.getName() + ": " + e.getMessage());
+        }
+    }
+
+    /**
+     * Initializes the fields of the provided bean from the ResultSet.
+     * @param <T> The type of bean
+     * @param rs The result set.
+     * @param bean The bean to be populated.
+     * @return An initialized object.
+     * @throws SQLException if a database error occurs.
+     */
+    public <T> T populateBean(final ResultSet rs, final T bean) throws SQLException {
+        final PropertyDescriptor[] props = this.propertyDescriptors(bean.getClass());
+        final ResultSetMetaData rsmd = rs.getMetaData();
+        final int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
+
+        return populateBean(rs, bean, props, columnToProperty);
+    }
+
+    /**
+     * This method populates a bean from the ResultSet based upon the underlying meta-data.
+     *
+     * @param <T> The type of bean
+     * @param rs The result set.
+     * @param bean The bean to be populated.
+     * @param props The property descriptors.
+     * @param columnToProperty The column indices in the result set.
+     * @return An initialized object.
+     * @throws SQLException if a database error occurs.
+     */
+    private <T> T populateBean(final ResultSet rs, final T bean,
+            final PropertyDescriptor[] props, final int[] columnToProperty)
+            throws SQLException {
+
+        for (int i = 1; i < columnToProperty.length; i++) {
+
+            if (columnToProperty[i] == PROPERTY_NOT_FOUND) {
+                continue;
+            }
+
+            final PropertyDescriptor prop = props[columnToProperty[i]];
+            final Class<?> propType = prop.getPropertyType();
+
+            Object value = null;
+            if (propType != null) {
+                value = this.processColumn(rs, i, propType);
+
+                if (value == null && propType.isPrimitive()) {
+                    value = primitiveDefaults.get(propType);
+                }
+            }
+
+            this.callSetter(bean, prop, value);
+        }
+
+        return bean;
+    }
+
     /**
      * Convert a {@code ResultSet} column into an object.  Simple
      * implementations could just call {@code rs.getObject(index)} while
@@ -536,4 +425,115 @@ public class BeanProcessor {
 
     }
 
+    /**
+     * Returns a PropertyDescriptor[] for the given Class.
+     *
+     * @param c The Class to retrieve PropertyDescriptors for.
+     * @return A PropertyDescriptor[] describing the Class.
+     * @throws SQLException if introspection failed.
+     */
+    private PropertyDescriptor[] propertyDescriptors(final Class<?> c)
+        throws SQLException {
+        // Introspector caches BeanInfo classes for better performance
+        BeanInfo beanInfo = null;
+        try {
+            beanInfo = Introspector.getBeanInfo(c);
+
+        } catch (final IntrospectionException e) {
+            throw new SQLException(
+                "Bean introspection failed: " + e.getMessage());
+        }
+
+        return beanInfo.getPropertyDescriptors();
+    }
+
+    /**
+     * Convert a {@code ResultSet} row into a JavaBean.  This
+     * implementation uses reflection and {@code BeanInfo} classes to
+     * match column names to bean property names.  Properties are matched to
+     * columns based on several factors:
+     * &lt;br/&gt;
+     * &lt;ol&gt;
+     *     &lt;li&gt;
+     *     The class has a writable property with the same name as a column.
+     *     The name comparison is case insensitive.
+     *     &lt;/li&gt;
+     *
+     *     &lt;li&gt;
+     *     The column type can be converted to the property's set method
+     *     parameter type with a ResultSet.get* method.  If the conversion fails
+     *     (ie. the property was an int and the column was a Timestamp) an
+     *     SQLException is thrown.
+     *     &lt;/li&gt;
+     * &lt;/ol&gt;
+     *
+     * &lt;p&gt;
+     * Primitive bean properties are set to their defaults when SQL NULL is
+     * returned from the {@code ResultSet}.  Numeric fields are set to 0
+     * and booleans are set to false.  Object bean properties are set to
+     * {@code null} when SQL NULL is returned.  This is the same behavior
+     * as the {@code ResultSet} get* methods.
+     * &lt;/p&gt;
+     * @param <T> The type of bean to create
+     * @param rs ResultSet that supplies the bean data
+     * @param type Class from which to create the bean instance
+     * @throws SQLException if a database access error occurs
+     * @return the newly created bean
+     */
+    public <T> T toBean(final ResultSet rs, final Class<? extends T> type) throws SQLException {
+        final T bean = this.newInstance(type);
+        return this.populateBean(rs, bean);
+    }
+
+    /**
+     * Convert a {@code ResultSet} into a {@code List} of JavaBeans.
+     * This implementation uses reflection and {@code BeanInfo} classes to
+     * match column names to bean property names. Properties are matched to
+     * columns based on several factors:
+     * &lt;br/&gt;
+     * &lt;ol&gt;
+     *     &lt;li&gt;
+     *     The class has a writable property with the same name as a column.
+     *     The name comparison is case insensitive.
+     *     &lt;/li&gt;
+     *
+     *     &lt;li&gt;
+     *     The column type can be converted to the property's set method
+     *     parameter type with a ResultSet.get* method.  If the conversion fails
+     *     (ie. the property was an int and the column was a Timestamp) an
+     *     SQLException is thrown.
+     *     &lt;/li&gt;
+     * &lt;/ol&gt;
+     *
+     * <p>
+     * Primitive bean properties are set to their defaults when SQL NULL is
+     * returned from the {@code ResultSet}.  Numeric fields are set to 0
+     * and booleans are set to false.  Object bean properties are set to
+     * {@code null} when SQL NULL is returned.  This is the same behavior
+     * as the {@code ResultSet} get* methods.
+     * &lt;/p&gt;
+     * @param <T> The type of bean to create
+     * @param rs ResultSet that supplies the bean data
+     * @param type Class from which to create the bean instance
+     * @throws SQLException if a database access error occurs
+     * @return the newly created List of beans
+     */
+    public <T> List<T> toBeanList(final ResultSet rs, final Class<? extends T> type) throws SQLException {
+        final List<T> results = new ArrayList<>();
+
+        if (!rs.next()) {
+            return results;
+        }
+
+        final PropertyDescriptor[] props = this.propertyDescriptors(type);
+        final ResultSetMetaData rsmd = rs.getMetaData();
+        final int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
+
+        do {
+            results.add(this.createBean(rs, type, props, columnToProperty));
+        } while (rs.next());
+
+        return results;
+    }
+
 }
diff --git a/src/main/java/org/apache/commons/dbutils/ColumnHandler.java b/src/main/java/org/apache/commons/dbutils/ColumnHandler.java
index 173435c..b834475 100644
--- a/src/main/java/org/apache/commons/dbutils/ColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/ColumnHandler.java
@@ -24,15 +24,6 @@ import java.sql.SQLException;
  * {@link java.sql.ResultSet}.  ColumnHandlers do the work of retrieving data correctly from the {@code ResultSet}.
  */
 public interface ColumnHandler {
-    /**
-     * Test whether this {@code ColumnHandler} wants to handle a column targeted for a value type matching
-     * {@code propType}.
-     *
-     * @param propType The type of the target parameter.
-     * @return true is this property handler can/wants to handle this value; false otherwise.
-     */
-    boolean match(Class<?> propType);
-
     /**
      * Do the work required to retrieve and store a column from {@code ResultSet} into something of type
      * {@code propType}. This method is called only if this handler responded {@code true} after a call to
@@ -45,4 +36,13 @@ public interface ColumnHandler {
      *                called on a closed result set
      */
     Object apply(ResultSet rs, int columnIndex) throws SQLException;
+
+    /**
+     * Test whether this {@code ColumnHandler} wants to handle a column targeted for a value type matching
+     * {@code propType}.
+     *
+     * @param propType The type of the target parameter.
+     * @return true is this property handler can/wants to handle this value; false otherwise.
+     */
+    boolean match(Class<?> propType);
 }
diff --git a/src/main/java/org/apache/commons/dbutils/DbUtils.java b/src/main/java/org/apache/commons/dbutils/DbUtils.java
index 67f5ef5..87462d5 100644
--- a/src/main/java/org/apache/commons/dbutils/DbUtils.java
+++ b/src/main/java/org/apache/commons/dbutils/DbUtils.java
@@ -38,15 +38,93 @@ import java.util.logging.Logger;
 public final class DbUtils {
 
     /**
-     * Default constructor.
-     *
-     * Utility classes should not have a public or default constructor,
-     * but this one preserves retro-compatibility.
+     * Simple {@link Driver} proxy class that proxies a JDBC Driver loaded dynamically.
      *
-     * @since 1.4
+     * @since 1.6
      */
-    public DbUtils() {
-        // do nothing
+    static final class DriverProxy implements Driver {
+
+        private boolean parentLoggerSupported = true;
+
+        /**
+         * The adapted JDBC Driver loaded dynamically.
+         */
+        private final Driver adapted;
+
+        /**
+         * Creates a new JDBC Driver that adapts a JDBC Driver loaded dynamically.
+         *
+         * @param adapted the adapted JDBC Driver loaded dynamically.
+         */
+        public DriverProxy(final Driver adapted) {
+            this.adapted = adapted;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean acceptsURL(final String url) throws SQLException {
+            return adapted.acceptsURL(url);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Connection connect(final String url, final Properties info) throws SQLException {
+            return adapted.connect(url, info);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int getMajorVersion() {
+            return adapted.getMajorVersion();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int getMinorVersion() {
+            return adapted.getMinorVersion();
+        }
+
+        /**
+         * Java 1.7 method.
+         */
+        @Override
+        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+            if (parentLoggerSupported) {
+                try {
+                    final Method method = adapted.getClass().getMethod("getParentLogger");
+                    return (Logger)method.invoke(adapted);
+                } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+                    parentLoggerSupported = false;
+                    throw new SQLFeatureNotSupportedException(e);
+                }
+            }
+            throw new SQLFeatureNotSupportedException();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) throws SQLException {
+            return adapted.getPropertyInfo(url, info);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean jdbcCompliant() {
+            return adapted.jdbcCompliant();
+        }
+
     }
 
     /**
@@ -181,17 +259,6 @@ public final class DbUtils {
         }
     }
 
-    /**
-     * Loads and registers a database driver class.
-     * If this succeeds, it returns true, else it returns false.
-     *
-     * @param driverClassName of driver to load
-     * @return boolean {@code true} if the driver was found, otherwise {@code false}
-     */
-    public static boolean loadDriver(final String driverClassName) {
-        return loadDriver(DbUtils.class.getClassLoader(), driverClassName);
-    }
-
     /**
      * Loads and registers a database driver class.
      * If this succeeds, it returns true, else it returns false.
@@ -236,6 +303,17 @@ public final class DbUtils {
         }
     }
 
+    /**
+     * Loads and registers a database driver class.
+     * If this succeeds, it returns true, else it returns false.
+     *
+     * @param driverClassName of driver to load
+     * @return boolean {@code true} if the driver was found, otherwise {@code false}
+     */
+    public static boolean loadDriver(final String driverClassName) {
+        return loadDriver(DbUtils.class.getClassLoader(), driverClassName);
+    }
+
     /**
      * Print the stack trace for a SQLException to STDERR.
      *
@@ -301,21 +379,6 @@ public final class DbUtils {
     }
 
 
-    /**
-     * Performs a rollback on the <code>Connection</code>, avoid
-     * closing if null and hide any SQLExceptions that occur.
-     *
-     * @param conn Connection to rollback.  A null value is legal.
-     * @since DbUtils 2.0
-     */
-    public static void rollbackQuietly(Connection conn) {
-        try {
-            rollback(conn);
-        } catch (SQLException e) { // NOPMD
-            // quiet
-        }
-    }
-
     /**
      * Performs a rollback on the {@code Connection} then closes it,
      * avoid closing if null.
@@ -350,93 +413,30 @@ public final class DbUtils {
     }
 
     /**
-     * Simple {@link Driver} proxy class that proxies a JDBC Driver loaded dynamically.
+     * Performs a rollback on the <code>Connection</code>, avoid
+     * closing if null and hide any SQLExceptions that occur.
      *
-     * @since 1.6
+     * @param conn Connection to rollback.  A null value is legal.
+     * @since DbUtils 2.0
      */
-    static final class DriverProxy implements Driver {
-
-        private boolean parentLoggerSupported = true;
-
-        /**
-         * The adapted JDBC Driver loaded dynamically.
-         */
-        private final Driver adapted;
-
-        /**
-         * Creates a new JDBC Driver that adapts a JDBC Driver loaded dynamically.
-         *
-         * @param adapted the adapted JDBC Driver loaded dynamically.
-         */
-        public DriverProxy(final Driver adapted) {
-            this.adapted = adapted;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public boolean acceptsURL(final String url) throws SQLException {
-            return adapted.acceptsURL(url);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public Connection connect(final String url, final Properties info) throws SQLException {
-            return adapted.connect(url, info);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public int getMajorVersion() {
-            return adapted.getMajorVersion();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public int getMinorVersion() {
-            return adapted.getMinorVersion();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) throws SQLException {
-            return adapted.getPropertyInfo(url, info);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public boolean jdbcCompliant() {
-            return adapted.jdbcCompliant();
-        }
-
-        /**
-         * Java 1.7 method.
-         */
-        @Override
-        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-            if (parentLoggerSupported) {
-                try {
-                    final Method method = adapted.getClass().getMethod("getParentLogger");
-                    return (Logger)method.invoke(adapted);
-                } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
-                    parentLoggerSupported = false;
-                    throw new SQLFeatureNotSupportedException(e);
-                }
-            }
-            throw new SQLFeatureNotSupportedException();
+    public static void rollbackQuietly(Connection conn) {
+        try {
+            rollback(conn);
+        } catch (SQLException e) { // NOPMD
+            // quiet
         }
+    }
 
+    /**
+     * Default constructor.
+     *
+     * Utility classes should not have a public or default constructor,
+     * but this one preserves retro-compatibility.
+     *
+     * @since 1.4
+     */
+    public DbUtils() {
+        // do nothing
     }
 
 }
diff --git a/src/main/java/org/apache/commons/dbutils/OutParameter.java b/src/main/java/org/apache/commons/dbutils/OutParameter.java
index ced20cb..127c20a 100644
--- a/src/main/java/org/apache/commons/dbutils/OutParameter.java
+++ b/src/main/java/org/apache/commons/dbutils/OutParameter.java
@@ -69,14 +69,6 @@ public class OutParameter<T> {
         this.value = value;
     }
 
-    /**
-     * Get the JDBC SQL type for this OUT parameter.
-     * @return the JDBC SQL type for this OUT parameter.
-     */
-    public int getSqlType() {
-        return sqlType;
-    }
-
     /**
      * Get the Java class for this OUT parameter.
      * @return the Java class for this OUT parameter.
@@ -85,6 +77,14 @@ public class OutParameter<T> {
         return javaType;
     }
 
+    /**
+     * Get the JDBC SQL type for this OUT parameter.
+     * @return the JDBC SQL type for this OUT parameter.
+     */
+    public int getSqlType() {
+        return sqlType;
+    }
+
     /**
      * Get the value of the OUT parameter.  After the stored procedure has
      * been executed, the value is the value returned via this parameter.
@@ -95,13 +95,20 @@ public class OutParameter<T> {
     }
 
     /**
-     * Set the value of the OUT parameter.  If the value is not null when the
-     * stored procedure is executed, then the parameter will be treated like an
-     * INOUT parameter.
-     * @param value the new value for the parameter.
+     * Set up the given statement by registering an OUT parameter at the given
+     * index using the {@code sqlType} and {@code value} of this
+     * {@code OutParameter}.  If the value is not null, the parameter is
+     * treated like an INOUT parameter and the value is set on the statement.
+     * @param stmt the statement the parameter should register on.
+     * @param index the (1-based) index of the parameter.
+     * @throws SQLException if the parameter could not be registered, or if the
+     * value of the parameter could not be set.
      */
-    public void setValue(final T value) {
-        this.value = value;
+    void register(final CallableStatement stmt, final int index) throws SQLException {
+        stmt.registerOutParameter(index, sqlType);
+        if (value != null) {
+            stmt.setObject(index, value);
+        }
     }
 
     /**
@@ -118,20 +125,13 @@ public class OutParameter<T> {
     }
 
     /**
-     * Set up the given statement by registering an OUT parameter at the given
-     * index using the {@code sqlType} and {@code value} of this
-     * {@code OutParameter}.  If the value is not null, the parameter is
-     * treated like an INOUT parameter and the value is set on the statement.
-     * @param stmt the statement the parameter should register on.
-     * @param index the (1-based) index of the parameter.
-     * @throws SQLException if the parameter could not be registered, or if the
-     * value of the parameter could not be set.
+     * Set the value of the OUT parameter.  If the value is not null when the
+     * stored procedure is executed, then the parameter will be treated like an
+     * INOUT parameter.
+     * @param value the new value for the parameter.
      */
-    void register(final CallableStatement stmt, final int index) throws SQLException {
-        stmt.registerOutParameter(index, sqlType);
-        if (value != null) {
-            stmt.setObject(index, value);
-        }
+    public void setValue(final T value) {
+        this.value = value;
     }
 
     @Override
diff --git a/src/main/java/org/apache/commons/dbutils/PropertyHandler.java b/src/main/java/org/apache/commons/dbutils/PropertyHandler.java
index dfb4d55..4afb9d2 100644
--- a/src/main/java/org/apache/commons/dbutils/PropertyHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/PropertyHandler.java
@@ -23,22 +23,22 @@ package org.apache.commons.dbutils;
 public interface PropertyHandler {
 
     /**
-     * Test whether this {@code PropertyHandler} wants to handle setting {@code value} into something of type
-     * {@code parameter}.
+     * Do the work required to store {@code value} into something of type {@code parameter}. This method is
+     * called only if this handler responded {@code true} after a call to {@link #match(Class, Object)}.
      *
      * @param parameter The type of the target parameter.
      * @param value The value to be set.
-     * @return true is this property handler can/wants to handle this value; false otherwise.
+     * @return The converted value or the original value if something doesn't work out.
      */
-    boolean match(Class<?> parameter, Object value);
+    Object apply(Class<?> parameter, Object value);
 
     /**
-     * Do the work required to store {@code value} into something of type {@code parameter}. This method is
-     * called only if this handler responded {@code true} after a call to {@link #match(Class, Object)}.
+     * Test whether this {@code PropertyHandler} wants to handle setting {@code value} into something of type
+     * {@code parameter}.
      *
      * @param parameter The type of the target parameter.
      * @param value The value to be set.
-     * @return The converted value or the original value if something doesn't work out.
+     * @return true is this property handler can/wants to handle this value; false otherwise.
      */
-    Object apply(Class<?> parameter, Object value);
+    boolean match(Class<?> parameter, Object value);
 }
diff --git a/src/main/java/org/apache/commons/dbutils/ProxyFactory.java b/src/main/java/org/apache/commons/dbutils/ProxyFactory.java
index 474c2bc..8bba34f 100644
--- a/src/main/java/org/apache/commons/dbutils/ProxyFactory.java
+++ b/src/main/java/org/apache/commons/dbutils/ProxyFactory.java
@@ -56,18 +56,6 @@ public class ProxyFactory {
     protected ProxyFactory() {
     }
 
-    /**
-     * Convenience method to generate a single-interface proxy using the handler's classloader
-     *
-     * @param <T> The type of object to proxy
-     * @param type The type of object to proxy
-     * @param handler The handler that intercepts/overrides method calls.
-     * @return proxied object
-     */
-    public <T> T newProxyInstance(final Class<T> type, final InvocationHandler handler) {
-        return type.cast(Proxy.newProxyInstance(handler.getClass().getClassLoader(), new Class<?>[] {type}, handler));
-    }
-
     /**
      * Creates a new proxy {@code CallableStatement} object.
      * @param handler The handler that intercepts/overrides method calls.
@@ -131,4 +119,16 @@ public class ProxyFactory {
         return newProxyInstance(Statement.class, handler);
     }
 
+    /**
+     * Convenience method to generate a single-interface proxy using the handler's classloader
+     *
+     * @param <T> The type of object to proxy
+     * @param type The type of object to proxy
+     * @param handler The handler that intercepts/overrides method calls.
+     * @return proxied object
+     */
+    public <T> T newProxyInstance(final Class<T> type, final InvocationHandler handler) {
+        return type.cast(Proxy.newProxyInstance(handler.getClass().getClassLoader(), new Class<?>[] {type}, handler));
+    }
+
 }
diff --git a/src/main/java/org/apache/commons/dbutils/QueryRunner.java b/src/main/java/org/apache/commons/dbutils/QueryRunner.java
index 8ee89db..13a188d 100644
--- a/src/main/java/org/apache/commons/dbutils/QueryRunner.java
+++ b/src/main/java/org/apache/commons/dbutils/QueryRunner.java
@@ -65,16 +65,6 @@ public class QueryRunner extends AbstractQueryRunner {
         super(ds);
     }
 
-    /**
-     * Constructor for QueryRunner that takes a {@code StatementConfiguration} to configure statements when
-     * preparing them.
-     *
-     * @param stmtConfig The configuration to apply to statements when they are prepared.
-     */
-    public QueryRunner(final StatementConfiguration stmtConfig) {
-        super(stmtConfig);
-    }
-
     /**
      * Constructor for QueryRunner that takes a {@code DataSource} and controls the use of {@code ParameterMetaData}.
      * Methods that do not take a {@code Connection} parameter will retrieve connections from this
@@ -89,19 +79,6 @@ public class QueryRunner extends AbstractQueryRunner {
         super(ds, pmdKnownBroken);
     }
 
-    /**
-     * Constructor for QueryRunner that takes a {@code DataSource} to use and a {@code StatementConfiguration}.
-     *
-     * Methods that do not take a {@code Connection} parameter will retrieve connections from this
-     * {@code DataSource}.
-     *
-     * @param ds The {@code DataSource} to retrieve connections from.
-     * @param stmtConfig The configuration to apply to statements when they are prepared.
-     */
-    public QueryRunner(final DataSource ds, final StatementConfiguration stmtConfig) {
-        super(ds, stmtConfig);
-    }
-
     /**
      * Constructor for QueryRunner that takes a {@code DataSource}, a {@code StatementConfiguration}, and
      * controls the use of {@code ParameterMetaData}.  Methods that do not take a {@code Connection} parameter
@@ -118,38 +95,26 @@ public class QueryRunner extends AbstractQueryRunner {
     }
 
     /**
-     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.
+     * Constructor for QueryRunner that takes a {@code DataSource} to use and a {@code StatementConfiguration}.
      *
-     * @param conn The Connection to use to run the query.  The caller is
-     * responsible for closing this Connection.
-     * @param sql The SQL to execute.
-     * @param params An array of query replacement parameters.  Each row in
-     * this array is one set of batch replacement values.
-     * @return The number of rows updated per statement.
-     * @throws SQLException if a database access error occurs
-     * @since 1.1
+     * Methods that do not take a {@code Connection} parameter will retrieve connections from this
+     * {@code DataSource}.
+     *
+     * @param ds The {@code DataSource} to retrieve connections from.
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
      */
-    public int[] batch(final Connection conn, final String sql, final Object[][] params) throws SQLException {
-        return this.batch(conn, false, sql, params);
+    public QueryRunner(final DataSource ds, final StatementConfiguration stmtConfig) {
+        super(ds, stmtConfig);
     }
 
     /**
-     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.  The
-     * {@code Connection} is retrieved from the {@code DataSource}
-     * set in the constructor.  This {@code Connection} must be in
-     * auto-commit mode or the update will not be saved.
+     * Constructor for QueryRunner that takes a {@code StatementConfiguration} to configure statements when
+     * preparing them.
      *
-     * @param sql The SQL to execute.
-     * @param params An array of query replacement parameters.  Each row in
-     * this array is one set of batch replacement values.
-     * @return The number of rows updated per statement.
-     * @throws SQLException if a database access error occurs
-     * @since 1.1
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
      */
-    public int[] batch(final String sql, final Object[][] params) throws SQLException {
-        final Connection conn = this.prepareConnection();
-
-        return this.batch(conn, true, sql, params);
+    public QueryRunner(final StatementConfiguration stmtConfig) {
+        super(stmtConfig);
     }
 
     /**
@@ -209,161 +174,99 @@ public class QueryRunner extends AbstractQueryRunner {
     }
 
     /**
-     * Execute an SQL SELECT query with a single replacement parameter. The
-     * caller is responsible for closing the connection.
-     * @param <T> The type of object that the handler returns
-     * @param conn The connection to execute the query in.
-     * @param sql The query to execute.
-     * @param param The replacement parameter.
-     * @param rsh The handler that converts the results into an object.
-     * @return The object returned by the handler.
-     * @throws SQLException if a database access error occurs
-     * @deprecated Use {@link #query(Connection, String, ResultSetHandler, Object...)}
-     */
-    @Deprecated
-    public <T> T query(final Connection conn, final String sql, final Object param, final ResultSetHandler<T> rsh) throws SQLException {
-        return this.<T>query(conn, false, sql, rsh, param);
-    }
-
-    /**
-     * Execute an SQL SELECT query with replacement parameters.  The
-     * caller is responsible for closing the connection.
-     * @param <T> The type of object that the handler returns
-     * @param conn The connection to execute the query in.
-     * @param sql The query to execute.
-     * @param params The replacement parameters.
-     * @param rsh The handler that converts the results into an object.
-     * @return The object returned by the handler.
-     * @throws SQLException if a database access error occurs
-     * @deprecated Use {@link #query(Connection,String,ResultSetHandler,Object...)} instead
-     */
-    @Deprecated
-    public <T> T query(final Connection conn, final String sql, final Object[] params, final ResultSetHandler<T> rsh) throws SQLException {
-        return this.<T>query(conn, false, sql, rsh, params);
-    }
-
-    /**
-     * Execute an SQL SELECT query with replacement parameters.  The
-     * caller is responsible for closing the connection.
-     * @param <T> The type of object that the handler returns
-     * @param conn The connection to execute the query in.
-     * @param sql The query to execute.
-     * @param rsh The handler that converts the results into an object.
-     * @param params The replacement parameters.
-     * @return The object returned by the handler.
-     * @throws SQLException if a database access error occurs
-     */
-    public <T> T query(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        return this.<T>query(conn, false, sql, rsh, params);
-    }
-
-    /**
-     * Execute an SQL SELECT query without any replacement parameters.  The
-     * caller is responsible for closing the connection.
-     * @param <T> The type of object that the handler returns
-     * @param conn The connection to execute the query in.
-     * @param sql The query to execute.
-     * @param rsh The handler that converts the results into an object.
-     * @return The object returned by the handler.
+     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.
+     *
+     * @param conn The Connection to use to run the query.  The caller is
+     * responsible for closing this Connection.
+     * @param sql The SQL to execute.
+     * @param params An array of query replacement parameters.  Each row in
+     * this array is one set of batch replacement values.
+     * @return The number of rows updated per statement.
      * @throws SQLException if a database access error occurs
+     * @since 1.1
      */
-    public <T> T query(final Connection conn, final String sql, final ResultSetHandler<T> rsh) throws SQLException {
-        return this.<T>query(conn, false, sql, rsh, (Object[]) null);
+    public int[] batch(final Connection conn, final String sql, final Object[][] params) throws SQLException {
+        return this.batch(conn, false, sql, params);
     }
 
     /**
-     * Executes the given SELECT SQL with a single replacement parameter.
-     * The {@code Connection} is retrieved from the
-     * {@code DataSource} set in the constructor.
-     * @param <T> The type of object that the handler returns
-     * @param sql The SQL statement to execute.
-     * @param param The replacement parameter.
-     * @param rsh The handler used to create the result object from
-     * the {@code ResultSet}.
+     * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.  The
+     * {@code Connection} is retrieved from the {@code DataSource}
+     * set in the constructor.  This {@code Connection} must be in
+     * auto-commit mode or the update will not be saved.
      *
-     * @return An object generated by the handler.
+     * @param sql The SQL to execute.
+     * @param params An array of query replacement parameters.  Each row in
+     * this array is one set of batch replacement values.
+     * @return The number of rows updated per statement.
      * @throws SQLException if a database access error occurs
-     * @deprecated Use {@link #query(String, ResultSetHandler, Object...)}
+     * @since 1.1
      */
-    @Deprecated
-    public <T> T query(final String sql, final Object param, final ResultSetHandler<T> rsh) throws SQLException {
+    public int[] batch(final String sql, final Object[][] params) throws SQLException {
         final Connection conn = this.prepareConnection();
 
-        return this.<T>query(conn, true, sql, rsh, param);
+        return this.batch(conn, true, sql, params);
     }
 
     /**
-     * Executes the given SELECT SQL query and returns a result object.
-     * The {@code Connection} is retrieved from the
-     * {@code DataSource} set in the constructor.
-     * @param <T> The type of object that the handler returns
+     * Invokes the stored procedure via update after checking the parameters to
+     * ensure nothing is null.
+     * @param conn The connection to use for the update call.
+     * @param closeConn True if the connection should be closed, false otherwise.
      * @param sql The SQL statement to execute.
-     * @param params Initialize the PreparedStatement's IN parameters with
-     * this array.
-     *
-     * @param rsh The handler used to create the result object from
-     * the {@code ResultSet}.
-     *
-     * @return An object generated by the handler.
-     * @throws SQLException if a database access error occurs
-     * @deprecated Use {@link #query(String, ResultSetHandler, Object...)}
+     * @param params An array of update replacement parameters.  Each row in
+     * this array is one set of update replacement values.
+     * @return The number of rows updated.
+     * @throws SQLException If there are database or parameter errors.
      */
-    @Deprecated
-    public <T> T query(final String sql, final Object[] params, final ResultSetHandler<T> rsh) throws SQLException {
-        final Connection conn = this.prepareConnection();
+    private int execute(final Connection conn, final boolean closeConn, final String sql, final Object... params) throws SQLException {
+        if (conn == null) {
+            throw new SQLException("Null connection");
+        }
 
-        return this.<T>query(conn, true, sql, rsh, params);
-    }
+        if (sql == null) {
+            if (closeConn) {
+                close(conn);
+            }
+            throw new SQLException("Null SQL statement");
+        }
 
-    /**
-     * Executes the given SELECT SQL query and returns a result object.
-     * The {@code Connection} is retrieved from the
-     * {@code DataSource} set in the constructor.
-     * @param <T> The type of object that the handler returns
-     * @param sql The SQL statement to execute.
-     * @param rsh The handler used to create the result object from
-     * the {@code ResultSet}.
-     * @param params Initialize the PreparedStatement's IN parameters with
-     * this array.
-     * @return An object generated by the handler.
-     * @throws SQLException if a database access error occurs
-     */
-    public <T> T query(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        final Connection conn = this.prepareConnection();
+        CallableStatement stmt = null;
+        int rows = 0;
 
-        return this.<T>query(conn, true, sql, rsh, params);
-    }
+        try {
+            stmt = this.prepareCall(conn, sql);
+            this.fillStatement(stmt, params);
+            stmt.execute();
+            rows = stmt.getUpdateCount();
+            this.retrieveOutParameters(stmt, params);
 
-    /**
-     * Executes the given SELECT SQL without any replacement parameters.
-     * The {@code Connection} is retrieved from the
-     * {@code DataSource} set in the constructor.
-     * @param <T> The type of object that the handler returns
-     * @param sql The SQL statement to execute.
-     * @param rsh The handler used to create the result object from
-     * the {@code ResultSet}.
-     *
-     * @return An object generated by the handler.
-     * @throws SQLException if a database access error occurs
-     */
-    public <T> T query(final String sql, final ResultSetHandler<T> rsh) throws SQLException {
-        final Connection conn = this.prepareConnection();
+        } catch (final SQLException e) {
+            this.rethrow(e, sql, params);
 
-        return this.<T>query(conn, true, sql, rsh, (Object[]) null);
+        } finally {
+            close(stmt);
+            if (closeConn) {
+                close(conn);
+            }
+        }
+
+        return rows;
     }
 
     /**
-     * Calls query after checking the parameters to ensure nothing is null.
-     * @param conn The connection to use for the query call.
+     * Invokes the stored procedure via update after checking the parameters to
+     * ensure nothing is null.
+     * @param conn The connection to use for the update call.
      * @param closeConn True if the connection should be closed, false otherwise.
      * @param sql The SQL statement to execute.
-     * @param params An array of query replacement parameters.  Each row in
-     * this array is one set of batch replacement values.
-     * @return The results of the query.
+     * @param rsh The result set handler
+     * @param params An array of update replacement parameters.  Each row in
+     * this array is one set of update replacement values.
+     * @return List of all objects generated by the ResultSetHandler for all result sets handled.
      * @throws SQLException If there are database or parameter errors.
      */
-    private <T> T query(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object... params)
-            throws SQLException {
+    private <T> List<T> execute(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
         if (conn == null) {
             throw new SQLException("Null connection");
         }
@@ -382,140 +285,159 @@ public class QueryRunner extends AbstractQueryRunner {
             throw new SQLException("Null ResultSetHandler");
         }
 
-        Statement stmt = null;
-        ResultSet rs = null;
-        T result = null;
+        CallableStatement stmt = null;
+        final List<T> results = new LinkedList<>();
 
         try {
-            if (params != null && params.length > 0) {
-                final PreparedStatement ps = this.prepareStatement(conn, sql);
-                stmt = ps;
-                this.fillStatement(ps, params);
-                rs = this.wrap(ps.executeQuery());
-            } else {
-                stmt = conn.createStatement();
-                rs = this.wrap(stmt.executeQuery(sql));
+            stmt = this.prepareCall(conn, sql);
+            this.fillStatement(stmt, params);
+            boolean moreResultSets = stmt.execute();
+            // Handle multiple result sets by passing them through the handler
+            // retaining the final result
+            ResultSet rs = null;
+            while (moreResultSets) {
+                try {
+                    rs = this.wrap(stmt.getResultSet());
+                    results.add(rsh.handle(rs));
+                    moreResultSets = stmt.getMoreResults();
+
+                } finally {
+                    close(rs);
+                }
             }
-            result = rsh.handle(rs);
+            this.retrieveOutParameters(stmt, params);
 
         } catch (final SQLException e) {
             this.rethrow(e, sql, params);
 
         } finally {
-            closeQuietly(rs);
-            closeQuietly(stmt);
+            close(stmt);
             if (closeConn) {
                 close(conn);
             }
         }
 
-        return result;
-    }
-
-    /**
-     * Execute an SQL INSERT, UPDATE, or DELETE query without replacement
-     * parameters.
-     *
-     * @param conn The connection to use to run the query.
-     * @param sql The SQL to execute.
-     * @return The number of rows updated.
-     * @throws SQLException if a database access error occurs
-     */
-    public int update(final Connection conn, final String sql) throws SQLException {
-        return this.update(conn, false, sql, (Object[]) null);
+        return results;
     }
 
     /**
-     * Execute an SQL INSERT, UPDATE, or DELETE query with a single replacement
-     * parameter.
+     * Execute an SQL statement, including a stored procedure call, which does
+     * not return any result sets.
+     * Any parameters which are instances of {@link OutParameter} will be
+     * registered as OUT parameters.
+     * <p>
+     * Use this method when invoking a stored procedure with OUT parameters
+     * that does not return any result sets.  If you are not invoking a stored
+     * procedure, or the stored procedure has no OUT parameters, consider using
+     * {@link #update(java.sql.Connection, String, Object...) }.
+     * If the stored procedure returns result sets, use
+     * {@link #execute(java.sql.Connection, String, org.apache.commons.dbutils.ResultSetHandler, Object...) }.
      *
      * @param conn The connection to use to run the query.
      * @param sql The SQL to execute.
-     * @param param The replacement parameter.
+     * @param params The query replacement parameters.
      * @return The number of rows updated.
      * @throws SQLException if a database access error occurs
      */
-    public int update(final Connection conn, final String sql, final Object param) throws SQLException {
-        return this.update(conn, false, sql, param);
+    public int execute(final Connection conn, final String sql, final Object... params) throws SQLException {
+        return this.execute(conn, false, sql, params);
     }
 
     /**
-     * Execute an SQL INSERT, UPDATE, or DELETE query.
+     * Execute an SQL statement, including a stored procedure call, which
+     * returns one or more result sets.
+     * Any parameters which are instances of {@link OutParameter} will be
+     * registered as OUT parameters.
+     * <p>
+     * Use this method when: a) running SQL statements that return multiple
+     * result sets; b) invoking a stored procedure that return result
+     * sets and OUT parameters.  Otherwise you may wish to use
+     * {@link #query(java.sql.Connection, String, org.apache.commons.dbutils.ResultSetHandler, Object...) }
+     * (if there are no OUT parameters) or
+     * {@link #execute(java.sql.Connection, String, Object...) }
+     * (if there are no result sets).
      *
+     * @param <T> The type of object that the handler returns
      * @param conn The connection to use to run the query.
      * @param sql The SQL to execute.
+     * @param rsh The result set handler
      * @param params The query replacement parameters.
-     * @return The number of rows updated.
-     * @throws SQLException if a database access error occurs
-     */
-    public int update(final Connection conn, final String sql, final Object... params) throws SQLException {
-        return update(conn, false, sql, params);
-    }
-
-    /**
-     * Executes the given INSERT, UPDATE, or DELETE SQL statement without
-     * any replacement parameters. The {@code Connection} is retrieved
-     * from the {@code DataSource} set in the constructor.  This
-     * {@code Connection} must be in auto-commit mode or the update will
-     * not be saved.
-     *
-     * @param sql The SQL statement to execute.
+     * @return A list of objects generated by the handler
      * @throws SQLException if a database access error occurs
-     * @return The number of rows updated.
      */
-    public int update(final String sql) throws SQLException {
-        final Connection conn = this.prepareConnection();
-
-        return this.update(conn, true, sql, (Object[]) null);
+    public <T> List<T> execute(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+        return this.execute(conn, false, sql, rsh, params);
     }
 
     /**
-     * Executes the given INSERT, UPDATE, or DELETE SQL statement with
-     * a single replacement parameter.  The {@code Connection} is
-     * retrieved from the {@code DataSource} set in the constructor.
-     * This {@code Connection} must be in auto-commit mode or the
-     * update will not be saved.
+     * Execute an SQL statement, including a stored procedure call, which does
+     * not return any result sets.
+     * Any parameters which are instances of {@link OutParameter} will be
+     * registered as OUT parameters.
+     * <p>
+     * Use this method when invoking a stored procedure with OUT parameters
+     * that does not return any result sets.  If you are not invoking a stored
+     * procedure, or the stored procedure has no OUT parameters, consider using
+     * {@link #update(String, Object...) }.
+     * If the stored procedure returns result sets, use
+     * {@link #execute(String, org.apache.commons.dbutils.ResultSetHandler, Object...) }.
+     * <p>
+     * The {@code Connection} is retrieved from the {@code DataSource}
+     * set in the constructor.  This {@code Connection} must be in
+     * auto-commit mode or the update will not be saved.
      *
      * @param sql The SQL statement to execute.
-     * @param param The replacement parameter.
+     * @param params Initializes the CallableStatement's parameters (i.e. '?').
      * @throws SQLException if a database access error occurs
      * @return The number of rows updated.
      */
-    public int update(final String sql, final Object param) throws SQLException {
+    public int execute(final String sql, final Object... params) throws SQLException {
         final Connection conn = this.prepareConnection();
 
-        return this.update(conn, true, sql, param);
+        return this.execute(conn, true, sql, params);
     }
 
     /**
-     * Executes the given INSERT, UPDATE, or DELETE SQL statement.  The
-     * {@code Connection} is retrieved from the {@code DataSource}
-     * set in the constructor.  This {@code Connection} must be in
-     * auto-commit mode or the update will not be saved.
+     * Execute an SQL statement, including a stored procedure call, which
+     * returns one or more result sets.
+     * Any parameters which are instances of {@link OutParameter} will be
+     * registered as OUT parameters.
+     * <p>
+     * Use this method when: a) running SQL statements that return multiple
+     * result sets; b) invoking a stored procedure that return result
+     * sets and OUT parameters.  Otherwise you may wish to use
+     * {@link #query(String, org.apache.commons.dbutils.ResultSetHandler, Object...) }
+     * (if there are no OUT parameters) or
+     * {@link #execute(String, Object...) }
+     * (if there are no result sets).
      *
-     * @param sql The SQL statement to execute.
-     * @param params Initializes the PreparedStatement's IN (i.e. '?')
-     * parameters.
+     * @param <T> The type of object that the handler returns
+     * @param sql The SQL to execute.
+     * @param rsh The result set handler
+     * @param params The query replacement parameters.
+     * @return A list of objects generated by the handler
      * @throws SQLException if a database access error occurs
-     * @return The number of rows updated.
      */
-    public int update(final String sql, final Object... params) throws SQLException {
+    public <T> List<T> execute(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
         final Connection conn = this.prepareConnection();
 
-        return this.update(conn, true, sql, params);
+        return this.execute(conn, true, sql, rsh, params);
     }
 
     /**
-     * Calls update after checking the parameters to ensure nothing is null.
-     * @param conn The connection to use for the update call.
+     * Executes the given INSERT SQL statement.
+     * @param conn The connection to use for the query call.
      * @param closeConn True if the connection should be closed, false otherwise.
      * @param sql The SQL statement to execute.
-     * @param params An array of update replacement parameters.  Each row in
-     * this array is one set of update replacement values.
-     * @return The number of rows updated.
+     * @param rsh The handler used to create the result object from
+     * the {@code ResultSet} of auto-generated keys.
+     * @param params The query replacement parameters.
+     * @return An object generated by the handler.
      * @throws SQLException If there are database or parameter errors.
+     * @since 1.6
      */
-    private int update(final Connection conn, final boolean closeConn, final String sql, final Object... params) throws SQLException {
+    private <T> T insert(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object... params)
+            throws SQLException {
         if (conn == null) {
             throw new SQLException("Null connection");
         }
@@ -527,23 +449,30 @@ public class QueryRunner extends AbstractQueryRunner {
             throw new SQLException("Null SQL statement");
         }
 
+        if (rsh == null) {
+            if (closeConn) {
+                close(conn);
+            }
+            throw new SQLException("Null ResultSetHandler");
+        }
+
         Statement stmt = null;
-        int rows = 0;
+        T generatedKeys = null;
 
         try {
             if (params != null && params.length > 0) {
-                final PreparedStatement ps = this.prepareStatement(conn, sql);
+                final PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                 stmt = ps;
                 this.fillStatement(ps, params);
-                rows = ps.executeUpdate();
+                ps.executeUpdate();
             } else {
                 stmt = conn.createStatement();
-                rows = stmt.executeUpdate(sql);
+                stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
             }
-
+            final ResultSet resultSet = stmt.getGeneratedKeys();
+            generatedKeys = rsh.handle(resultSet);
         } catch (final SQLException e) {
             this.rethrow(e, sql, params);
-
         } finally {
             close(stmt);
             if (closeConn) {
@@ -551,87 +480,87 @@ public class QueryRunner extends AbstractQueryRunner {
             }
         }
 
-        return rows;
+        return generatedKeys;
     }
 
     /**
-     * Executes the given INSERT SQL without any replacement parameters.
-     * The {@code Connection} is retrieved from the
-     * {@code DataSource} set in the constructor.
+     * Execute an SQL INSERT query without replacement parameters.
      * @param <T> The type of object that the handler returns
-     * @param sql The SQL statement to execute.
+     * @param conn The connection to use to run the query.
+     * @param sql The SQL to execute.
      * @param rsh The handler used to create the result object from
      * the {@code ResultSet} of auto-generated keys.
      * @return An object generated by the handler.
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
-    public <T> T insert(final String sql, final ResultSetHandler<T> rsh) throws SQLException {
-        return insert(this.prepareConnection(), true, sql, rsh, (Object[]) null);
+    public <T> T insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh) throws SQLException {
+        return insert(conn, false, sql, rsh, (Object[]) null);
     }
 
     /**
-     * Executes the given INSERT SQL statement. The
-     * {@code Connection} is retrieved from the {@code DataSource}
-     * set in the constructor.  This {@code Connection} must be in
-     * auto-commit mode or the insert will not be saved.
+     * Execute an SQL INSERT query.
      * @param <T> The type of object that the handler returns
-     * @param sql The SQL statement to execute.
+     * @param conn The connection to use to run the query.
+     * @param sql The SQL to execute.
      * @param rsh The handler used to create the result object from
      * the {@code ResultSet} of auto-generated keys.
-     * @param params Initializes the PreparedStatement's IN (i.e. '?')
+     * @param params The query replacement parameters.
      * @return An object generated by the handler.
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
-    public <T> T insert(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        return insert(this.prepareConnection(), true, sql, rsh, params);
+    public <T> T insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+        return insert(conn, false, sql, rsh, params);
     }
 
     /**
-     * Execute an SQL INSERT query without replacement parameters.
+     * Executes the given INSERT SQL without any replacement parameters.
+     * The {@code Connection} is retrieved from the
+     * {@code DataSource} set in the constructor.
      * @param <T> The type of object that the handler returns
-     * @param conn The connection to use to run the query.
-     * @param sql The SQL to execute.
+     * @param sql The SQL statement to execute.
      * @param rsh The handler used to create the result object from
      * the {@code ResultSet} of auto-generated keys.
      * @return An object generated by the handler.
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
-    public <T> T insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh) throws SQLException {
-        return insert(conn, false, sql, rsh, (Object[]) null);
+    public <T> T insert(final String sql, final ResultSetHandler<T> rsh) throws SQLException {
+        return insert(this.prepareConnection(), true, sql, rsh, (Object[]) null);
     }
 
     /**
-     * Execute an SQL INSERT query.
+     * Executes the given INSERT SQL statement. The
+     * {@code Connection} is retrieved from the {@code DataSource}
+     * set in the constructor.  This {@code Connection} must be in
+     * auto-commit mode or the insert will not be saved.
      * @param <T> The type of object that the handler returns
-     * @param conn The connection to use to run the query.
-     * @param sql The SQL to execute.
+     * @param sql The SQL statement to execute.
      * @param rsh The handler used to create the result object from
      * the {@code ResultSet} of auto-generated keys.
-     * @param params The query replacement parameters.
+     * @param params Initializes the PreparedStatement's IN (i.e. '?')
      * @return An object generated by the handler.
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
-    public <T> T insert(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        return insert(conn, false, sql, rsh, params);
+    public <T> T insert(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+        return insert(this.prepareConnection(), true, sql, rsh, params);
     }
 
     /**
-     * Executes the given INSERT SQL statement.
+     * Executes the given batch of INSERT SQL statements.
      * @param conn The connection to use for the query call.
      * @param closeConn True if the connection should be closed, false otherwise.
      * @param sql The SQL statement to execute.
      * @param rsh The handler used to create the result object from
      * the {@code ResultSet} of auto-generated keys.
      * @param params The query replacement parameters.
-     * @return An object generated by the handler.
+     * @return The result generated by the handler.
      * @throws SQLException If there are database or parameter errors.
      * @since 1.6
      */
-    private <T> T insert(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object... params)
+    private <T> T insertBatch(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object[][] params)
             throws SQLException {
         if (conn == null) {
             throw new SQLException("Null connection");
@@ -644,30 +573,28 @@ public class QueryRunner extends AbstractQueryRunner {
             throw new SQLException("Null SQL statement");
         }
 
-        if (rsh == null) {
+        if (params == null) {
             if (closeConn) {
                 close(conn);
             }
-            throw new SQLException("Null ResultSetHandler");
+            throw new SQLException("Null parameters. If parameters aren't need, pass an empty array.");
         }
 
-        Statement stmt = null;
+        PreparedStatement stmt = null;
         T generatedKeys = null;
-
         try {
-            if (params != null && params.length > 0) {
-                final PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
-                stmt = ps;
-                this.fillStatement(ps, params);
-                ps.executeUpdate();
-            } else {
-                stmt = conn.createStatement();
-                stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
+            stmt = this.prepareStatement(conn, sql, Statement.RETURN_GENERATED_KEYS);
+
+            for (final Object[] param : params) {
+                this.fillStatement(stmt, param);
+                stmt.addBatch();
             }
-            final ResultSet resultSet = stmt.getGeneratedKeys();
-            generatedKeys = rsh.handle(resultSet);
+            stmt.executeBatch();
+            final ResultSet rs = stmt.getGeneratedKeys();
+            generatedKeys = rsh.handle(rs);
+
         } catch (final SQLException e) {
-            this.rethrow(e, sql, params);
+            this.rethrow(e, sql, (Object[])params);
         } finally {
             close(stmt);
             if (closeConn) {
@@ -679,52 +606,50 @@ public class QueryRunner extends AbstractQueryRunner {
     }
 
     /**
-     * Executes the given batch of INSERT SQL statements. The
-     * {@code Connection} is retrieved from the {@code DataSource}
-     * set in the constructor.  This {@code Connection} must be in
-     * auto-commit mode or the insert will not be saved.
+     * Executes the given batch of INSERT SQL statements.
      * @param <T> The type of object that the handler returns
-     * @param sql The SQL statement to execute.
+     * @param conn The connection to use to run the query.
+     * @param sql The SQL to execute.
      * @param rsh The handler used to create the result object from
      * the {@code ResultSet} of auto-generated keys.
-     * @param params Initializes the PreparedStatement's IN (i.e. '?')
+     * @param params The query replacement parameters.
      * @return The result generated by the handler.
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
-    public <T> T insertBatch(final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
-        return insertBatch(this.prepareConnection(), true, sql, rsh, params);
+    public <T> T insertBatch(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
+        return insertBatch(conn, false, sql, rsh, params);
     }
 
     /**
-     * Executes the given batch of INSERT SQL statements.
+     * Executes the given batch of INSERT SQL statements. The
+     * {@code Connection} is retrieved from the {@code DataSource}
+     * set in the constructor.  This {@code Connection} must be in
+     * auto-commit mode or the insert will not be saved.
      * @param <T> The type of object that the handler returns
-     * @param conn The connection to use to run the query.
-     * @param sql The SQL to execute.
+     * @param sql The SQL statement to execute.
      * @param rsh The handler used to create the result object from
      * the {@code ResultSet} of auto-generated keys.
-     * @param params The query replacement parameters.
+     * @param params Initializes the PreparedStatement's IN (i.e. '?')
      * @return The result generated by the handler.
      * @throws SQLException if a database access error occurs
      * @since 1.6
      */
-    public <T> T insertBatch(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
-        return insertBatch(conn, false, sql, rsh, params);
+    public <T> T insertBatch(final String sql, final ResultSetHandler<T> rsh, final Object[][] params) throws SQLException {
+        return insertBatch(this.prepareConnection(), true, sql, rsh, params);
     }
 
     /**
-     * Executes the given batch of INSERT SQL statements.
+     * Calls query after checking the parameters to ensure nothing is null.
      * @param conn The connection to use for the query call.
      * @param closeConn True if the connection should be closed, false otherwise.
      * @param sql The SQL statement to execute.
-     * @param rsh The handler used to create the result object from
-     * the {@code ResultSet} of auto-generated keys.
-     * @param params The query replacement parameters.
-     * @return The result generated by the handler.
+     * @param params An array of query replacement parameters.  Each row in
+     * this array is one set of batch replacement values.
+     * @return The results of the query.
      * @throws SQLException If there are database or parameter errors.
-     * @since 1.6
      */
-    private <T> T insertBatch(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object[][] params)
+    private <T> T query(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object... params)
             throws SQLException {
         if (conn == null) {
             throw new SQLException("Null connection");
@@ -737,145 +662,208 @@ public class QueryRunner extends AbstractQueryRunner {
             throw new SQLException("Null SQL statement");
         }
 
-        if (params == null) {
+        if (rsh == null) {
             if (closeConn) {
                 close(conn);
             }
-            throw new SQLException("Null parameters. If parameters aren't need, pass an empty array.");
+            throw new SQLException("Null ResultSetHandler");
         }
 
-        PreparedStatement stmt = null;
-        T generatedKeys = null;
-        try {
-            stmt = this.prepareStatement(conn, sql, Statement.RETURN_GENERATED_KEYS);
+        Statement stmt = null;
+        ResultSet rs = null;
+        T result = null;
 
-            for (final Object[] param : params) {
-                this.fillStatement(stmt, param);
-                stmt.addBatch();
+        try {
+            if (params != null && params.length > 0) {
+                final PreparedStatement ps = this.prepareStatement(conn, sql);
+                stmt = ps;
+                this.fillStatement(ps, params);
+                rs = this.wrap(ps.executeQuery());
+            } else {
+                stmt = conn.createStatement();
+                rs = this.wrap(stmt.executeQuery(sql));
             }
-            stmt.executeBatch();
-            final ResultSet rs = stmt.getGeneratedKeys();
-            generatedKeys = rsh.handle(rs);
+            result = rsh.handle(rs);
 
         } catch (final SQLException e) {
-            this.rethrow(e, sql, (Object[])params);
+            this.rethrow(e, sql, params);
+
         } finally {
-            close(stmt);
+            closeQuietly(rs);
+            closeQuietly(stmt);
             if (closeConn) {
                 close(conn);
             }
         }
 
-        return generatedKeys;
+        return result;
     }
 
     /**
-     * Execute an SQL statement, including a stored procedure call, which does
-     * not return any result sets.
-     * Any parameters which are instances of {@link OutParameter} will be
-     * registered as OUT parameters.
-     * <p>
-     * Use this method when invoking a stored procedure with OUT parameters
-     * that does not return any result sets.  If you are not invoking a stored
-     * procedure, or the stored procedure has no OUT parameters, consider using
-     * {@link #update(java.sql.Connection, String, Object...) }.
-     * If the stored procedure returns result sets, use
-     * {@link #execute(java.sql.Connection, String, org.apache.commons.dbutils.ResultSetHandler, Object...) }.
-     *
-     * @param conn The connection to use to run the query.
-     * @param sql The SQL to execute.
-     * @param params The query replacement parameters.
-     * @return The number of rows updated.
+     * Execute an SQL SELECT query with a single replacement parameter. The
+     * caller is responsible for closing the connection.
+     * @param <T> The type of object that the handler returns
+     * @param conn The connection to execute the query in.
+     * @param sql The query to execute.
+     * @param param The replacement parameter.
+     * @param rsh The handler that converts the results into an object.
+     * @return The object returned by the handler.
      * @throws SQLException if a database access error occurs
+     * @deprecated Use {@link #query(Connection, String, ResultSetHandler, Object...)}
      */
-    public int execute(final Connection conn, final String sql, final Object... params) throws SQLException {
-        return this.execute(conn, false, sql, params);
+    @Deprecated
+    public <T> T query(final Connection conn, final String sql, final Object param, final ResultSetHandler<T> rsh) throws SQLException {
+        return this.<T>query(conn, false, sql, rsh, param);
     }
 
     /**
-     * Execute an SQL statement, including a stored procedure call, which does
-     * not return any result sets.
-     * Any parameters which are instances of {@link OutParameter} will be
-     * registered as OUT parameters.
-     * <p>
-     * Use this method when invoking a stored procedure with OUT parameters
-     * that does not return any result sets.  If you are not invoking a stored
-     * procedure, or the stored procedure has no OUT parameters, consider using
-     * {@link #update(String, Object...) }.
-     * If the stored procedure returns result sets, use
-     * {@link #execute(String, org.apache.commons.dbutils.ResultSetHandler, Object...) }.
-     * <p>
-     * The {@code Connection} is retrieved from the {@code DataSource}
-     * set in the constructor.  This {@code Connection} must be in
-     * auto-commit mode or the update will not be saved.
-     *
+     * Execute an SQL SELECT query with replacement parameters.  The
+     * caller is responsible for closing the connection.
+     * @param <T> The type of object that the handler returns
+     * @param conn The connection to execute the query in.
+     * @param sql The query to execute.
+     * @param params The replacement parameters.
+     * @param rsh The handler that converts the results into an object.
+     * @return The object returned by the handler.
+     * @throws SQLException if a database access error occurs
+     * @deprecated Use {@link #query(Connection,String,ResultSetHandler,Object...)} instead
+     */
+    @Deprecated
+    public <T> T query(final Connection conn, final String sql, final Object[] params, final ResultSetHandler<T> rsh) throws SQLException {
+        return this.<T>query(conn, false, sql, rsh, params);
+    }
+
+    /**
+     * Execute an SQL SELECT query without any replacement parameters.  The
+     * caller is responsible for closing the connection.
+     * @param <T> The type of object that the handler returns
+     * @param conn The connection to execute the query in.
+     * @param sql The query to execute.
+     * @param rsh The handler that converts the results into an object.
+     * @return The object returned by the handler.
+     * @throws SQLException if a database access error occurs
+     */
+    public <T> T query(final Connection conn, final String sql, final ResultSetHandler<T> rsh) throws SQLException {
+        return this.<T>query(conn, false, sql, rsh, (Object[]) null);
+    }
+
+    /**
+     * Execute an SQL SELECT query with replacement parameters.  The
+     * caller is responsible for closing the connection.
+     * @param <T> The type of object that the handler returns
+     * @param conn The connection to execute the query in.
+     * @param sql The query to execute.
+     * @param rsh The handler that converts the results into an object.
+     * @param params The replacement parameters.
+     * @return The object returned by the handler.
+     * @throws SQLException if a database access error occurs
+     */
+    public <T> T query(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+        return this.<T>query(conn, false, sql, rsh, params);
+    }
+
+    /**
+     * Executes the given SELECT SQL with a single replacement parameter.
+     * The {@code Connection} is retrieved from the
+     * {@code DataSource} set in the constructor.
+     * @param <T> The type of object that the handler returns
      * @param sql The SQL statement to execute.
-     * @param params Initializes the CallableStatement's parameters (i.e. '?').
+     * @param param The replacement parameter.
+     * @param rsh The handler used to create the result object from
+     * the {@code ResultSet}.
+     *
+     * @return An object generated by the handler.
      * @throws SQLException if a database access error occurs
-     * @return The number of rows updated.
+     * @deprecated Use {@link #query(String, ResultSetHandler, Object...)}
      */
-    public int execute(final String sql, final Object... params) throws SQLException {
+    @Deprecated
+    public <T> T query(final String sql, final Object param, final ResultSetHandler<T> rsh) throws SQLException {
         final Connection conn = this.prepareConnection();
 
-        return this.execute(conn, true, sql, params);
+        return this.<T>query(conn, true, sql, rsh, param);
     }
 
     /**
-     * Execute an SQL statement, including a stored procedure call, which
-     * returns one or more result sets.
-     * Any parameters which are instances of {@link OutParameter} will be
-     * registered as OUT parameters.
-     * <p>
-     * Use this method when: a) running SQL statements that return multiple
-     * result sets; b) invoking a stored procedure that return result
-     * sets and OUT parameters.  Otherwise you may wish to use
-     * {@link #query(java.sql.Connection, String, org.apache.commons.dbutils.ResultSetHandler, Object...) }
-     * (if there are no OUT parameters) or
-     * {@link #execute(java.sql.Connection, String, Object...) }
-     * (if there are no result sets).
-     *
+     * Executes the given SELECT SQL query and returns a result object.
+     * The {@code Connection} is retrieved from the
+     * {@code DataSource} set in the constructor.
      * @param <T> The type of object that the handler returns
-     * @param conn The connection to use to run the query.
-     * @param sql The SQL to execute.
-     * @param rsh The result set handler
-     * @param params The query replacement parameters.
-     * @return A list of objects generated by the handler
+     * @param sql The SQL statement to execute.
+     * @param params Initialize the PreparedStatement's IN parameters with
+     * this array.
+     *
+     * @param rsh The handler used to create the result object from
+     * the {@code ResultSet}.
+     *
+     * @return An object generated by the handler.
      * @throws SQLException if a database access error occurs
+     * @deprecated Use {@link #query(String, ResultSetHandler, Object...)}
      */
-    public <T> List<T> execute(final Connection conn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        return this.execute(conn, false, sql, rsh, params);
+    @Deprecated
+    public <T> T query(final String sql, final Object[] params, final ResultSetHandler<T> rsh) throws SQLException {
+        final Connection conn = this.prepareConnection();
+
+        return this.<T>query(conn, true, sql, rsh, params);
     }
 
     /**
-     * Execute an SQL statement, including a stored procedure call, which
-     * returns one or more result sets.
-     * Any parameters which are instances of {@link OutParameter} will be
-     * registered as OUT parameters.
-     * <p>
-     * Use this method when: a) running SQL statements that return multiple
-     * result sets; b) invoking a stored procedure that return result
-     * sets and OUT parameters.  Otherwise you may wish to use
-     * {@link #query(String, org.apache.commons.dbutils.ResultSetHandler, Object...) }
-     * (if there are no OUT parameters) or
-     * {@link #execute(String, Object...) }
-     * (if there are no result sets).
+     * Executes the given SELECT SQL without any replacement parameters.
+     * The {@code Connection} is retrieved from the
+     * {@code DataSource} set in the constructor.
+     * @param <T> The type of object that the handler returns
+     * @param sql The SQL statement to execute.
+     * @param rsh The handler used to create the result object from
+     * the {@code ResultSet}.
      *
+     * @return An object generated by the handler.
+     * @throws SQLException if a database access error occurs
+     */
+    public <T> T query(final String sql, final ResultSetHandler<T> rsh) throws SQLException {
+        final Connection conn = this.prepareConnection();
+
+        return this.<T>query(conn, true, sql, rsh, (Object[]) null);
+    }
+
+    /**
+     * Executes the given SELECT SQL query and returns a result object.
+     * The {@code Connection} is retrieved from the
+     * {@code DataSource} set in the constructor.
      * @param <T> The type of object that the handler returns
-     * @param sql The SQL to execute.
-     * @param rsh The result set handler
-     * @param params The query replacement parameters.
-     * @return A list of objects generated by the handler
+     * @param sql The SQL statement to execute.
+     * @param rsh The handler used to create the result object from
+     * the {@code ResultSet}.
+     * @param params Initialize the PreparedStatement's IN parameters with
+     * this array.
+     * @return An object generated by the handler.
      * @throws SQLException if a database access error occurs
      */
-    public <T> List<T> execute(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
+    public <T> T query(final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
         final Connection conn = this.prepareConnection();
 
-        return this.execute(conn, true, sql, rsh, params);
+        return this.<T>query(conn, true, sql, rsh, params);
     }
 
     /**
-     * Invokes the stored procedure via update after checking the parameters to
-     * ensure nothing is null.
+     * Set the value on all the {@link OutParameter} instances in the
+     * {@code params} array using the OUT parameter values from the
+     * {@code stmt}.
+     * @param stmt the statement from which to retrieve OUT parameter values
+     * @param params the parameter array for the statement invocation
+     * @throws SQLException when the value could not be retrieved from the
+     * statement.
+     */
+    private void retrieveOutParameters(final CallableStatement stmt, final Object[] params) throws SQLException {
+        if (params != null) {
+            for (int i = 0; i < params.length; i++) {
+                if (params[i] instanceof OutParameter) {
+                    ((OutParameter)params[i]).setValue(stmt, i + 1);
+                }
+            }
+        }
+    }
+
+    /**
+     * Calls update after checking the parameters to ensure nothing is null.
      * @param conn The connection to use for the update call.
      * @param closeConn True if the connection should be closed, false otherwise.
      * @param sql The SQL statement to execute.
@@ -884,7 +872,7 @@ public class QueryRunner extends AbstractQueryRunner {
      * @return The number of rows updated.
      * @throws SQLException If there are database or parameter errors.
      */
-    private int execute(final Connection conn, final boolean closeConn, final String sql, final Object... params) throws SQLException {
+    private int update(final Connection conn, final boolean closeConn, final String sql, final Object... params) throws SQLException {
         if (conn == null) {
             throw new SQLException("Null connection");
         }
@@ -896,15 +884,19 @@ public class QueryRunner extends AbstractQueryRunner {
             throw new SQLException("Null SQL statement");
         }
 
-        CallableStatement stmt = null;
+        Statement stmt = null;
         int rows = 0;
 
         try {
-            stmt = this.prepareCall(conn, sql);
-            this.fillStatement(stmt, params);
-            stmt.execute();
-            rows = stmt.getUpdateCount();
-            this.retrieveOutParameters(stmt, params);
+            if (params != null && params.length > 0) {
+                final PreparedStatement ps = this.prepareStatement(conn, sql);
+                stmt = ps;
+                this.fillStatement(ps, params);
+                rows = ps.executeUpdate();
+            } else {
+                stmt = conn.createStatement();
+                rows = stmt.executeUpdate(sql);
+            }
 
         } catch (final SQLException e) {
             this.rethrow(e, sql, params);
@@ -920,87 +912,95 @@ public class QueryRunner extends AbstractQueryRunner {
     }
 
     /**
-     * Invokes the stored procedure via update after checking the parameters to
-     * ensure nothing is null.
-     * @param conn The connection to use for the update call.
-     * @param closeConn True if the connection should be closed, false otherwise.
-     * @param sql The SQL statement to execute.
-     * @param rsh The result set handler
-     * @param params An array of update replacement parameters.  Each row in
-     * this array is one set of update replacement values.
-     * @return List of all objects generated by the ResultSetHandler for all result sets handled.
-     * @throws SQLException If there are database or parameter errors.
+     * Execute an SQL INSERT, UPDATE, or DELETE query without replacement
+     * parameters.
+     *
+     * @param conn The connection to use to run the query.
+     * @param sql The SQL to execute.
+     * @return The number of rows updated.
+     * @throws SQLException if a database access error occurs
      */
-    private <T> List<T> execute(final Connection conn, final boolean closeConn, final String sql, final ResultSetHandler<T> rsh, final Object... params) throws SQLException {
-        if (conn == null) {
-            throw new SQLException("Null connection");
-        }
-
-        if (sql == null) {
-            if (closeConn) {
-                close(conn);
-            }
-            throw new SQLException("Null SQL statement");
-        }
-
-        if (rsh == null) {
-            if (closeConn) {
-                close(conn);
-            }
-            throw new SQLException("Null ResultSetHandler");
-        }
+    public int update(final Connection conn, final String sql) throws SQLException {
+        return this.update(conn, false, sql, (Object[]) null);
+    }
 
-        CallableStatement stmt = null;
-        final List<T> results = new LinkedList<>();
+    /**
+     * Execute an SQL INSERT, UPDATE, or DELETE query with a single replacement
+     * parameter.
+     *
+     * @param conn The connection to use to run the query.
+     * @param sql The SQL to execute.
+     * @param param The replacement parameter.
+     * @return The number of rows updated.
+     * @throws SQLException if a database access error occurs
+     */
+    public int update(final Connection conn, final String sql, final Object param) throws SQLException {
+        return this.update(conn, false, sql, param);
+    }
 
-        try {
-            stmt = this.prepareCall(conn, sql);
-            this.fillStatement(stmt, params);
-            boolean moreResultSets = stmt.execute();
-            // Handle multiple result sets by passing them through the handler
-            // retaining the final result
-            ResultSet rs = null;
-            while (moreResultSets) {
-                try {
-                    rs = this.wrap(stmt.getResultSet());
-                    results.add(rsh.handle(rs));
-                    moreResultSets = stmt.getMoreResults();
+    /**
+     * Execute an SQL INSERT, UPDATE, or DELETE query.
+     *
+     * @param conn The connection to use to run the query.
+     * @param sql The SQL to execute.
+     * @param params The query replacement parameters.
+     * @return The number of rows updated.
+     * @throws SQLException if a database access error occurs
+     */
+    public int update(final Connection conn, final String sql, final Object... params) throws SQLException {
+        return update(conn, false, sql, params);
+    }
 
-                } finally {
-                    close(rs);
-                }
-            }
-            this.retrieveOutParameters(stmt, params);
+    /**
+     * Executes the given INSERT, UPDATE, or DELETE SQL statement without
+     * any replacement parameters. The {@code Connection} is retrieved
+     * from the {@code DataSource} set in the constructor.  This
+     * {@code Connection} must be in auto-commit mode or the update will
+     * not be saved.
+     *
+     * @param sql The SQL statement to execute.
+     * @throws SQLException if a database access error occurs
+     * @return The number of rows updated.
+     */
+    public int update(final String sql) throws SQLException {
+        final Connection conn = this.prepareConnection();
 
-        } catch (final SQLException e) {
-            this.rethrow(e, sql, params);
+        return this.update(conn, true, sql, (Object[]) null);
+    }
 
-        } finally {
-            close(stmt);
-            if (closeConn) {
-                close(conn);
-            }
-        }
+    /**
+     * Executes the given INSERT, UPDATE, or DELETE SQL statement with
+     * a single replacement parameter.  The {@code Connection} is
+     * retrieved from the {@code DataSource} set in the constructor.
+     * This {@code Connection} must be in auto-commit mode or the
+     * update will not be saved.
+     *
+     * @param sql The SQL statement to execute.
+     * @param param The replacement parameter.
+     * @throws SQLException if a database access error occurs
+     * @return The number of rows updated.
+     */
+    public int update(final String sql, final Object param) throws SQLException {
+        final Connection conn = this.prepareConnection();
 
-        return results;
+        return this.update(conn, true, sql, param);
     }
 
     /**
-     * Set the value on all the {@link OutParameter} instances in the
-     * {@code params} array using the OUT parameter values from the
-     * {@code stmt}.
-     * @param stmt the statement from which to retrieve OUT parameter values
-     * @param params the parameter array for the statement invocation
-     * @throws SQLException when the value could not be retrieved from the
-     * statement.
+     * Executes the given INSERT, UPDATE, or DELETE SQL statement.  The
+     * {@code Connection} is retrieved from the {@code DataSource}
+     * set in the constructor.  This {@code Connection} must be in
+     * auto-commit mode or the update will not be saved.
+     *
+     * @param sql The SQL statement to execute.
+     * @param params Initializes the PreparedStatement's IN (i.e. '?')
+     * parameters.
+     * @throws SQLException if a database access error occurs
+     * @return The number of rows updated.
      */
-    private void retrieveOutParameters(final CallableStatement stmt, final Object[] params) throws SQLException {
-        if (params != null) {
-            for (int i = 0; i < params.length; i++) {
-                if (params[i] instanceof OutParameter) {
-                    ((OutParameter)params[i]).setValue(stmt, i + 1);
-                }
-            }
-        }
+    public int update(final String sql, final Object... params) throws SQLException {
+        final Connection conn = this.prepareConnection();
+
+        return this.update(conn, true, sql, params);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/ResultSetIterator.java b/src/main/java/org/apache/commons/dbutils/ResultSetIterator.java
index 6f5a83c..71382d3 100644
--- a/src/main/java/org/apache/commons/dbutils/ResultSetIterator.java
+++ b/src/main/java/org/apache/commons/dbutils/ResultSetIterator.java
@@ -34,6 +34,23 @@ import java.util.Iterator;
  */
 public class ResultSetIterator implements Iterator<Object[]> {
 
+    /**
+     * Generates an {@code Iterable}, suitable for use in for-each loops.
+     *
+     * @param rs Wrap this {@code ResultSet} in an {@code Iterator}.
+     * @return an {@code Iterable}, suitable for use in for-each loops.
+     */
+    public static Iterable<Object[]> iterable(final ResultSet rs) {
+        return new Iterable<Object[]>() {
+
+            @Override
+            public Iterator<Object[]> iterator() {
+                return new ResultSetIterator(rs);
+            }
+
+        };
+    }
+
     /**
      * The wrapped {@code ResultSet}.
      */
@@ -121,21 +138,4 @@ public class ResultSetIterator implements Iterator<Object[]> {
         throw new RuntimeException(e.getMessage());
     }
 
-    /**
-     * Generates an {@code Iterable}, suitable for use in for-each loops.
-     *
-     * @param rs Wrap this {@code ResultSet} in an {@code Iterator}.
-     * @return an {@code Iterable}, suitable for use in for-each loops.
-     */
-    public static Iterable<Object[]> iterable(final ResultSet rs) {
-        return new Iterable<Object[]>() {
-
-            @Override
-            public Iterator<Object[]> iterator() {
-                return new ResultSetIterator(rs);
-            }
-
-        };
-    }
-
 }
diff --git a/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java b/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java
index cd6cb5d..f1d9376 100644
--- a/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java
+++ b/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java
@@ -20,10 +20,78 @@ package org.apache.commons.dbutils;
  * Configuration options for a {@link java.sql.Statement} when preparing statements in {@code QueryRunner}.
  */
 public class StatementConfiguration {
+    /**
+     * Builder class for {@code StatementConfiguration} for more flexible construction.
+     */
+    public static final class Builder {
+        private Integer fetchDirection;
+        private Integer fetchSize;
+        private Integer maxRows;
+        private Integer queryTimeout;
+        private Integer maxFieldSize;
+
+        /**
+         * @return A new and configured {@link StatementConfiguration}.
+         */
+        public StatementConfiguration build() {
+            return new StatementConfiguration(fetchDirection, fetchSize, maxFieldSize, maxRows, queryTimeout);
+        }
+
+        /**
+         * @param fetchDirection The direction for fetching rows from database tables.
+         * @return This builder for chaining.
+         * @see StatementConfiguration#getFetchDirection()
+         */
+        public Builder fetchDirection(final Integer fetchDirection) {
+            this.fetchDirection = fetchDirection;
+            return this;
+        }
+
+        /**
+         * @param fetchSize The number of rows that should be fetched from the database when more rows are needed.
+         * @return This builder for chaining.
+         * @see StatementConfiguration#getFetchSize()
+         */
+        public Builder fetchSize(final Integer fetchSize) {
+            this.fetchSize = fetchSize;
+            return this;
+        }
+
+        /**
+         * @param maxFieldSize The maximum number of bytes that can be returned for character and binary column values.
+         * @return This builder for chaining.
+         * @see StatementConfiguration#getMaxFieldSize()
+         */
+        public Builder maxFieldSize(final Integer maxFieldSize) {
+            this.maxFieldSize = maxFieldSize;
+            return this;
+        }
+
+        /**
+         * @param maxRows The maximum number of rows that a {@code ResultSet} can produce.
+         * @return This builder for chaining.
+         * @see StatementConfiguration#getMaxRows()
+         */
+        public Builder maxRows(final Integer maxRows) {
+            this.maxRows = maxRows;
+            return this;
+        }
+
+        /**
+         * @param queryTimeout The number of seconds the driver will wait for execution.
+         * @return This builder for chaining.
+         * @see StatementConfiguration#getQueryTimeout()
+         */
+        public Builder queryTimeout(final Integer queryTimeout) {
+            this.queryTimeout = queryTimeout;
+            return this;
+        }
+    }
     private final Integer fetchDirection;
     private final Integer fetchSize;
     private final Integer maxFieldSize;
     private final Integer maxRows;
+
     private final Integer queryTimeout;
 
     /**
@@ -55,75 +123,75 @@ public class StatementConfiguration {
     }
 
     /**
-     * Whether fetch direction is set.
+     * Get the fetch size.
      *
-     * @return true if set, false otherwise.
+     * @return The fetch size or null if not set.
      */
-    public boolean isFetchDirectionSet() {
-        return fetchDirection != null;
+    public Integer getFetchSize() {
+        return fetchSize;
     }
 
     /**
-     * Get the fetch size.
+     * Get the max field size.
      *
-     * @return The fetch size or null if not set.
+     * @return The max field size or null if not set.
      */
-    public Integer getFetchSize() {
-        return fetchSize;
+    public Integer getMaxFieldSize() {
+        return maxFieldSize;
     }
 
     /**
-     * Whether fetch size is set.
+     * Get the max rows.
      *
-     * @return true if set, false otherwise.
+     * @return The max rows or null if not set.
      */
-    public boolean isFetchSizeSet() {
-        return fetchSize != null;
+    public Integer getMaxRows() {
+        return maxRows;
     }
 
     /**
-     * Get the max field size.
+     * Get the query timeout.
      *
-     * @return The max field size or null if not set.
+     * @return The query timeout or null if not set.
      */
-    public Integer getMaxFieldSize() {
-        return maxFieldSize;
+    public Integer getQueryTimeout() {
+        return queryTimeout;
     }
 
     /**
-     * Whether max field size is set.
+     * Whether fetch direction is set.
      *
      * @return true if set, false otherwise.
      */
-    public boolean isMaxFieldSizeSet() {
-        return maxFieldSize != null;
+    public boolean isFetchDirectionSet() {
+        return fetchDirection != null;
     }
 
     /**
-     * Get the max rows.
+     * Whether fetch size is set.
      *
-     * @return The max rows or null if not set.
+     * @return true if set, false otherwise.
      */
-    public Integer getMaxRows() {
-        return maxRows;
+    public boolean isFetchSizeSet() {
+        return fetchSize != null;
     }
 
     /**
-     * Whether max rows is set.
+     * Whether max field size is set.
      *
      * @return true if set, false otherwise.
      */
-    public boolean isMaxRowsSet() {
-        return maxRows != null;
+    public boolean isMaxFieldSizeSet() {
+        return maxFieldSize != null;
     }
 
     /**
-     * Get the query timeout.
+     * Whether max rows is set.
      *
-     * @return The query timeout or null if not set.
+     * @return true if set, false otherwise.
      */
-    public Integer getQueryTimeout() {
-        return queryTimeout;
+    public boolean isMaxRowsSet() {
+        return maxRows != null;
     }
 
     /**
@@ -134,72 +202,4 @@ public class StatementConfiguration {
     public boolean isQueryTimeoutSet() {
         return queryTimeout != null;
     }
-
-    /**
-     * Builder class for {@code StatementConfiguration} for more flexible construction.
-     */
-    public static final class Builder {
-        private Integer fetchDirection;
-        private Integer fetchSize;
-        private Integer maxRows;
-        private Integer queryTimeout;
-        private Integer maxFieldSize;
-
-        /**
-         * @param fetchDirection The direction for fetching rows from database tables.
-         * @return This builder for chaining.
-         * @see StatementConfiguration#getFetchDirection()
-         */
-        public Builder fetchDirection(final Integer fetchDirection) {
-            this.fetchDirection = fetchDirection;
-            return this;
-        }
-
-        /**
-         * @param fetchSize The number of rows that should be fetched from the database when more rows are needed.
-         * @return This builder for chaining.
-         * @see StatementConfiguration#getFetchSize()
-         */
-        public Builder fetchSize(final Integer fetchSize) {
-            this.fetchSize = fetchSize;
-            return this;
-        }
-
-        /**
-         * @param maxRows The maximum number of rows that a {@code ResultSet} can produce.
-         * @return This builder for chaining.
-         * @see StatementConfiguration#getMaxRows()
-         */
-        public Builder maxRows(final Integer maxRows) {
-            this.maxRows = maxRows;
-            return this;
-        }
-
-        /**
-         * @param queryTimeout The number of seconds the driver will wait for execution.
-         * @return This builder for chaining.
-         * @see StatementConfiguration#getQueryTimeout()
-         */
-        public Builder queryTimeout(final Integer queryTimeout) {
-            this.queryTimeout = queryTimeout;
-            return this;
-        }
-
-        /**
-         * @param maxFieldSize The maximum number of bytes that can be returned for character and binary column values.
-         * @return This builder for chaining.
-         * @see StatementConfiguration#getMaxFieldSize()
-         */
-        public Builder maxFieldSize(final Integer maxFieldSize) {
-            this.maxFieldSize = maxFieldSize;
-            return this;
-        }
-
-        /**
-         * @return A new and configured {@link StatementConfiguration}.
-         */
-        public StatementConfiguration build() {
-            return new StatementConfiguration(fetchDirection, fetchSize, maxFieldSize, maxRows, queryTimeout);
-        }
-    }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/AbstractKeyedHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/AbstractKeyedHandler.java
index e2a692d..48941fb 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/AbstractKeyedHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/AbstractKeyedHandler.java
@@ -39,21 +39,13 @@ public abstract class AbstractKeyedHandler<K, V> implements ResultSetHandler<Map
 
 
     /**
-     * Convert each row's columns into a Map and store then
-     * in a {@code Map} under {@code ResultSet.getObject(key)} key.
-     * @param rs {@code ResultSet} to process.
-     * @return A {@code Map}, never {@code null}.
+     * This factory method is called by {@code handle()} to retrieve the
+     * key value from the current {@code ResultSet} row.
+     * @param rs ResultSet to create a key from
+     * @return K from the configured key column name/index
      * @throws SQLException if a database access error occurs
-     * @see org.apache.commons.dbutils.ResultSetHandler#handle(java.sql.ResultSet)
      */
-    @Override
-    public Map<K, V> handle(final ResultSet rs) throws SQLException {
-        final Map<K, V> result = createMap();
-        while (rs.next()) {
-            result.put(createKey(rs), createRow(rs));
-        }
-        return result;
-    }
+    protected abstract K createKey(ResultSet rs) throws SQLException;
 
     /**
      * This factory method is called by {@code handle()} to create the Map
@@ -66,15 +58,6 @@ public abstract class AbstractKeyedHandler<K, V> implements ResultSetHandler<Map
         return new HashMap<>();
     }
 
-    /**
-     * This factory method is called by {@code handle()} to retrieve the
-     * key value from the current {@code ResultSet} row.
-     * @param rs ResultSet to create a key from
-     * @return K from the configured key column name/index
-     * @throws SQLException if a database access error occurs
-     */
-    protected abstract K createKey(ResultSet rs) throws SQLException;
-
     /**
      * This factory method is called by {@code handle()} to store the
      * current {@code ResultSet} row in some object.
@@ -84,4 +67,21 @@ public abstract class AbstractKeyedHandler<K, V> implements ResultSetHandler<Map
      */
     protected abstract V createRow(ResultSet rs) throws SQLException;
 
+    /**
+     * Convert each row's columns into a Map and store then
+     * in a {@code Map} under {@code ResultSet.getObject(key)} key.
+     * @param rs {@code ResultSet} to process.
+     * @return A {@code Map}, never {@code null}.
+     * @throws SQLException if a database access error occurs
+     * @see org.apache.commons.dbutils.ResultSetHandler#handle(java.sql.ResultSet)
+     */
+    @Override
+    public Map<K, V> handle(final ResultSet rs) throws SQLException {
+        final Map<K, V> result = createMap();
+        while (rs.next()) {
+            result.put(createKey(rs), createRow(rs));
+        }
+        return result;
+    }
+
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java
index 420300e..ef583ab 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java
@@ -90,21 +90,6 @@ public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> {
         this(type, ArrayHandler.ROW_PROCESSOR, 1, null);
     }
 
-    /**
-     * Creates a new instance of BeanMapHandler. The value of the first column
-     * of each row will be a key in the Map.
-     *
-     * @param type
-     *            The Class that objects returned from {@code createRow()}
-     *            are created from.
-     * @param convert
-     *            The {@code RowProcessor} implementation to use when
-     *            converting rows into Beans
-     */
-    public BeanMapHandler(final Class<V> type, final RowProcessor convert) {
-        this(type, convert, 1, null);
-    }
-
     /**
      * Creates a new instance of BeanMapHandler.
      *
@@ -120,17 +105,18 @@ public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> {
     }
 
     /**
-     * Creates a new instance of BeanMapHandler.
+     * Creates a new instance of BeanMapHandler. The value of the first column
+     * of each row will be a key in the Map.
      *
      * @param type
      *            The Class that objects returned from {@code createRow()}
      *            are created from.
-     * @param columnName
-     *            The values to use as keys in the Map are retrieved from the
-     *            column with this name.
+     * @param convert
+     *            The {@code RowProcessor} implementation to use when
+     *            converting rows into Beans
      */
-    public BeanMapHandler(final Class<V> type, final String columnName) {
-        this(type, ArrayHandler.ROW_PROCESSOR, 1, columnName);
+    public BeanMapHandler(final Class<V> type, final RowProcessor convert) {
+        this(type, convert, 1, null);
     }
 
     /**
@@ -154,6 +140,20 @@ public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> {
         this.columnName = columnName;
     }
 
+    /**
+     * Creates a new instance of BeanMapHandler.
+     *
+     * @param type
+     *            The Class that objects returned from {@code createRow()}
+     *            are created from.
+     * @param columnName
+     *            The values to use as keys in the Map are retrieved from the
+     *            column with this name.
+     */
+    public BeanMapHandler(final Class<V> type, final String columnName) {
+        this(type, ArrayHandler.ROW_PROCESSOR, 1, columnName);
+    }
+
     /**
      * This factory method is called by {@code handle()} to retrieve the
      * key value from the current {@code ResultSet} row.
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/ColumnListHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/ColumnListHandler.java
index 00b025e..b52aebd 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/ColumnListHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/ColumnListHandler.java
@@ -59,16 +59,6 @@ public class ColumnListHandler<T> extends AbstractListHandler<T> {
         this(columnIndex, null);
     }
 
-    /**
-     * Creates a new instance of ColumnListHandler.
-     *
-     * @param columnName The name of the column to retrieve from the
-     * {@code ResultSet}.
-     */
-    public ColumnListHandler(final String columnName) {
-        this(1, columnName);
-    }
-
     /** Private Helper
      * @param columnIndex The index of the column to retrieve from the
      * {@code ResultSet}.
@@ -80,6 +70,16 @@ public class ColumnListHandler<T> extends AbstractListHandler<T> {
         this.columnName = columnName;
     }
 
+    /**
+     * Creates a new instance of ColumnListHandler.
+     *
+     * @param columnName The name of the column to retrieve from the
+     * {@code ResultSet}.
+     */
+    public ColumnListHandler(final String columnName) {
+        this(1, columnName);
+    }
+
     /**
      * Returns one {@code ResultSet} column value as {@code Object}.
      * @param rs {@code ResultSet} to process.
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/KeyedHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/KeyedHandler.java
index 829f053..975eb10 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/KeyedHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/KeyedHandler.java
@@ -76,17 +76,6 @@ public class KeyedHandler<K> extends AbstractKeyedHandler<K, Map<String, Object>
         this(ArrayHandler.ROW_PROCESSOR, 1, null);
     }
 
-    /**
-     * Creates a new instance of KeyedHandler.  The value of the first column
-     * of each row will be a key in the Map.
-     *
-     * @param convert The {@code RowProcessor} implementation
-     * to use when converting rows into Maps
-     */
-    public KeyedHandler(final RowProcessor convert) {
-        this(convert, 1, null);
-    }
-
     /**
      * Creates a new instance of KeyedHandler.
      *
@@ -98,13 +87,14 @@ public class KeyedHandler<K> extends AbstractKeyedHandler<K, Map<String, Object>
     }
 
     /**
-     * Creates a new instance of KeyedHandler.
+     * Creates a new instance of KeyedHandler.  The value of the first column
+     * of each row will be a key in the Map.
      *
-     * @param columnName The values to use as keys in the Map are
-     * retrieved from the column with this name.
+     * @param convert The {@code RowProcessor} implementation
+     * to use when converting rows into Maps
      */
-    public KeyedHandler(final String columnName) {
-        this(ArrayHandler.ROW_PROCESSOR, 1, columnName);
+    public KeyedHandler(final RowProcessor convert) {
+        this(convert, 1, null);
     }
 
     /** Private Helper
@@ -121,6 +111,16 @@ public class KeyedHandler<K> extends AbstractKeyedHandler<K, Map<String, Object>
         this.columnIndex = columnIndex;
         this.columnName = columnName;
     }
+
+    /**
+     * Creates a new instance of KeyedHandler.
+     *
+     * @param columnName The values to use as keys in the Map are
+     * retrieved from the column with this name.
+     */
+    public KeyedHandler(final String columnName) {
+        this(ArrayHandler.ROW_PROCESSOR, 1, columnName);
+    }
     /**
      * This factory method is called by {@code handle()} to retrieve the
      * key value from the current {@code ResultSet} row.  This
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/ScalarHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/ScalarHandler.java
index fdb30b3..dfa180b 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/ScalarHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/ScalarHandler.java
@@ -59,16 +59,6 @@ public class ScalarHandler<T> implements ResultSetHandler<T> {
         this(columnIndex, null);
     }
 
-    /**
-     * Creates a new instance of ScalarHandler.
-     *
-     * @param columnName The name of the column to retrieve from the
-     * {@code ResultSet}.
-     */
-    public ScalarHandler(final String columnName) {
-        this(1, columnName);
-    }
-
     /** Helper constructor
      * @param columnIndex The index of the column to retrieve from the
      * {@code ResultSet}.
@@ -80,6 +70,16 @@ public class ScalarHandler<T> implements ResultSetHandler<T> {
         this.columnName = columnName;
     }
 
+    /**
+     * Creates a new instance of ScalarHandler.
+     *
+     * @param columnName The name of the column to retrieve from the
+     * {@code ResultSet}.
+     */
+    public ScalarHandler(final String columnName) {
+        this(1, columnName);
+    }
+
     /**
      * Returns one {@code ResultSet} column as an object via the
      * {@code ResultSet.getObject()} method that performs type
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/BooleanColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/BooleanColumnHandler.java
index d0a77fb..afbdcdb 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/BooleanColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/BooleanColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class BooleanColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Boolean.TYPE) || propType.equals(Boolean.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return Boolean.valueOf(rs.getBoolean(columnIndex));
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return Boolean.valueOf(rs.getBoolean(columnIndex));
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Boolean.TYPE) || propType.equals(Boolean.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/ByteColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/ByteColumnHandler.java
index 2df55df..c2c76bd 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/ByteColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/ByteColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class ByteColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Byte.TYPE) || propType.equals(Byte.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return Byte.valueOf(rs.getByte(columnIndex));
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return Byte.valueOf(rs.getByte(columnIndex));
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Byte.TYPE) || propType.equals(Byte.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/DoubleColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/DoubleColumnHandler.java
index 3cedb26..c62512b 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/DoubleColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/DoubleColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class DoubleColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Double.TYPE) || propType.equals(Double.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return Double.valueOf(rs.getDouble(columnIndex));
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return Double.valueOf(rs.getDouble(columnIndex));
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Double.TYPE) || propType.equals(Double.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/FloatColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/FloatColumnHandler.java
index b50045f..6b37d9d 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/FloatColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/FloatColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class FloatColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Float.TYPE) || propType.equals(Float.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return Float.valueOf(rs.getFloat(columnIndex));
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return Float.valueOf(rs.getFloat(columnIndex));
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Float.TYPE) || propType.equals(Float.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandler.java
index a803cff..edc88a4 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class IntegerColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Integer.TYPE) || propType.equals(Integer.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return Integer.valueOf(rs.getInt(columnIndex));
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return Integer.valueOf(rs.getInt(columnIndex));
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Integer.TYPE) || propType.equals(Integer.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/LongColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/LongColumnHandler.java
index 0cbaeb1..ea0cc9c 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/LongColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/LongColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class LongColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Long.TYPE) || propType.equals(Long.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return Long.valueOf(rs.getLong(columnIndex));
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return Long.valueOf(rs.getLong(columnIndex));
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Long.TYPE) || propType.equals(Long.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/SQLXMLColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/SQLXMLColumnHandler.java
index d02a14d..2ed2291 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/SQLXMLColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/SQLXMLColumnHandler.java
@@ -24,12 +24,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class SQLXMLColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(SQLXML.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return rs.getSQLXML(columnIndex);
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return rs.getSQLXML(columnIndex);
+    public boolean match(final Class<?> propType) {
+        return propType.equals(SQLXML.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/ShortColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/ShortColumnHandler.java
index 27aecf8..d7fb3df 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/ShortColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/ShortColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class ShortColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Short.TYPE) || propType.equals(Short.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return Short.valueOf(rs.getShort(columnIndex));
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return Short.valueOf(rs.getShort(columnIndex));
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Short.TYPE) || propType.equals(Short.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/StringColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/StringColumnHandler.java
index dc68fe6..85fc5c4 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/StringColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/StringColumnHandler.java
@@ -23,12 +23,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class StringColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(String.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return rs.getString(columnIndex);
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return rs.getString(columnIndex);
+    public boolean match(final Class<?> propType) {
+        return propType.equals(String.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/columns/TimestampColumnHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/columns/TimestampColumnHandler.java
index 1d505e3..d82517f 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/columns/TimestampColumnHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/columns/TimestampColumnHandler.java
@@ -24,12 +24,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 
 public class TimestampColumnHandler implements ColumnHandler {
     @Override
-    public boolean match(final Class<?> propType) {
-        return propType.equals(Timestamp.class);
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return rs.getTimestamp(columnIndex);
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return rs.getTimestamp(columnIndex);
+    public boolean match(final Class<?> propType) {
+        return propType.equals(Timestamp.class);
     }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandler.java
index c1ef96b..98b7a5d 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandler.java
@@ -26,25 +26,6 @@ import org.apache.commons.dbutils.PropertyHandler;
  * {@link java.sql.Timestamp} from SQL types to java types.
  */
 public class DatePropertyHandler implements PropertyHandler {
-    @Override
-    public boolean match(final Class<?> parameter, final Object value) {
-        if (value instanceof Date) {
-            final String targetType = parameter.getName();
-            if ("java.sql.Date".equals(targetType)) {
-                return true;
-            }
-            if ("java.sql.Time".equals(targetType)) {
-                return true;
-            }
-            if ("java.sql.Timestamp".equals(targetType)
-                    && !Timestamp.class.isInstance(value)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
     @Override
     public Object apply(final Class<?> parameter, Object value) {
         final String targetType = parameter.getName();
@@ -63,4 +44,23 @@ public class DatePropertyHandler implements PropertyHandler {
 
         return value;
     }
+
+    @Override
+    public boolean match(final Class<?> parameter, final Object value) {
+        if (value instanceof Date) {
+            final String targetType = parameter.getName();
+            if ("java.sql.Date".equals(targetType)) {
+                return true;
+            }
+            if ("java.sql.Time".equals(targetType)) {
+                return true;
+            }
+            if ("java.sql.Timestamp".equals(targetType)
+                    && !Timestamp.class.isInstance(value)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
 }
diff --git a/src/main/java/org/apache/commons/dbutils/handlers/properties/StringEnumPropertyHandler.java b/src/main/java/org/apache/commons/dbutils/handlers/properties/StringEnumPropertyHandler.java
index bd0eae9..0fbbcbc 100644
--- a/src/main/java/org/apache/commons/dbutils/handlers/properties/StringEnumPropertyHandler.java
+++ b/src/main/java/org/apache/commons/dbutils/handlers/properties/StringEnumPropertyHandler.java
@@ -22,14 +22,14 @@ import org.apache.commons.dbutils.PropertyHandler;
  * {@link PropertyHandler} for enums. Will convert strings to enums.
  */
 public class StringEnumPropertyHandler implements PropertyHandler {
-    @Override
-    public boolean match(final Class<?> parameter, final Object value) {
-        return value instanceof String && parameter.isEnum();
-    }
-
     @Override
     @SuppressWarnings("unchecked")
     public Object apply(final Class<?> parameter, final Object value) {
         return Enum.valueOf(parameter.asSubclass(Enum.class), (String) value);
     }
+
+    @Override
+    public boolean match(final Class<?> parameter, final Object value) {
+        return value instanceof String && parameter.isEnum();
+    }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java b/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java
index 2fc891c..dcb5632 100644
--- a/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/AsyncQueryRunnerTest.java
@@ -57,21 +57,27 @@ public class AsyncQueryRunnerTest {
     @Mock ParameterMetaData meta;
     @Mock ResultSet results;
 
-    @Before
-    public void setUp() throws Exception {
-        when(dataSource.getConnection()).thenReturn(conn);
+    // helper method for calling batch when an exception is expected
+    private void callBatchWithException(final String sql, final Object[][] params) throws Exception {
+        Future<int[]> future = null;
+        boolean caught = false;
 
-        when(conn.prepareStatement(any(String.class))).thenReturn(prepStmt);
-        when(prepStmt.getParameterMetaData()).thenReturn(meta);
-        when(prepStmt.executeQuery()).thenReturn(results);
+        try {
+            future = runner.batch(sql, params);
 
-        when(conn.createStatement()).thenReturn(stmt);
-        when(stmt.executeQuery(any(String.class))).thenReturn(results);
+            future.get();
 
-        when(results.next()).thenReturn(false);
+            verify(prepStmt, times(2)).addBatch();
+            verify(prepStmt, times(1)).executeBatch();
+            verify(prepStmt, times(1)).close();    // make sure the statement is closed
+            verify(conn, times(1)).close();    // make sure the connection is closed
+        } catch (final Exception e) {
+            caught = true;
+        }
 
-         handler = new ArrayHandler();
-         runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1), new QueryRunner(dataSource));
+        if(!caught) {
+            fail("Exception never thrown, but expected");
+        }
     }
 
     //
@@ -101,112 +107,26 @@ public class AsyncQueryRunnerTest {
         verify(conn, times(1)).close();    // make sure we closed the connection
     }
 
-    @Test
-    public void testGoodBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
-
-        callGoodBatch(params);
-    }
-
-    @SuppressWarnings("deprecation") // deliberate test of deprecated code
-    @Test
-    public void testGoodBatchPmdTrue() throws Exception {
-        runner = new AsyncQueryRunner(dataSource, true, Executors.newFixedThreadPool(1));
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
-
-        callGoodBatch(params);
-    }
-
-    @Test
-    public void testGoodBatchDefaultConstructor() throws Exception {
-        runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
-
-        callGoodBatch(conn, params);
-    }
-
-    @Test
-    public void testNullParamsBatch() throws Exception {
-        final String[][] params = new String[][] { { null, "unit" }, { "test", null } };
-
-        callGoodBatch(params);
-    }
-
-
-
-    // helper method for calling batch when an exception is expected
-    private void callBatchWithException(final String sql, final Object[][] params) throws Exception {
-        Future<int[]> future = null;
-        boolean caught = false;
-
-        try {
-            future = runner.batch(sql, params);
-
-            future.get();
-
-            verify(prepStmt, times(2)).addBatch();
-            verify(prepStmt, times(1)).executeBatch();
-            verify(prepStmt, times(1)).close();    // make sure the statement is closed
-            verify(conn, times(1)).close();    // make sure the connection is closed
-        } catch (final Exception e) {
-            caught = true;
-        }
-
-        if(!caught) {
-            fail("Exception never thrown, but expected");
-        }
-    }
-
-    @Test
-    public void testTooFewParamsBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit" }, { "test" } };
-
-        callBatchWithException("select * from blah where ? = ?", params);
-    }
-
-    @Test
-    public void testTooManyParamsBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit", "unit" }, { "test", "test", "test" } };
-
-        callBatchWithException("select * from blah where ? = ?", params);
-    }
-
-    @Test(expected=ExecutionException.class)
-    public void testNullConnectionBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
-
-        when(dataSource.getConnection()).thenReturn(null);
-
-        runner.batch("select * from blah where ? = ?", params).get();
-    }
-
-    @Test(expected=ExecutionException.class)
-    public void testNullSqlBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
-
-        runner.batch(null, params).get();
-    }
-
-    @Test(expected=ExecutionException.class)
-    public void testNullParamsArgBatch() throws Exception {
-        runner.batch("select * from blah where ? = ?", null).get();
-    }
-
-    @Test
-    public void testAddBatchException() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+    private void callGoodQuery() throws Exception {
+        when(meta.getParameterCount()).thenReturn(2);
+        String sql = "select * from blah where ? = ?";
+        runner.query(sql, handler, "unit", "test").get();
 
-        callBatchWithException("select * from blah where ? = ?", params);
-    }
+        verify(prepStmt, times(1)).executeQuery();
+        verify(results, times(1)).close();
+        verify(prepStmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(1)).close();    // make sure we closed the connection
 
-    @Test
-    public void testExecuteBatchException() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+        // call the other variation of query
+        sql = "select * from blah";
+        runner.query(sql, handler).get();
 
-        callBatchWithException("select * from blah where ? = ?", params);
+        verify(stmt, times(1)).executeQuery(sql);
+        verify(results, times(2)).close();
+        verify(stmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(2)).close();    // make sure we closed the connection
     }
 
-
     //
     // Query test cases
     //
@@ -230,45 +150,66 @@ public class AsyncQueryRunnerTest {
         verify(conn, times(0)).close();    // make sure we closed the connection
     }
 
-    private void callGoodQuery() throws Exception {
+    private void callGoodUpdate() throws Exception {
         when(meta.getParameterCount()).thenReturn(2);
-        String sql = "select * from blah where ? = ?";
-        runner.query(sql, handler, "unit", "test").get();
+        String sql = "update blah set ? = ?";
+        runner.update(sql, "unit", "test").get();
 
-        verify(prepStmt, times(1)).executeQuery();
-        verify(results, times(1)).close();
+        verify(prepStmt, times(1)).executeUpdate();
         verify(prepStmt, times(1)).close();    // make sure we closed the statement
         verify(conn, times(1)).close();    // make sure we closed the connection
 
-        // call the other variation of query
-        sql = "select * from blah";
-        runner.query(sql, handler).get();
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(0);
+        sql = "update blah set unit = test";
+        runner.update(sql).get();
 
-        verify(stmt, times(1)).executeQuery(sql);
-        verify(results, times(2)).close();
+        verify(stmt, times(1)).executeUpdate(sql);
         verify(stmt, times(1)).close();    // make sure we closed the statement
         verify(conn, times(2)).close();    // make sure we closed the connection
-    }
 
-    @Test
-    public void testGoodQuery() throws Exception {
-        callGoodQuery();
-    }
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(1);
+        runner.update("update blah set unit = ?", "test").get();
 
-    @SuppressWarnings("deprecation") // deliberate test of deprecated code
-    @Test
-    public void testGoodQueryPmdTrue() throws Exception {
-        runner = new AsyncQueryRunner(true, Executors.newFixedThreadPool(1));
-        callGoodQuery(conn);
+        verify(prepStmt, times(2)).executeUpdate();
+        verify(prepStmt, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(3)).close();    // make sure we closed the connection
     }
 
-    @Test
-    public void testGoodQueryDefaultConstructor() throws Exception {
-        runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
-        callGoodQuery(conn);
+    //
+    // Update test cases
+    //
+    private void callGoodUpdate(final Connection conn) throws Exception {
+        when(meta.getParameterCount()).thenReturn(2);
+        String sql = "update blah set ? = ?";
+        runner.update(conn, sql, "unit", "test").get();
+
+        verify(prepStmt, times(1)).executeUpdate();
+        verify(prepStmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we closed the connection
+
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(0);
+        sql = "update blah set unit = test";
+        runner.update(conn, sql).get();
+
+        verify(stmt, times(1)).executeUpdate(sql);
+        verify(stmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we closed the connection
+
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(1);
+        sql = "update blah set unit = ?";
+        runner.update(conn, sql, "test").get();
+
+        verify(prepStmt, times(2)).executeUpdate();
+        verify(prepStmt, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we closed the connection
     }
 
 
+
     // helper method for calling batch when an exception is expected
     private void callQueryWithException(final Object... params) throws Exception {
         boolean caught = false;
@@ -290,153 +231,138 @@ public class AsyncQueryRunnerTest {
         }
     }
 
-    @Test
-    public void testNoParamsQuery() throws Exception {
-        callGoodQuery();
-    }
+    // helper method for calling batch when an exception is expected
+    private void callUpdateWithException(final Object... params) throws Exception {
+        boolean caught = false;
 
-    @Test
-    public void testTooFewParamsQuery() throws Exception {
-        callQueryWithException("unit");
-    }
+        try {
+            when(meta.getParameterCount()).thenReturn(2);
+            runner.update("select * from blah where ? = ?", params).get();
 
-    @Test
-    public void testTooManyParamsQuery() throws Exception {
-        callQueryWithException("unit", "test", "fail");
+            verify(prepStmt, times(1)).executeUpdate();
+            verify(prepStmt, times(1)).close();    // make sure we closed the statement
+            verify(conn, times(1)).close();    // make sure we closed the connection
+        } catch (final Exception e) {
+            caught = true;
+        }
+
+        if(!caught) {
+            fail("Exception never thrown, but expected");
+        }
     }
 
-    @Test(expected=ExecutionException.class)
-    public void testNullConnectionQuery() throws Exception {
-        when(dataSource.getConnection()).thenReturn(null);
+    @Before
+    public void setUp() throws Exception {
+        when(dataSource.getConnection()).thenReturn(conn);
 
-        runner.query("select * from blah where ? = ?", handler, "unit", "test").get();
-    }
+        when(conn.prepareStatement(any(String.class))).thenReturn(prepStmt);
+        when(prepStmt.getParameterMetaData()).thenReturn(meta);
+        when(prepStmt.executeQuery()).thenReturn(results);
 
-    @Test(expected=ExecutionException.class)
-    public void testNullSqlQuery() throws Exception {
-        runner.query(null, handler).get();
-    }
+        when(conn.createStatement()).thenReturn(stmt);
+        when(stmt.executeQuery(any(String.class))).thenReturn(results);
 
-    @Test(expected=ExecutionException.class)
-    public void testNullHandlerQuery() throws Exception {
-        runner.query("select * from blah where ? = ?", null).get();
+        when(results.next()).thenReturn(false);
+
+         handler = new ArrayHandler();
+         runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1), new QueryRunner(dataSource));
     }
 
     @Test
-    public void testExecuteQueryException() throws Exception {
-        callQueryWithException(handler, "unit", "test");
-    }
+    public void testAddBatchException() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
+        callBatchWithException("select * from blah where ? = ?", params);
+    }
 
     //
-    // Update test cases
+    // Random tests
     //
-    private void callGoodUpdate(final Connection conn) throws Exception {
-        when(meta.getParameterCount()).thenReturn(2);
-        String sql = "update blah set ? = ?";
-        runner.update(conn, sql, "unit", "test").get();
+    @Test(expected=ExecutionException.class)
+    public void testBadPrepareConnection() throws Exception {
+        runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
+        runner.update("update blah set unit = test").get();
+    }
 
-        verify(prepStmt, times(1)).executeUpdate();
-        verify(prepStmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we closed the connection
+    @Test
+    public void testExecuteBatchException() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        // call the other variation
-        when(meta.getParameterCount()).thenReturn(0);
-        sql = "update blah set unit = test";
-        runner.update(conn, sql).get();
+        callBatchWithException("select * from blah where ? = ?", params);
+    }
 
-        verify(stmt, times(1)).executeUpdate(sql);
-        verify(stmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we closed the connection
+    @Test
+    public void testExecuteQueryException() throws Exception {
+        callQueryWithException(handler, "unit", "test");
+    }
 
-        // call the other variation
-        when(meta.getParameterCount()).thenReturn(1);
-        sql = "update blah set unit = ?";
-        runner.update(conn, sql, "test").get();
+    @Test
+    public void testExecuteUpdateException() throws Exception {
+        doThrow(new SQLException()).when(prepStmt).executeUpdate();
 
-        verify(prepStmt, times(2)).executeUpdate();
-        verify(prepStmt, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we closed the connection
+        callUpdateWithException("unit", "test");
     }
 
-    private void callGoodUpdate() throws Exception {
-        when(meta.getParameterCount()).thenReturn(2);
-        String sql = "update blah set ? = ?";
-        runner.update(sql, "unit", "test").get();
-
-        verify(prepStmt, times(1)).executeUpdate();
-        verify(prepStmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(1)).close();    // make sure we closed the connection
 
-        // call the other variation
-        when(meta.getParameterCount()).thenReturn(0);
-        sql = "update blah set unit = test";
-        runner.update(sql).get();
+    @Test
+    public void testGoodBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        verify(stmt, times(1)).executeUpdate(sql);
-        verify(stmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(2)).close();    // make sure we closed the connection
+        callGoodBatch(params);
+    }
 
-        // call the other variation
-        when(meta.getParameterCount()).thenReturn(1);
-        runner.update("update blah set unit = ?", "test").get();
+    @Test
+    public void testGoodBatchDefaultConstructor() throws Exception {
+        runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        verify(prepStmt, times(2)).executeUpdate();
-        verify(prepStmt, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(3)).close();    // make sure we closed the connection
+        callGoodBatch(conn, params);
     }
 
+    @SuppressWarnings("deprecation") // deliberate test of deprecated code
     @Test
-    public void testGoodUpdate() throws Exception {
-        callGoodUpdate();
+    public void testGoodBatchPmdTrue() throws Exception {
+        runner = new AsyncQueryRunner(dataSource, true, Executors.newFixedThreadPool(1));
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+
+        callGoodBatch(params);
     }
 
-    @SuppressWarnings("deprecation") // deliberate test of deprecated code
     @Test
-    public void testGoodUpdatePmdTrue() throws Exception {
-        runner = new AsyncQueryRunner(true, Executors.newFixedThreadPool(1));
-        callGoodUpdate(conn);
+    public void testGoodQuery() throws Exception {
+        callGoodQuery();
     }
 
     @Test
-    public void testGoodUpdateDefaultConstructor() throws Exception {
+    public void testGoodQueryDefaultConstructor() throws Exception {
         runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
-        callGoodUpdate(conn);
+        callGoodQuery(conn);
     }
 
-    // helper method for calling batch when an exception is expected
-    private void callUpdateWithException(final Object... params) throws Exception {
-        boolean caught = false;
-
-        try {
-            when(meta.getParameterCount()).thenReturn(2);
-            runner.update("select * from blah where ? = ?", params).get();
 
-            verify(prepStmt, times(1)).executeUpdate();
-            verify(prepStmt, times(1)).close();    // make sure we closed the statement
-            verify(conn, times(1)).close();    // make sure we closed the connection
-        } catch (final Exception e) {
-            caught = true;
-        }
-
-        if(!caught) {
-            fail("Exception never thrown, but expected");
-        }
+    @SuppressWarnings("deprecation") // deliberate test of deprecated code
+    @Test
+    public void testGoodQueryPmdTrue() throws Exception {
+        runner = new AsyncQueryRunner(true, Executors.newFixedThreadPool(1));
+        callGoodQuery(conn);
     }
 
     @Test
-    public void testNoParamsUpdate() throws Exception {
+    public void testGoodUpdate() throws Exception {
         callGoodUpdate();
     }
 
     @Test
-    public void testTooFewParamsUpdate() throws Exception {
-        callUpdateWithException("unit");
+    public void testGoodUpdateDefaultConstructor() throws Exception {
+        runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
+        callGoodUpdate(conn);
     }
 
+    @SuppressWarnings("deprecation") // deliberate test of deprecated code
     @Test
-    public void testTooManyParamsUpdate() throws Exception {
-        callUpdateWithException("unit", "test", "fail");
+    public void testGoodUpdatePmdTrue() throws Exception {
+        runner = new AsyncQueryRunner(true, Executors.newFixedThreadPool(1));
+        callGoodUpdate(conn);
     }
 
     @Test
@@ -460,6 +386,33 @@ public class AsyncQueryRunnerTest {
         verify(mockQueryRunner).insert(conn, "4", handler, "param1");
     }
 
+    @Test
+    public void testNoParamsQuery() throws Exception {
+        callGoodQuery();
+    }
+
+    @Test
+    public void testNoParamsUpdate() throws Exception {
+        callGoodUpdate();
+    }
+
+    @Test(expected=ExecutionException.class)
+    public void testNullConnectionBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+
+        when(dataSource.getConnection()).thenReturn(null);
+
+        runner.batch("select * from blah where ? = ?", params).get();
+    }
+
+
+    @Test(expected=ExecutionException.class)
+    public void testNullConnectionQuery() throws Exception {
+        when(dataSource.getConnection()).thenReturn(null);
+
+        runner.query("select * from blah where ? = ?", handler, "unit", "test").get();
+    }
+
     @Test(expected=ExecutionException.class)
     public void testNullConnectionUpdate() throws Exception {
         when(dataSource.getConnection()).thenReturn(null);
@@ -467,24 +420,71 @@ public class AsyncQueryRunnerTest {
         runner.update("select * from blah where ? = ?", "unit", "test").get();
     }
 
+    @Test(expected=ExecutionException.class)
+    public void testNullHandlerQuery() throws Exception {
+        runner.query("select * from blah where ? = ?", null).get();
+    }
+
+    @Test(expected=ExecutionException.class)
+    public void testNullParamsArgBatch() throws Exception {
+        runner.batch("select * from blah where ? = ?", null).get();
+    }
+
+    @Test
+    public void testNullParamsBatch() throws Exception {
+        final String[][] params = new String[][] { { null, "unit" }, { "test", null } };
+
+        callGoodBatch(params);
+    }
+
+    @Test(expected=ExecutionException.class)
+    public void testNullSqlBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+
+        runner.batch(null, params).get();
+    }
+
+    @Test(expected=ExecutionException.class)
+    public void testNullSqlQuery() throws Exception {
+        runner.query(null, handler).get();
+    }
+
     @Test(expected=ExecutionException.class)
     public void testNullSqlUpdate() throws Exception {
         runner.update(null).get();
     }
 
     @Test
-    public void testExecuteUpdateException() throws Exception {
-        doThrow(new SQLException()).when(prepStmt).executeUpdate();
+    public void testTooFewParamsBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit" }, { "test" } };
 
-        callUpdateWithException("unit", "test");
+        callBatchWithException("select * from blah where ? = ?", params);
     }
 
-    //
-    // Random tests
-    //
-    @Test(expected=ExecutionException.class)
-    public void testBadPrepareConnection() throws Exception {
-        runner = new AsyncQueryRunner(Executors.newFixedThreadPool(1));
-        runner.update("update blah set unit = test").get();
+    @Test
+    public void testTooFewParamsQuery() throws Exception {
+        callQueryWithException("unit");
+    }
+
+    @Test
+    public void testTooFewParamsUpdate() throws Exception {
+        callUpdateWithException("unit");
+    }
+
+    @Test
+    public void testTooManyParamsBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit", "unit" }, { "test", "test", "test" } };
+
+        callBatchWithException("select * from blah where ? = ?", params);
+    }
+
+    @Test
+    public void testTooManyParamsQuery() throws Exception {
+        callQueryWithException("unit", "test", "fail");
+    }
+
+    @Test
+    public void testTooManyParamsUpdate() throws Exception {
+        callUpdateWithException("unit", "test", "fail");
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/BaseResultSetHandlerTest.java b/src/test/java/org/apache/commons/dbutils/BaseResultSetHandlerTest.java
index a7fa756..646c0ed 100644
--- a/src/test/java/org/apache/commons/dbutils/BaseResultSetHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/BaseResultSetHandlerTest.java
@@ -26,26 +26,6 @@ import org.junit.Test;
 
 public final class BaseResultSetHandlerTest extends BaseTestCase {
 
-    @Test
-    public void handleWithoutExplicitResultSetInvocation() throws Exception {
-        final Collection<Map<String, Object>> result = new ToMapCollectionHandler().handle(createMockResultSet());
-
-        assertFalse(result.isEmpty());
-
-        for (final Map<String, Object> current : result) {
-            assertTrue(current.containsKey("one"));
-            assertTrue(current.containsKey("two"));
-            assertTrue(current.containsKey("three"));
-            assertTrue(current.containsKey("notInBean"));
-            assertTrue(current.containsKey("intTest"));
-            assertTrue(current.containsKey("integerTest"));
-            assertTrue(current.containsKey("nullObjectTest"));
-            assertTrue(current.containsKey("nullPrimitiveTest"));
-            assertTrue(current.containsKey("notDate"));
-            assertTrue(current.containsKey("columnProcessorDoubleTest"));
-        }
-    }
-
     private static final class ToMapCollectionHandler
         extends BaseResultSetHandler<Collection<Map<String, Object>>> {
 
@@ -68,4 +48,24 @@ public final class BaseResultSetHandlerTest extends BaseTestCase {
 
     }
 
+    @Test
+    public void handleWithoutExplicitResultSetInvocation() throws Exception {
+        final Collection<Map<String, Object>> result = new ToMapCollectionHandler().handle(createMockResultSet());
+
+        assertFalse(result.isEmpty());
+
+        for (final Map<String, Object> current : result) {
+            assertTrue(current.containsKey("one"));
+            assertTrue(current.containsKey("two"));
+            assertTrue(current.containsKey("three"));
+            assertTrue(current.containsKey("notInBean"));
+            assertTrue(current.containsKey("intTest"));
+            assertTrue(current.containsKey("integerTest"));
+            assertTrue(current.containsKey("nullObjectTest"));
+            assertTrue(current.containsKey("nullPrimitiveTest"));
+            assertTrue(current.containsKey("notDate"));
+            assertTrue(current.containsKey("columnProcessorDoubleTest"));
+        }
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/dbutils/BaseTestCase.java b/src/test/java/org/apache/commons/dbutils/BaseTestCase.java
index c9b530c..d56c6fe 100644
--- a/src/test/java/org/apache/commons/dbutils/BaseTestCase.java
+++ b/src/test/java/org/apache/commons/dbutils/BaseTestCase.java
@@ -110,6 +110,13 @@ public class BaseTestCase extends TestCase {
      */
     protected ResultSet emptyResultSet = null;
 
+    /**
+     * Creates a freshly initialized ResultSet.
+     */
+    protected ResultSet createMockResultSet() {
+        return MockResultSet.create(metaData, rows);
+    }
+
     /**
      * This is called before each test method so ResultSet will be fresh each
      * time.
@@ -123,13 +130,6 @@ public class BaseTestCase extends TestCase {
         emptyResultSet = MockResultSet.create(metaData, null);
     }
 
-    /**
-     * Creates a freshly initialized ResultSet.
-     */
-    protected ResultSet createMockResultSet() {
-        return MockResultSet.create(metaData, rows);
-    }
-
     // Test which allows Eclipse to be run on full project (avoids no tests found)
     // check that the rows are valid for the column definition
     public void testCheckDataSizes() {
diff --git a/src/test/java/org/apache/commons/dbutils/BasicRowProcessorTest.java b/src/test/java/org/apache/commons/dbutils/BasicRowProcessorTest.java
index 525b391..3c71398 100644
--- a/src/test/java/org/apache/commons/dbutils/BasicRowProcessorTest.java
+++ b/src/test/java/org/apache/commons/dbutils/BasicRowProcessorTest.java
@@ -40,6 +40,22 @@ public class BasicRowProcessorTest extends BaseTestCase {
     private static final DateFormat datef =
         new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
 
+    public void testPutAllContainsKeyAndRemove() throws Exception {
+        Map<String, Object> test = new HashMap<>(3);
+        test.put("fiRst", "thing");
+        test.put("seCond", "another");
+        test.put("thIrd", "more");
+        Map<String, Object> brpMap = BasicRowProcessor.createCaseInsensitiveHashMap(3);
+        brpMap.putAll(test);
+
+        assertEquals(test, brpMap);
+        assertTrue(brpMap.containsKey("fiRst"));
+        assertTrue(brpMap.containsKey("first"));
+
+        brpMap.remove("first");
+        assertFalse(brpMap.containsKey("first"));
+    }
+
     public void testToArray() throws SQLException {
 
         Object[] a;
@@ -158,20 +174,4 @@ public class BasicRowProcessorTest extends BaseTestCase {
 
         assertFalse(itr.hasNext());
     }
-
-    public void testPutAllContainsKeyAndRemove() throws Exception {
-        Map<String, Object> test = new HashMap<>(3);
-        test.put("fiRst", "thing");
-        test.put("seCond", "another");
-        test.put("thIrd", "more");
-        Map<String, Object> brpMap = BasicRowProcessor.createCaseInsensitiveHashMap(3);
-        brpMap.putAll(test);
-
-        assertEquals(test, brpMap);
-        assertTrue(brpMap.containsKey("fiRst"));
-        assertTrue(brpMap.containsKey("first"));
-
-        brpMap.remove("first");
-        assertFalse(brpMap.containsKey("first"));
-    }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/BeanProcessorTest.java b/src/test/java/org/apache/commons/dbutils/BeanProcessorTest.java
index f941dac..dfedde6 100644
--- a/src/test/java/org/apache/commons/dbutils/BeanProcessorTest.java
+++ b/src/test/java/org/apache/commons/dbutils/BeanProcessorTest.java
@@ -32,39 +32,47 @@ import org.apache.commons.dbutils.annotations.Column;
 
 public class BeanProcessorTest extends BaseTestCase {
 
-    private static final BeanProcessor beanProc = new BeanProcessor();
+    private static class IndexedPropertyTestClass {
+        private String name;
+        // Indexed variable with indexed getter and setter
+        private List<String> things;
+        // Indexed variable without indexed getter or setter
+        private List<String> stuff;
 
-    public void testProcessWithToBean() throws SQLException {
-        assertTrue(this.rs.next());
-        TestBean b = beanProc.toBean(this.rs, TestBean.class);
-        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
-        assertEquals(b.getThree(), TestBean.Ordinal.THREE);
+        public String getName() {
+            return name;
+        }
 
-        assertTrue(this.rs.next());
-        b = beanProc.toBean(this.rs, TestBean.class);
-        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
-        assertEquals(b.getThree(), TestBean.Ordinal.SIX);
+        public List<String> getStuff() {
+            return stuff;
+        }
 
-        assertFalse(this.rs.next());
-    }
+        public String getThing(int idx) {
+            return things.get(idx);
+        }
 
-    public void testProcessWithPopulateBean() throws SQLException {
-        TestBean b = new TestBean();
+        public List<String> getThings() {
+            return things;
+        }
 
-        assertTrue(this.rs.next());
-        b = beanProc.populateBean(this.rs, b);
-        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
-        assertEquals(b.getThree(), TestBean.Ordinal.THREE);
+        public void setName(String name) {
+            this.name = name;
+        }
 
-        assertTrue(this.rs.next());
-        b = beanProc.populateBean(this.rs, b);
-        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
-        assertEquals(b.getThree(), TestBean.Ordinal.SIX);
+        public void setStuff(List<String> stuff) {
+            this.stuff = stuff;
+        }
 
-        assertFalse(this.rs.next());
+        public void setThing(int idx, String thing) {
+            this.things.set(idx, thing);
+        }
+
+        public void setThings(List<String> things) {
+            this.things = things;
+        }
     }
 
-    public static class MapColumnToPropertiesBean {
+    public static class MapColumnToAnnotationFieldBean {
         private String one;
 
         private String two;
@@ -73,105 +81,79 @@ public class BeanProcessorTest extends BaseTestCase {
 
         private String four;
 
+        public String getFour() {
+            return four;
+        }
+
         public String getOne() {
             return one;
         }
 
-        public void setOne(final String one) {
-            this.one = one;
+        @Column(name = "three_")
+        public String getThree() {
+            return three;
         }
 
         public String getTwo() {
             return two;
         }
 
-        public void setTwo(final String two) {
-            this.two = two;
+        public void setFour(final String four) {
+            this.four = four;
         }
 
-        public String getThree() {
-            return three;
+        public void setOne(final String one) {
+            this.one = one;
         }
 
         public void setThree(final String three) {
             this.three = three;
         }
 
-        public String getFour() {
-            return four;
-        }
-
-        public void setFour(final String four) {
-            this.four = four;
+        public void setTwo(final String two) {
+            this.two = two;
         }
     }
 
-    public void testMapColumnToProperties() throws Exception {
-        final String[] columnNames = { "test", "test", "three" };
-        final String[] columnLabels = { "one", "two", null };
-        final ResultSetMetaData rsmd = ProxyFactory.instance().createResultSetMetaData(
-                new MockResultSetMetaData(columnNames, columnLabels));
-        final PropertyDescriptor[] props = Introspector.getBeanInfo(MapColumnToPropertiesBean.class).getPropertyDescriptors();
-
-        final int[] columns = beanProc.mapColumnsToProperties(rsmd, props);
-        for (int i = 1; i < columns.length; i++) {
-            assertTrue(columns[i] != BeanProcessor.PROPERTY_NOT_FOUND);
-        }
-    }
+    public static class MapColumnToPropertiesBean {
+        private String one;
 
-    public void testMapColumnToPropertiesWithOverrides() throws Exception {
-        final Map<String, String> columnToPropertyOverrides = new HashMap<>();
-        columnToPropertyOverrides.put("five", "four");
-        final BeanProcessor beanProc = new BeanProcessor(columnToPropertyOverrides);
-        final String[] columnNames = { "test", "test", "three", "five" };
-        final String[] columnLabels = { "one", "two", null, null };
-        final ResultSetMetaData rsmd = ProxyFactory.instance().createResultSetMetaData(
-                new MockResultSetMetaData(columnNames, columnLabels));
-        final PropertyDescriptor[] props = Introspector.getBeanInfo(MapColumnToPropertiesBean.class).getPropertyDescriptors();
+        private String two;
 
-        final int[] columns = beanProc.mapColumnsToProperties(rsmd, props);
-        for (int i = 1; i < columns.length; i++) {
-            assertTrue(columns[i] != BeanProcessor.PROPERTY_NOT_FOUND);
-        }
-    }
+        private String three;
 
-    private static class IndexedPropertyTestClass {
-        private String name;
-        // Indexed variable with indexed getter and setter
-        private List<String> things;
-        // Indexed variable without indexed getter or setter
-        private List<String> stuff;
+        private String four;
 
-        public String getName() {
-            return name;
+        public String getFour() {
+            return four;
         }
 
-        public void setName(String name) {
-            this.name = name;
+        public String getOne() {
+            return one;
         }
 
-        public List<String> getThings() {
-            return things;
+        public String getThree() {
+            return three;
         }
 
-        public String getThing(int idx) {
-            return things.get(idx);
+        public String getTwo() {
+            return two;
         }
 
-        public void setThings(List<String> things) {
-            this.things = things;
+        public void setFour(final String four) {
+            this.four = four;
         }
 
-        public void setThing(int idx, String thing) {
-            this.things.set(idx, thing);
+        public void setOne(final String one) {
+            this.one = one;
         }
 
-        public List<String> getStuff() {
-            return stuff;
+        public void setThree(final String three) {
+            this.three = three;
         }
 
-        public void setStuff(List<String> stuff) {
-            this.stuff = stuff;
+        public void setTwo(final String two) {
+            this.two = two;
         }
     }
 
@@ -188,22 +170,6 @@ public class BeanProcessorTest extends BaseTestCase {
         }
     }
 
-    public void testCheckAnnotationOnMissingReadMethod() throws Exception {
-        String[] colNames = new String[] {"testField"};
-        ResultSetMetaData metaData = MockResultSetMetaData.create(colNames);
-
-        String testField = "first";
-        Object[][] rows = new Object[][] {
-                new Object[] {testField}
-        };
-
-        ResultSet rs = MockResultSet.create(metaData, rows);
-        assertTrue(rs.next());
-        TestNoGetter testCls = new TestNoGetter();
-        testCls = beanProc.populateBean(rs, testCls);
-        assertEquals(testCls.testField, "first");
-    }
-
     private static final class TestWrongSetter {
         public Integer testField;
 
@@ -222,20 +188,22 @@ public class BeanProcessorTest extends BaseTestCase {
         }
     }
 
-    public void testWrongSetterParamCount() throws Exception {
+    private static final BeanProcessor beanProc = new BeanProcessor();
+
+    public void testCheckAnnotationOnMissingReadMethod() throws Exception {
         String[] colNames = new String[] {"testField"};
         ResultSetMetaData metaData = MockResultSetMetaData.create(colNames);
 
-        Integer testField = 1;
+        String testField = "first";
         Object[][] rows = new Object[][] {
                 new Object[] {testField}
         };
 
         ResultSet rs = MockResultSet.create(metaData, rows);
         assertTrue(rs.next());
-        TestWrongSetter testCls = new TestWrongSetter();
+        TestNoGetter testCls = new TestNoGetter();
         testCls = beanProc.populateBean(rs, testCls);
-        assertNull(testCls.testField);
+        assertEquals(testCls.testField, "first");
     }
 
     /**
@@ -266,59 +234,91 @@ public class BeanProcessorTest extends BaseTestCase {
         assertArrayEquals(stuff.toArray(), testCls.getStuff().toArray());
     }
 
-    public static class MapColumnToAnnotationFieldBean {
-        private String one;
-
-        private String two;
+    public void testMapColumnToAnnotationField() throws Exception {
+        final String[] columnNames = { "test", "test", "three_" };
+        final String[] columnLabels = { "one", "two", null };
+        final ResultSetMetaData rsmd = ProxyFactory.instance().createResultSetMetaData(
+                new MockResultSetMetaData(columnNames, columnLabels));
+        final PropertyDescriptor[] props = Introspector.getBeanInfo(MapColumnToAnnotationFieldBean.class).getPropertyDescriptors();
 
-        private String three;
+        final int[] columns = beanProc.mapColumnsToProperties(rsmd, props);
+        for (int i = 1; i < columns.length; i++) {
+            assertTrue(columns[i] != BeanProcessor.PROPERTY_NOT_FOUND);
+        }
+    }
 
-        private String four;
+    public void testMapColumnToProperties() throws Exception {
+        final String[] columnNames = { "test", "test", "three" };
+        final String[] columnLabels = { "one", "two", null };
+        final ResultSetMetaData rsmd = ProxyFactory.instance().createResultSetMetaData(
+                new MockResultSetMetaData(columnNames, columnLabels));
+        final PropertyDescriptor[] props = Introspector.getBeanInfo(MapColumnToPropertiesBean.class).getPropertyDescriptors();
 
-        public String getOne() {
-            return one;
+        final int[] columns = beanProc.mapColumnsToProperties(rsmd, props);
+        for (int i = 1; i < columns.length; i++) {
+            assertTrue(columns[i] != BeanProcessor.PROPERTY_NOT_FOUND);
         }
+    }
 
-        public void setOne(final String one) {
-            this.one = one;
-        }
+    public void testMapColumnToPropertiesWithOverrides() throws Exception {
+        final Map<String, String> columnToPropertyOverrides = new HashMap<>();
+        columnToPropertyOverrides.put("five", "four");
+        final BeanProcessor beanProc = new BeanProcessor(columnToPropertyOverrides);
+        final String[] columnNames = { "test", "test", "three", "five" };
+        final String[] columnLabels = { "one", "two", null, null };
+        final ResultSetMetaData rsmd = ProxyFactory.instance().createResultSetMetaData(
+                new MockResultSetMetaData(columnNames, columnLabels));
+        final PropertyDescriptor[] props = Introspector.getBeanInfo(MapColumnToPropertiesBean.class).getPropertyDescriptors();
 
-        public String getTwo() {
-            return two;
+        final int[] columns = beanProc.mapColumnsToProperties(rsmd, props);
+        for (int i = 1; i < columns.length; i++) {
+            assertTrue(columns[i] != BeanProcessor.PROPERTY_NOT_FOUND);
         }
+    }
 
-        public void setTwo(final String two) {
-            this.two = two;
-        }
+    public void testProcessWithPopulateBean() throws SQLException {
+        TestBean b = new TestBean();
 
-        @Column(name = "three_")
-        public String getThree() {
-            return three;
-        }
+        assertTrue(this.rs.next());
+        b = beanProc.populateBean(this.rs, b);
+        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
+        assertEquals(b.getThree(), TestBean.Ordinal.THREE);
 
-        public void setThree(final String three) {
-            this.three = three;
-        }
+        assertTrue(this.rs.next());
+        b = beanProc.populateBean(this.rs, b);
+        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
+        assertEquals(b.getThree(), TestBean.Ordinal.SIX);
 
-        public String getFour() {
-            return four;
-        }
+        assertFalse(this.rs.next());
+    }
 
-        public void setFour(final String four) {
-            this.four = four;
-        }
+    public void testProcessWithToBean() throws SQLException {
+        assertTrue(this.rs.next());
+        TestBean b = beanProc.toBean(this.rs, TestBean.class);
+        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
+        assertEquals(b.getThree(), TestBean.Ordinal.THREE);
+
+        assertTrue(this.rs.next());
+        b = beanProc.toBean(this.rs, TestBean.class);
+        assertEquals(13.0, b.getColumnProcessorDoubleTest(), 0);
+        assertEquals(b.getThree(), TestBean.Ordinal.SIX);
+
+        assertFalse(this.rs.next());
     }
 
-    public void testMapColumnToAnnotationField() throws Exception {
-        final String[] columnNames = { "test", "test", "three_" };
-        final String[] columnLabels = { "one", "two", null };
-        final ResultSetMetaData rsmd = ProxyFactory.instance().createResultSetMetaData(
-                new MockResultSetMetaData(columnNames, columnLabels));
-        final PropertyDescriptor[] props = Introspector.getBeanInfo(MapColumnToAnnotationFieldBean.class).getPropertyDescriptors();
+    public void testWrongSetterParamCount() throws Exception {
+        String[] colNames = new String[] {"testField"};
+        ResultSetMetaData metaData = MockResultSetMetaData.create(colNames);
 
-        final int[] columns = beanProc.mapColumnsToProperties(rsmd, props);
-        for (int i = 1; i < columns.length; i++) {
-            assertTrue(columns[i] != BeanProcessor.PROPERTY_NOT_FOUND);
-        }
+        Integer testField = 1;
+        Object[][] rows = new Object[][] {
+                new Object[] {testField}
+        };
+
+        ResultSet rs = MockResultSet.create(metaData, rows);
+        assertTrue(rs.next());
+        TestWrongSetter testCls = new TestWrongSetter();
+        testCls = beanProc.populateBean(rs, testCls);
+        assertNull(testCls.testField);
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/DbUtilsTest.java b/src/test/java/org/apache/commons/dbutils/DbUtilsTest.java
index b6d0ebb..06999b6 100644
--- a/src/test/java/org/apache/commons/dbutils/DbUtilsTest.java
+++ b/src/test/java/org/apache/commons/dbutils/DbUtilsTest.java
@@ -36,9 +36,40 @@ import org.junit.Test;
 
 public class DbUtilsTest {
 
-    @Test
-    public void closeNullConnection() throws Exception {
-        DbUtils.close((Connection) null);
+    public static class DriverProxyTest {
+        private static final Driver mockedDriver = mock(Driver.class);
+        private DbUtils.DriverProxy proxy;
+
+        @Before
+        public void setUp() {
+            proxy = new DbUtils.DriverProxy(mockedDriver);
+        }
+
+        @After
+        public void tearDown() {
+            reset(mockedDriver);
+        }
+
+        @Test
+        public void testProxiedMethods() throws Exception {
+            proxy.getMajorVersion();
+            verify(mockedDriver).getMajorVersion();
+            proxy.getMinorVersion();
+            verify(mockedDriver).getMinorVersion();
+            proxy.jdbcCompliant();
+            verify(mockedDriver).jdbcCompliant();
+
+            final String url = "testUrl";
+            proxy.acceptsURL(url);
+            verify(mockedDriver).acceptsURL(url);
+
+            final Properties props = new Properties();
+            props.setProperty("test", "true");
+            proxy.connect(url, props);
+            verify(mockedDriver).connect(url, props);
+            proxy.getPropertyInfo(url, props);
+            verify(mockedDriver).getPropertyInfo(url, props);
+        }
     }
 
     @Test
@@ -49,15 +80,13 @@ public class DbUtilsTest {
     }
 
     @Test
-    public void closeNullResultSet() throws Exception {
-        DbUtils.close((ResultSet) null);
+    public void closeNullConnection() throws Exception {
+        DbUtils.close((Connection) null);
     }
 
     @Test
-    public void closeResultSet() throws Exception {
-        final ResultSet mockResultSet = mock(ResultSet.class);
-        DbUtils.close(mockResultSet);
-        verify(mockResultSet).close();
+    public void closeNullResultSet() throws Exception {
+        DbUtils.close((ResultSet) null);
     }
 
     @Test
@@ -66,22 +95,45 @@ public class DbUtilsTest {
     }
 
     @Test
-    public void closeStatement() throws Exception {
+    public void closeQuietlyConnection() throws Exception {
+        final Connection mockConnection = mock(Connection.class);
+        DbUtils.closeQuietly(mockConnection);
+        verify(mockConnection).close();
+    }
+
+    @Test
+    public void closeQuietlyConnectionResultSetStatement() throws Exception {
+        final Connection mockConnection = mock(Connection.class);
+        final ResultSet mockResultSet = mock(ResultSet.class);
         final Statement mockStatement = mock(Statement.class);
-        DbUtils.close(mockStatement);
+        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
+        verify(mockConnection).close();
+        verify(mockResultSet).close();
         verify(mockStatement).close();
     }
 
     @Test
-    public void closeQuietlyNullConnection() throws Exception {
-        DbUtils.closeQuietly((Connection) null);
+    public void closeQuietlyConnectionResultSetStatementThrowingException() throws Exception {
+        final Connection mockConnection = mock(Connection.class);
+        final ResultSet mockResultSet = mock(ResultSet.class);
+        final Statement mockStatement = mock(Statement.class);
+        doThrow(SQLException.class).when(mockStatement).close();
+        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
+        verify(mockConnection).close();
+        verify(mockResultSet).close();
+        verify(mockStatement).close();
     }
 
     @Test
-    public void closeQuietlyConnection() throws Exception {
+    public void closeQuietlyConnectionResultSetThrowingExceptionStatement() throws Exception {
         final Connection mockConnection = mock(Connection.class);
-        DbUtils.closeQuietly(mockConnection);
+        final ResultSet mockResultSet = mock(ResultSet.class);
+        doThrow(SQLException.class).when(mockResultSet).close();
+        final Statement mockStatement = mock(Statement.class);
+        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
         verify(mockConnection).close();
+        verify(mockResultSet).close();
+        verify(mockStatement).close();
     }
 
     @Test
@@ -91,11 +143,33 @@ public class DbUtilsTest {
         DbUtils.closeQuietly(mockConnection);
     }
 
+    @Test
+    public void closeQuietlyConnectionThrowingExceptionResultSetStatement() throws Exception {
+        final Connection mockConnection = mock(Connection.class);
+        doThrow(SQLException.class).when(mockConnection).close();
+        final ResultSet mockResultSet = mock(ResultSet.class);
+        final Statement mockStatement = mock(Statement.class);
+        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
+        verify(mockConnection).close();
+        verify(mockResultSet).close();
+        verify(mockStatement).close();
+    }
+
+    @Test
+    public void closeQuietlyNullConnection() throws Exception {
+        DbUtils.closeQuietly((Connection) null);
+    }
+
     @Test
     public void closeQuietlyNullResultSet() throws Exception {
         DbUtils.closeQuietly((ResultSet) null);
     }
 
+    @Test
+    public void closeQuietlyNullStatement() throws Exception {
+        DbUtils.closeQuietly((Statement) null);
+    }
+
     @Test
     public void closeQuietlyResultSet() throws Exception {
         final ResultSet mockResultSet = mock(ResultSet.class);
@@ -110,11 +184,6 @@ public class DbUtilsTest {
         DbUtils.closeQuietly(mockResultSet);
     }
 
-    @Test
-    public void closeQuietlyNullStatement() throws Exception {
-        DbUtils.closeQuietly((Statement) null);
-    }
-
     @Test
     public void closeQuietlyStatement() throws Exception {
         final Statement mockStatement = mock(Statement.class);
@@ -130,56 +199,40 @@ public class DbUtilsTest {
     }
 
     @Test
-    public void closeQuietlyConnectionResultSetStatement() throws Exception {
-        final Connection mockConnection = mock(Connection.class);
+    public void closeResultSet() throws Exception {
         final ResultSet mockResultSet = mock(ResultSet.class);
-        final Statement mockStatement = mock(Statement.class);
-        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
-        verify(mockConnection).close();
+        DbUtils.close(mockResultSet);
         verify(mockResultSet).close();
-        verify(mockStatement).close();
     }
 
     @Test
-    public void closeQuietlyConnectionThrowingExceptionResultSetStatement() throws Exception {
-        final Connection mockConnection = mock(Connection.class);
-        doThrow(SQLException.class).when(mockConnection).close();
-        final ResultSet mockResultSet = mock(ResultSet.class);
+    public void closeStatement() throws Exception {
         final Statement mockStatement = mock(Statement.class);
-        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
-        verify(mockConnection).close();
-        verify(mockResultSet).close();
+        DbUtils.close(mockStatement);
         verify(mockStatement).close();
     }
 
     @Test
-    public void closeQuietlyConnectionResultSetThrowingExceptionStatement() throws Exception {
+    public void commitAndClose() throws Exception {
         final Connection mockConnection = mock(Connection.class);
-        final ResultSet mockResultSet = mock(ResultSet.class);
-        doThrow(SQLException.class).when(mockResultSet).close();
-        final Statement mockStatement = mock(Statement.class);
-        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
+        DbUtils.commitAndClose(mockConnection);
+        verify(mockConnection).commit();
         verify(mockConnection).close();
-        verify(mockResultSet).close();
-        verify(mockStatement).close();
     }
 
     @Test
-    public void closeQuietlyConnectionResultSetStatementThrowingException() throws Exception {
+    public void commitAndCloseQuietly() throws Exception {
         final Connection mockConnection = mock(Connection.class);
-        final ResultSet mockResultSet = mock(ResultSet.class);
-        final Statement mockStatement = mock(Statement.class);
-        doThrow(SQLException.class).when(mockStatement).close();
-        DbUtils.closeQuietly(mockConnection, mockStatement, mockResultSet);
+        DbUtils.commitAndClose(mockConnection);
+        verify(mockConnection).commit();
         verify(mockConnection).close();
-        verify(mockResultSet).close();
-        verify(mockStatement).close();
     }
 
     @Test
-    public void commitAndClose() throws Exception {
+    public void commitAndCloseQuietlyWithException() throws Exception {
         final Connection mockConnection = mock(Connection.class);
-        DbUtils.commitAndClose(mockConnection);
+        doThrow(SQLException.class).when(mockConnection).close();
+        DbUtils.commitAndCloseQuietly(mockConnection);
         verify(mockConnection).commit();
         verify(mockConnection).close();
     }
@@ -197,28 +250,6 @@ public class DbUtilsTest {
         verify(mockConnection).close();
     }
 
-    @Test
-    public void commitAndCloseQuietly() throws Exception {
-        final Connection mockConnection = mock(Connection.class);
-        DbUtils.commitAndClose(mockConnection);
-        verify(mockConnection).commit();
-        verify(mockConnection).close();
-    }
-
-    @Test
-    public void commitAndCloseQuietlyWithException() throws Exception {
-        final Connection mockConnection = mock(Connection.class);
-        doThrow(SQLException.class).when(mockConnection).close();
-        DbUtils.commitAndCloseQuietly(mockConnection);
-        verify(mockConnection).commit();
-        verify(mockConnection).close();
-    }
-
-    @Test
-    public void rollbackNull() throws Exception {
-        DbUtils.rollback(null);
-    }
-
     @Test
     public void rollback() throws Exception {
         final Connection mockConnection = mock(Connection.class);
@@ -227,34 +258,36 @@ public class DbUtilsTest {
     }
 
     @Test
-    public void rollbackQuietlyNull() throws Exception {
-        DbUtils.rollbackQuietly(null);
+    public void rollbackAndClose() throws Exception {
+        final Connection mockConnection = mock(Connection.class);
+        DbUtils.rollbackAndClose(mockConnection);
+        verify(mockConnection).rollback();
+        verify(mockConnection).close();
     }
 
     @Test
-    public void rollbackQuietly() throws Exception {
-        Connection mockConnection = mock(Connection.class);
-        DbUtils.rollbackQuietly(mockConnection);
-        verify(mockConnection).rollback();
+    public void rollbackAndCloseNull() throws Exception {
+        DbUtils.rollbackAndClose(null);
     }
     
     @Test
-    public void rollbackQuietlyWithException() throws Exception {
-        Connection mockConnection = mock(Connection.class);
-        doThrow(SQLException.class).when(mockConnection).rollback();
-        DbUtils.rollbackQuietly(mockConnection);
+    public void rollbackAndCloseQuietly() throws Exception {
+        final Connection mockConnection = mock(Connection.class);
+        DbUtils.rollbackAndCloseQuietly(mockConnection);
         verify(mockConnection).rollback();
+        verify(mockConnection).close();
     }
     
     @Test
-    public void rollbackAndCloseNull() throws Exception {
-        DbUtils.rollbackAndClose(null);
+    public void rollbackAndCloseQuietlyNull() throws Exception {
+        DbUtils.rollbackAndCloseQuietly(null);
     }
 
     @Test
-    public void rollbackAndClose() throws Exception {
+    public void rollbackAndCloseQuietlyWithException() throws Exception {
         final Connection mockConnection = mock(Connection.class);
-        DbUtils.rollbackAndClose(mockConnection);
+        doThrow(SQLException.class).when(mockConnection).rollback();
+        DbUtils.rollbackAndCloseQuietly(mockConnection);
         verify(mockConnection).rollback();
         verify(mockConnection).close();
     }
@@ -274,32 +307,28 @@ public class DbUtilsTest {
     }
 
     @Test
-    public void rollbackAndCloseQuietlyNull() throws Exception {
-        DbUtils.rollbackAndCloseQuietly(null);
+    public void rollbackNull() throws Exception {
+        DbUtils.rollback(null);
     }
 
     @Test
-    public void rollbackAndCloseQuietly() throws Exception {
-        final Connection mockConnection = mock(Connection.class);
-        DbUtils.rollbackAndCloseQuietly(mockConnection);
+    public void rollbackQuietly() throws Exception {
+        Connection mockConnection = mock(Connection.class);
+        DbUtils.rollbackQuietly(mockConnection);
         verify(mockConnection).rollback();
-        verify(mockConnection).close();
     }
 
     @Test
-    public void rollbackAndCloseQuietlyWithException() throws Exception {
-        final Connection mockConnection = mock(Connection.class);
-        doThrow(SQLException.class).when(mockConnection).rollback();
-        DbUtils.rollbackAndCloseQuietly(mockConnection);
-        verify(mockConnection).rollback();
-        verify(mockConnection).close();
+    public void rollbackQuietlyNull() throws Exception {
+        DbUtils.rollbackQuietly(null);
     }
 
     @Test
-    public void testLoadDriverReturnsFalse() {
-
-        assertFalse(DbUtils.loadDriver(""));
-
+    public void rollbackQuietlyWithException() throws Exception {
+        Connection mockConnection = mock(Connection.class);
+        doThrow(SQLException.class).when(mockConnection).rollback();
+        DbUtils.rollbackQuietly(mockConnection);
+        verify(mockConnection).rollback();
     }
 
     @Test
@@ -309,39 +338,10 @@ public class DbUtilsTest {
 
     }
 
-    public static class DriverProxyTest {
-        private static final Driver mockedDriver = mock(Driver.class);
-        private DbUtils.DriverProxy proxy;
-
-        @Before
-        public void setUp() {
-            proxy = new DbUtils.DriverProxy(mockedDriver);
-        }
-
-        @After
-        public void tearDown() {
-            reset(mockedDriver);
-        }
-
-        @Test
-        public void testProxiedMethods() throws Exception {
-            proxy.getMajorVersion();
-            verify(mockedDriver).getMajorVersion();
-            proxy.getMinorVersion();
-            verify(mockedDriver).getMinorVersion();
-            proxy.jdbcCompliant();
-            verify(mockedDriver).jdbcCompliant();
+    @Test
+    public void testLoadDriverReturnsFalse() {
 
-            final String url = "testUrl";
-            proxy.acceptsURL(url);
-            verify(mockedDriver).acceptsURL(url);
+        assertFalse(DbUtils.loadDriver(""));
 
-            final Properties props = new Properties();
-            props.setProperty("test", "true");
-            proxy.connect(url, props);
-            verify(mockedDriver).connect(url, props);
-            proxy.getPropertyInfo(url, props);
-            verify(mockedDriver).getPropertyInfo(url, props);
-        }
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/GenerousBeanProcessorTest.java b/src/test/java/org/apache/commons/dbutils/GenerousBeanProcessorTest.java
index 19a8b42..4016d75 100644
--- a/src/test/java/org/apache/commons/dbutils/GenerousBeanProcessorTest.java
+++ b/src/test/java/org/apache/commons/dbutils/GenerousBeanProcessorTest.java
@@ -32,8 +32,38 @@ import org.mockito.junit.MockitoJUnitRunner;
 @RunWith(MockitoJUnitRunner.class)
 public class GenerousBeanProcessorTest {
 
+    static class TestBean {
+        private String one;
+        private int two;
+        private long three;
+
+        public String getOne() {
+            return one;
+        }
+
+        public long getThree() {
+            return three;
+        }
+
+        public int getTwo() {
+            return two;
+        }
+
+        public void setOne(final String one) {
+            this.one = one;
+        }
+
+        public void setThree(final long three) {
+            this.three = three;
+        }
+
+        public void setTwo(final int two) {
+            this.two = two;
+        }
+    }
     GenerousBeanProcessor processor = new GenerousBeanProcessor();
     @Mock ResultSetMetaData metaData;
+
     PropertyDescriptor[] propDescriptors;
 
     @Before
@@ -47,21 +77,17 @@ public class GenerousBeanProcessorTest {
 
     @SuppressWarnings("boxing") // test code
     @Test
-    public void testMapColumnsToPropertiesWithOutUnderscores() throws Exception {
-        when(metaData.getColumnCount()).thenReturn(3);
-
-        when(metaData.getColumnLabel(1)).thenReturn("three");
-        when(metaData.getColumnLabel(2)).thenReturn("one");
-        when(metaData.getColumnLabel(3)).thenReturn("two");
+    public void testMapColumnsToPropertiesColumnLabelIsNull() throws Exception {
+        when(metaData.getColumnCount()).thenReturn(1);
+        when(metaData.getColumnName(1)).thenReturn("juhu");
+        when(metaData.getColumnLabel(1)).thenReturn(null);
 
         final int[] ret = processor.mapColumnsToProperties(metaData, propDescriptors);
 
         assertNotNull(ret);
-        assertEquals(4, ret.length);
+        assertEquals(2, ret.length);
         assertEquals(-1, ret[0]);
-        assertEquals(2, ret[1]);
-        assertEquals(0, ret[2]);
-        assertEquals(1, ret[3]);
+        assertEquals(-1, ret[1]);
     }
 
     @SuppressWarnings("boxing") // test code
@@ -85,12 +111,12 @@ public class GenerousBeanProcessorTest {
 
     @SuppressWarnings("boxing") // test code
     @Test
-    public void testMapColumnsToPropertiesWithUnderscores() throws Exception {
+    public void testMapColumnsToPropertiesWithOutUnderscores() throws Exception {
         when(metaData.getColumnCount()).thenReturn(3);
 
-        when(metaData.getColumnLabel(1)).thenReturn("t_h_r_e_e");
-        when(metaData.getColumnLabel(2)).thenReturn("o_n_e");
-        when(metaData.getColumnLabel(3)).thenReturn("t_w_o");
+        when(metaData.getColumnLabel(1)).thenReturn("three");
+        when(metaData.getColumnLabel(2)).thenReturn("one");
+        when(metaData.getColumnLabel(3)).thenReturn("two");
 
         final int[] ret = processor.mapColumnsToProperties(metaData, propDescriptors);
 
@@ -123,47 +149,21 @@ public class GenerousBeanProcessorTest {
 
     @SuppressWarnings("boxing") // test code
     @Test
-    public void testMapColumnsToPropertiesColumnLabelIsNull() throws Exception {
-        when(metaData.getColumnCount()).thenReturn(1);
-        when(metaData.getColumnName(1)).thenReturn("juhu");
-        when(metaData.getColumnLabel(1)).thenReturn(null);
+    public void testMapColumnsToPropertiesWithUnderscores() throws Exception {
+        when(metaData.getColumnCount()).thenReturn(3);
+
+        when(metaData.getColumnLabel(1)).thenReturn("t_h_r_e_e");
+        when(metaData.getColumnLabel(2)).thenReturn("o_n_e");
+        when(metaData.getColumnLabel(3)).thenReturn("t_w_o");
 
         final int[] ret = processor.mapColumnsToProperties(metaData, propDescriptors);
 
         assertNotNull(ret);
-        assertEquals(2, ret.length);
+        assertEquals(4, ret.length);
         assertEquals(-1, ret[0]);
-        assertEquals(-1, ret[1]);
-    }
-
-    static class TestBean {
-        private String one;
-        private int two;
-        private long three;
-
-        public String getOne() {
-            return one;
-        }
-
-        public void setOne(final String one) {
-            this.one = one;
-        }
-
-        public int getTwo() {
-            return two;
-        }
-
-        public void setTwo(final int two) {
-            this.two = two;
-        }
-
-        public long getThree() {
-            return three;
-        }
-
-        public void setThree(final long three) {
-            this.three = three;
-        }
+        assertEquals(2, ret[1]);
+        assertEquals(0, ret[2]);
+        assertEquals(1, ret[3]);
     }
 
 }
diff --git a/src/test/java/org/apache/commons/dbutils/MockResultSetMetaData.java b/src/test/java/org/apache/commons/dbutils/MockResultSetMetaData.java
index 04f0737..7ae5763 100644
--- a/src/test/java/org/apache/commons/dbutils/MockResultSetMetaData.java
+++ b/src/test/java/org/apache/commons/dbutils/MockResultSetMetaData.java
@@ -26,9 +26,6 @@ import java.sql.ResultSetMetaData;
  */
 public class MockResultSetMetaData implements InvocationHandler {
 
-    private String[] columnNames = null;
-    private String[] columnLabels = null;
-
     /**
      * Create a {@code MockResultSetMetaData} proxy object.  This is
      * equivalent to:
@@ -43,6 +40,9 @@ public class MockResultSetMetaData implements InvocationHandler {
         return ProxyFactory.instance().createResultSetMetaData(
             new MockResultSetMetaData(columnNames));
     }
+    private String[] columnNames = null;
+
+    private String[] columnLabels = null;
 
     public MockResultSetMetaData(final String[] columnNames) {
         this.columnNames = columnNames;
diff --git a/src/test/java/org/apache/commons/dbutils/OutParameterTest.java b/src/test/java/org/apache/commons/dbutils/OutParameterTest.java
index 4b85590..ec657e1 100644
--- a/src/test/java/org/apache/commons/dbutils/OutParameterTest.java
+++ b/src/test/java/org/apache/commons/dbutils/OutParameterTest.java
@@ -47,15 +47,6 @@ public class OutParameterTest {
         parameter = new OutParameter<>(Types.INTEGER, Number.class);
     }
 
-    @Test
-    public void testSetValue() throws Exception {
-        when(stmt.getObject(INDEX)).thenReturn(VALUE);
-
-        parameter.setValue(stmt, INDEX);
-
-        assertEquals(VALUE, parameter.getValue());
-    }
-
     @Test
     public void testRegister() throws Exception {
         parameter.register(stmt, INDEX);
@@ -76,4 +67,13 @@ public class OutParameterTest {
         verify(stmt, times(1)).setObject(INDEX, VALUE);
     }
 
+    @Test
+    public void testSetValue() throws Exception {
+        when(stmt.getObject(INDEX)).thenReturn(VALUE);
+
+        parameter.setValue(stmt, INDEX);
+
+        assertEquals(VALUE, parameter.getValue());
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/dbutils/ProxyFactoryTest.java b/src/test/java/org/apache/commons/dbutils/ProxyFactoryTest.java
index ac91392..bd8662d 100644
--- a/src/test/java/org/apache/commons/dbutils/ProxyFactoryTest.java
+++ b/src/test/java/org/apache/commons/dbutils/ProxyFactoryTest.java
@@ -35,6 +35,10 @@ public class ProxyFactoryTest extends BaseTestCase {
         }
     };
 
+    public void testCreateCallableStatement() {
+        assertNotNull(ProxyFactory.instance().createCallableStatement(stub));
+    }
+
     public void testCreateConnection() {
         assertNotNull(ProxyFactory.instance().createConnection(stub));
     }
@@ -59,8 +63,4 @@ public class ProxyFactoryTest extends BaseTestCase {
         assertNotNull(ProxyFactory.instance().createStatement(stub));
     }
 
-    public void testCreateCallableStatement() {
-        assertNotNull(ProxyFactory.instance().createCallableStatement(stub));
-    }
-
 }
diff --git a/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java b/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java
index 985da7c..db130f5 100644
--- a/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java
@@ -54,9 +54,24 @@ import org.mockito.stubbing.Answer;
 @SuppressWarnings("boxing") // test code
 @RunWith(MockitoJUnitRunner.class)
 public class QueryRunnerTest {
+    //
+    // Random tests
+    //
+    class MyBean {
+        private int a;
+        private double b;
+        private String c;
+
+        public int getA() {    return a; }
+        public double getB() { return b; }
+        public String getC() { return c; }
+        public void setA(final int a) { this.a = a; }
+        public void setB(final double b) { this.b = b; }
+        public void setC(final String c) { this.c = c; }
+    }
     QueryRunner runner;
-    ArrayHandler handler;
 
+    ArrayHandler handler;
     @Mock DataSource dataSource;
     @Mock Connection conn;
     @Mock PreparedStatement prepStmt;
@@ -64,33 +79,71 @@ public class QueryRunnerTest {
     @Mock CallableStatement call;
     @Mock ParameterMetaData meta;
     @Mock ResultSet results;
+
     @Mock ResultSetMetaData resultsMeta;
 
-    @Before
-    public void setUp() throws Exception {
-        when(dataSource.getConnection()).thenReturn(conn);
+    //
+    // Batch test cases
+    //
 
-        when(conn.prepareStatement(any(String.class))).thenReturn(prepStmt);
-        when(prepStmt.getParameterMetaData()).thenReturn(meta);
-        when(prepStmt.executeQuery()).thenReturn(results);
+    // helper method for calling batch when an exception is expected
+    private void callBatchWithException(final String sql, final Object[][] params) throws Exception {
+        when(meta.getParameterCount()).thenReturn(2);
+        boolean caught = false;
 
-        when(conn.createStatement()).thenReturn(stmt);
-        when(stmt.executeQuery(any(String.class))).thenReturn(results);
+        try {
+            runner.batch(sql, params);
 
-        when(conn.prepareCall(any(String.class))).thenReturn(call);
-        when(call.getParameterMetaData()).thenReturn(meta);
-        when(call.getResultSet()).thenReturn(results);
-        when(call.getMoreResults()).thenReturn(false);
+            verify(prepStmt, times(1)).getParameterMetaData();
+            verify(prepStmt, times(2)).addBatch();
+            verify(prepStmt, times(1)).executeBatch();
+            verify(prepStmt, times(1)).close();    // make sure the statement is closed
+            verify(conn, times(1)).close();    // make sure the connection is closed
+        } catch (final SQLException e) {
+            System.out.println("[TEST] The following exception is expected:");
+            System.out.println(e);
+            caught = true;
+        }
 
-        when(results.next()).thenReturn(false);
+        if(!caught) {
+            fail("Exception never thrown, but expected");
+        }
+    }
 
-         handler = new ArrayHandler();
-         runner = new QueryRunner(dataSource);
+    // helper method for calling execute when an exception is expected
+    private void callExecuteWithException(final Object... params) throws Exception {
+        boolean caught = false;
+
+        try {
+            when(meta.getParameterCount()).thenReturn(2);
+            runner.query("{call my_proc(?, ?)}", handler, params);
+
+        } catch (final SQLException e) {
+            caught = true;
+        }
+
+        if(!caught) {
+            fail("Exception never thrown, but expected");
+        }
+    }
+
+    // helper method for calling execute when an exception is expected
+    private void callExecuteWithResultSetWithException(final Object... params) throws Exception {
+        boolean caught = false;
+
+        try {
+            when(meta.getParameterCount()).thenReturn(2);
+            runner.execute("{call my_proc(?, ?)}", handler, params);
+
+        } catch (final SQLException e) {
+            caught = true;
+        }
+
+        if(!caught) {
+            fail("Exception never thrown, but expected");
+        }
     }
 
-    //
-    // Batch test cases
-    //
 
     private void callGoodBatch(final Connection conn, final Object[][] params) throws Exception {
         when(meta.getParameterCount()).thenReturn(2);
@@ -118,117 +171,295 @@ public class QueryRunnerTest {
         verify(conn, times(1)).close();    // make sure we closed the connection
     }
 
+    private void callGoodExecute() throws Exception {
+        when(call.execute()).thenReturn(false);
+        when(call.getUpdateCount()).thenReturn(3);
 
-    @Test
-    public void testGoodBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+        when(meta.getParameterCount()).thenReturn(2);
+        int result = runner.execute("{call my_proc(?, ?)}", "unit", "test");
 
-        callGoodBatch(params);
-    }
+        Assert.assertEquals(3, result);
 
-    @Test
-    public void testGoodBatchPmdTrue() throws Exception {
-        runner = new QueryRunner(dataSource, true);
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+        verify(call, times(1)).execute();
+        verify(call, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(1)).close();    // make sure we do not close the connection
 
-        callGoodBatch(params, false);
-    }
+        // call the other variation of query
+        when(meta.getParameterCount()).thenReturn(0);
+        result = runner.execute("{call my_proc()}");
 
-    @Test
-    public void testGoodBatchDefaultConstructor() throws Exception {
-        runner = new QueryRunner();
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+        Assert.assertEquals(3, result);
 
-        callGoodBatch(conn, params);
-    }
+        verify(call, times(2)).execute();
+        verify(call, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(2)).close();    // make sure we do not close the connection
 
-    @Test
-    public void testNullParamsBatch() throws Exception {
-        final String[][] params = new String[][] { { null, "unit" }, { "test", null } };
+        // Test single OUT parameter
+        when(meta.getParameterCount()).thenReturn(1);
+        when(call.getObject(1)).thenReturn(42);
+        final OutParameter<Integer> intParam =
+            new OutParameter<>(Types.INTEGER, Integer.class);
+        result = runner.execute("{?= call my_proc()}", intParam);
 
-        callGoodBatch(params);
-    }
+        Assert.assertEquals(42, intParam.getValue().intValue());
+        Assert.assertEquals(3, result);
 
+        verify(call, times(3)).execute();
+        verify(call, times(3)).close();    // make sure we closed the statement
+        verify(conn, times(3)).close();    // make sure we do not close the connection
 
-    // helper method for calling batch when an exception is expected
-    private void callBatchWithException(final String sql, final Object[][] params) throws Exception {
-        when(meta.getParameterCount()).thenReturn(2);
-        boolean caught = false;
+        // Test OUT parameters with IN parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(4242);
+        intParam.setValue(null);
+        result = runner.execute("{?= call my_proc(?, ?)}", intParam, "unit", "test");
 
-        try {
-            runner.batch(sql, params);
+        Assert.assertEquals(4242, intParam.getValue().intValue());
+        Assert.assertEquals(3, result);
 
-            verify(prepStmt, times(1)).getParameterMetaData();
-            verify(prepStmt, times(2)).addBatch();
-            verify(prepStmt, times(1)).executeBatch();
-            verify(prepStmt, times(1)).close();    // make sure the statement is closed
-            verify(conn, times(1)).close();    // make sure the connection is closed
-        } catch (final SQLException e) {
-            System.out.println("[TEST] The following exception is expected:");
-            System.out.println(e);
-            caught = true;
-        }
+        verify(call, times(4)).execute();
+        verify(call, times(4)).close();    // make sure we closed the statement
+        verify(conn, times(4)).close();    // make sure we do not close the connection
 
-        if(!caught) {
-            fail("Exception never thrown, but expected");
-        }
-    }
+        // Test INOUT parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(24);
+        when(call.getObject(3)).thenReturn("out");
+        intParam.setValue(null);
+        final OutParameter<String> stringParam =
+            new OutParameter<>(Types.VARCHAR, String.class, "in");
+        result = runner.execute("{?= call my_proc(?, ?)}", intParam, "test", stringParam);
 
-    @Test
-    public void testTooFewParamsBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit" }, { "test" } };
+        Assert.assertEquals(24, intParam.getValue().intValue());
+        Assert.assertEquals("out", stringParam.getValue());
+        Assert.assertEquals(3, result);
 
-        callBatchWithException("select * from blah where ? = ?", params);
+        verify(call, times(5)).execute();
+        verify(call, times(5)).close();    // make sure we closed the statement
+        verify(conn, times(5)).close();    // make sure we do not close the connection
     }
 
-    @Test
-    public void testTooManyParamsBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit", "unit" }, { "test", "test", "test" } };
-
-        callBatchWithException("select * from blah where ? = ?", params);
-    }
 
-    @Test(expected=SQLException.class)
-    public void testNullConnectionBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+    //
+    // Execute tests
+    //
+    private void callGoodExecute(final Connection conn) throws Exception {
+        when(call.execute()).thenReturn(false);
+        when(call.getUpdateCount()).thenReturn(3);
 
-        when(dataSource.getConnection()).thenReturn(null);
+        when(meta.getParameterCount()).thenReturn(2);
+        int result = runner.execute(conn, "{call my_proc(?, ?)}", "unit", "test");
 
-        runner.batch("select * from blah where ? = ?", params);
-    }
+        Assert.assertEquals(3, result);
 
+        verify(call, times(1)).execute();
+        verify(call, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
 
-    @Test(expected=SQLException.class)
-    public void testNullSqlBatch() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+        // call the other variation of query
+        when(meta.getParameterCount()).thenReturn(0);
+        result = runner.execute(conn, "{call my_proc()}");
 
-        runner.batch(null, params);
-    }
+        Assert.assertEquals(3, result);
 
+        verify(call, times(2)).execute();
+        verify(call, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
 
-    @Test(expected=SQLException.class)
-    public void testNullParamsArgBatch() throws Exception {
-        runner.batch("select * from blah where ? = ?", null);
-    }
+        // Test single OUT parameter
+        when(meta.getParameterCount()).thenReturn(1);
+        when(call.getObject(1)).thenReturn(42);
+        final OutParameter<Integer> intParam =
+            new OutParameter<>(Types.INTEGER, Integer.class);
+        result = runner.execute(conn, "{?= call my_proc()}", intParam);
 
-    @Test
-    public void testAddBatchExceptionOnAdd() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+        Assert.assertEquals(42, intParam.getValue().intValue());
+        Assert.assertEquals(3, result);
 
-        doThrow(new SQLException()).when(prepStmt).addBatch();
+        verify(call, times(3)).execute();
+        verify(call, times(3)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
 
-        callBatchWithException("select * from blah where ? = ?", params);
-    }
+        // Test OUT parameters with IN parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(4242);
+        intParam.setValue(null);
+        result = runner.execute(conn, "{?= call my_proc(?, ?)}", intParam, "unit", "test");
 
-    @Test
-    public void testExecuteBatchExceptionOnExec() throws Exception {
-        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+        Assert.assertEquals(4242, intParam.getValue().intValue());
+        Assert.assertEquals(3, result);
 
-        doThrow(new SQLException()).when(prepStmt).executeBatch();
+        verify(call, times(4)).execute();
+        verify(call, times(4)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
 
-        callBatchWithException("select * from blah where ? = ?", params);
+        // Test INOUT parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(24);
+        when(call.getObject(3)).thenReturn("out");
+        intParam.setValue(null);
+        final OutParameter<String> stringParam =
+            new OutParameter<>(Types.VARCHAR, String.class, "in");
+        result = runner.execute(conn, "{?= call my_proc(?, ?)}", intParam, "test", stringParam);
+
+        Assert.assertEquals(24, intParam.getValue().intValue());
+        Assert.assertEquals("out", stringParam.getValue());
+        Assert.assertEquals(3, result);
+
+        verify(call, times(5)).execute();
+        verify(call, times(5)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
+    }
+
+    private void callGoodExecuteWithResultSet() throws Exception {
+        when(call.execute()).thenReturn(true);
+
+        when(meta.getParameterCount()).thenReturn(2);
+        runner.execute("{call my_proc(?, ?)}", handler, "unit", "test");
+
+        verify(call, times(1)).execute();
+        verify(results, times(1)).close();
+        verify(call, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(1)).close();    // make sure we do not close the connection
+
+        // call the other variation of query
+        when(meta.getParameterCount()).thenReturn(0);
+        runner.execute("{call my_proc()}", handler);
+
+        verify(call, times(2)).execute();
+        verify(results, times(2)).close();
+        verify(call, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(2)).close();    // make sure we do not close the connection
+
+        // Test single OUT parameter
+        when(meta.getParameterCount()).thenReturn(1);
+        when(call.getObject(1)).thenReturn(42);
+        final OutParameter<Integer> intParam =
+            new OutParameter<>(Types.INTEGER, Integer.class);
+        runner.execute("{?= call my_proc()}", handler, intParam);
+
+        Assert.assertEquals(42, intParam.getValue().intValue());
+
+        verify(call, times(3)).execute();
+        verify(results, times(3)).close();
+        verify(call, times(3)).close();    // make sure we closed the statement
+        verify(conn, times(3)).close();    // make sure we do not close the connection
+
+        // Test OUT parameters with IN parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(4242);
+        intParam.setValue(null);
+        runner.execute("{?= call my_proc(?, ?)}", handler, intParam, "unit", "test");
+
+        Assert.assertEquals(4242, intParam.getValue().intValue());
+
+        verify(call, times(4)).execute();
+        verify(results, times(4)).close();
+        verify(call, times(4)).close();    // make sure we closed the statement
+        verify(conn, times(4)).close();    // make sure we do not close the connection
+
+        // Test INOUT parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(24);
+        when(call.getObject(3)).thenReturn("out");
+        intParam.setValue(null);
+        final OutParameter<String> stringParam =
+            new OutParameter<>(Types.VARCHAR, String.class, "in");
+        runner.execute("{?= call my_proc(?, ?)}", handler, intParam, "test", stringParam);
+
+        Assert.assertEquals(24, intParam.getValue().intValue());
+        Assert.assertEquals("out", stringParam.getValue());
+
+        verify(call, times(5)).execute();
+        verify(results, times(5)).close();
+        verify(call, times(5)).close();    // make sure we closed the statement
+        verify(conn, times(5)).close();    // make sure we do not close the connection
+    }
+
+    private void callGoodExecuteWithResultSet(final Connection conn) throws Exception {
+        when(call.execute()).thenReturn(true);
+
+        when(meta.getParameterCount()).thenReturn(2);
+        runner.execute(conn, "{call my_proc(?, ?)}", handler, "unit", "test");
+
+        verify(call, times(1)).execute();
+        verify(results, times(1)).close();
+        verify(call, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
+
+        // call the other variation of query
+        when(meta.getParameterCount()).thenReturn(0);
+        runner.execute(conn, "{call my_proc()}", handler);
+
+        verify(call, times(2)).execute();
+        verify(results, times(2)).close();
+        verify(call, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
+
+        // Test single OUT parameter
+        when(meta.getParameterCount()).thenReturn(1);
+        when(call.getObject(1)).thenReturn(42);
+        final OutParameter<Integer> intParam =
+            new OutParameter<>(Types.INTEGER, Integer.class);
+        runner.execute(conn, "{?= call my_proc()}", handler, intParam);
+
+        Assert.assertEquals(42, intParam.getValue().intValue());
+
+        verify(call, times(3)).execute();
+        verify(results, times(3)).close();
+        verify(call, times(3)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
+
+        // Test OUT parameters with IN parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(4242);
+        intParam.setValue(null);
+        runner.execute(conn, "{?= call my_proc(?, ?)}", handler, intParam, "unit", "test");
+
+        Assert.assertEquals(4242, intParam.getValue().intValue());
+
+        verify(call, times(4)).execute();
+        verify(results, times(4)).close();
+        verify(call, times(4)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
+
+        // Test INOUT parameters
+        when(meta.getParameterCount()).thenReturn(3);
+        when(call.getObject(1)).thenReturn(24);
+        when(call.getObject(3)).thenReturn("out");
+        intParam.setValue(null);
+        final OutParameter<String> stringParam =
+            new OutParameter<>(Types.VARCHAR, String.class, "in");
+        runner.execute(conn, "{?= call my_proc(?, ?)}", handler, intParam, "test", stringParam);
+
+        Assert.assertEquals(24, intParam.getValue().intValue());
+        Assert.assertEquals("out", stringParam.getValue());
+
+        verify(call, times(5)).execute();
+        verify(results, times(5)).close();
+        verify(call, times(5)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection
     }
 
+    private void callGoodQuery() throws Exception {
+        when(meta.getParameterCount()).thenReturn(2);
+        String sql = "select * from blah where ? = ?";
+        runner.query(sql, handler, "unit", "test");
+
+        verify(prepStmt, times(1)).executeQuery();
+        verify(results, times(1)).close();
+        verify(prepStmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(1)).close();    // make sure we closed the connection
+
+        // call the other variation of query
+        sql = "select * from blah";
+        runner.query(sql, handler);
+
+        verify(stmt, times(1)).executeQuery(sql);
+        verify(results, times(2)).close();
+        verify(stmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(2)).close();    // make sure we closed the connection
+    }
 
 
     //
@@ -254,43 +485,63 @@ public class QueryRunnerTest {
         verify(conn, times(0)).close();    // make sure we do not close the connection, see above
     }
 
-    private void callGoodQuery() throws Exception {
+
+    private void callGoodUpdate() throws Exception {
         when(meta.getParameterCount()).thenReturn(2);
-        String sql = "select * from blah where ? = ?";
-        runner.query(sql, handler, "unit", "test");
+        String sql = "update blah set ? = ?";
+        runner.update(sql, "unit", "test");
 
-        verify(prepStmt, times(1)).executeQuery();
-        verify(results, times(1)).close();
+        verify(prepStmt, times(1)).executeUpdate();
         verify(prepStmt, times(1)).close();    // make sure we closed the statement
         verify(conn, times(1)).close();    // make sure we closed the connection
 
-        // call the other variation of query
-        sql = "select * from blah";
-        runner.query(sql, handler);
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(0);
+        sql = "update blah set unit = test";
+        runner.update(sql);
 
-        verify(stmt, times(1)).executeQuery(sql);
-        verify(results, times(2)).close();
+        verify(stmt, times(1)).executeUpdate(sql);
         verify(stmt, times(1)).close();    // make sure we closed the statement
         verify(conn, times(2)).close();    // make sure we closed the connection
-    }
 
-    @Test
-    public void testGoodQuery() throws Exception {
-        callGoodQuery();
-    }
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(1);
+        sql = "update blah set unit = ?";
+        runner.update(sql, "test");
 
-    @Test
-    public void testGoodQueryPmdTrue() throws Exception {
-        runner = new QueryRunner(true);
-        callGoodQuery(conn);
+        verify(prepStmt, times(2)).executeUpdate();
+        verify(prepStmt, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(3)).close();    // make sure we closed the connection
     }
 
-    @Test
-    public void testGoodQueryDefaultConstructor() throws Exception {
-        runner = new QueryRunner();
-        callGoodQuery(conn);
-    }
+    //
+    // Update test cases
+    //
+    private void callGoodUpdate(final Connection conn) throws Exception {
+        when(meta.getParameterCount()).thenReturn(2);
+        runner.update(conn, "update blah set ? = ?", "unit", "test");
+
+        verify(prepStmt, times(1)).executeUpdate();
+        verify(prepStmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection, since QueryRunner.update(Connection, String, Object...) does not close connections
+
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(0);
+        final String sql = "update blah set unit = test";
+        runner.update(conn, sql);
+
+        verify(stmt, times(1)).executeUpdate(sql);
+        verify(stmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection, see above
+
+        // call the other variation
+        when(meta.getParameterCount()).thenReturn(1);
+        runner.update(conn, "update blah set unit = ?", "test");
 
+        verify(prepStmt, times(2)).executeUpdate();
+        verify(prepStmt, times(2)).close();    // make sure we closed the statement
+        verify(conn, times(0)).close();    // make sure we do not close the connection, see above
+    }
 
     // helper method for calling batch when an exception is expected
     private void callQueryWithException(final Object... params) throws Exception {
@@ -315,135 +566,148 @@ public class QueryRunnerTest {
         }
     }
 
-    @Test
-    public void testNoParamsQuery() throws Exception {
-        callGoodQuery();
-    }
-
-    @Test
-    public void testTooFewParamsQuery() throws Exception {
-        callQueryWithException("unit");
-    }
 
-    @Test
-    public void testTooManyParamsQuery() throws Exception {
-        callQueryWithException("unit", "test", "fail");
-    }
 
-    @Test(expected=SQLException.class)
-    public void testNullConnectionQuery() throws Exception {
-        when(dataSource.getConnection()).thenReturn(null);
+    // helper method for calling batch when an exception is expected
+    private void callUpdateWithException(final Object... params) throws Exception {
+        boolean caught = false;
 
-        runner.query("select * from blah where ? = ?", handler, "unit", "test");
-    }
+        try {
+            when(meta.getParameterCount()).thenReturn(2);
+            final String sql = "select * from blah where ? = ?";
+            runner.update(sql, params);
 
-    @Test(expected=SQLException.class)
-    public void testNullSqlQuery() throws Exception {
-        runner.query(null, handler);
+            verify(prepStmt, times(1)).executeUpdate();
+            verify(prepStmt, times(1)).close();    // make sure we closed the statement
+            verify(conn, times(1)).close();    // make sure we closed the connection
+        } catch (final SQLException e) {
+            caught = true;
+        }
+
+        if(!caught) {
+            fail("Exception never thrown, but expected");
+        }
     }
 
-    @Test(expected=SQLException.class)
-    public void testNullHandlerQuery() throws Exception {
-        runner.query("select * from blah where ? = ?", null);
+    @Before
+    public void setUp() throws Exception {
+        when(dataSource.getConnection()).thenReturn(conn);
+
+        when(conn.prepareStatement(any(String.class))).thenReturn(prepStmt);
+        when(prepStmt.getParameterMetaData()).thenReturn(meta);
+        when(prepStmt.executeQuery()).thenReturn(results);
+
+        when(conn.createStatement()).thenReturn(stmt);
+        when(stmt.executeQuery(any(String.class))).thenReturn(results);
+
+        when(conn.prepareCall(any(String.class))).thenReturn(call);
+        when(call.getParameterMetaData()).thenReturn(meta);
+        when(call.getResultSet()).thenReturn(results);
+        when(call.getMoreResults()).thenReturn(false);
+
+        when(results.next()).thenReturn(false);
+
+         handler = new ArrayHandler();
+         runner = new QueryRunner(dataSource);
     }
 
     @Test
-    public void testExecuteQueryException() throws Exception {
-        callQueryWithException(handler, "unit", "test");
+    public void testAddBatchExceptionOnAdd() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+
+        doThrow(new SQLException()).when(prepStmt).addBatch();
+
+        callBatchWithException("select * from blah where ? = ?", params);
     }
 
+    @Test(expected=SQLException.class)
+    public void testBadPrepareConnection() throws Exception {
+        runner = new QueryRunner();
+        runner.update("update blah set unit = test");
+    }
 
-    //
-    // Update test cases
-    //
-    private void callGoodUpdate(final Connection conn) throws Exception {
-        when(meta.getParameterCount()).thenReturn(2);
-        runner.update(conn, "update blah set ? = ?", "unit", "test");
+    @Test
+    public void testExecuteBatchExceptionOnExec() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        verify(prepStmt, times(1)).executeUpdate();
-        verify(prepStmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection, since QueryRunner.update(Connection, String, Object...) does not close connections
+        doThrow(new SQLException()).when(prepStmt).executeBatch();
 
-        // call the other variation
-        when(meta.getParameterCount()).thenReturn(0);
-        final String sql = "update blah set unit = test";
-        runner.update(conn, sql);
+        callBatchWithException("select * from blah where ? = ?", params);
+    }
 
-        verify(stmt, times(1)).executeUpdate(sql);
-        verify(stmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection, see above
 
-        // call the other variation
-        when(meta.getParameterCount()).thenReturn(1);
-        runner.update(conn, "update blah set unit = ?", "test");
+    @Test
+    public void testExecuteException() throws Exception {
+        callExecuteWithException(handler, "unit", "test");
+    }
 
-        verify(prepStmt, times(2)).executeUpdate();
-        verify(prepStmt, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection, see above
+    @Test
+    public void testExecuteQueryException() throws Exception {
+        callQueryWithException(handler, "unit", "test");
     }
 
-    private void callGoodUpdate() throws Exception {
-        when(meta.getParameterCount()).thenReturn(2);
-        String sql = "update blah set ? = ?";
-        runner.update(sql, "unit", "test");
+    @Test
+    public void testExecuteUpdateException() throws Exception {
+        doThrow(new SQLException()).when(prepStmt).executeUpdate();
 
-        verify(prepStmt, times(1)).executeUpdate();
-        verify(prepStmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(1)).close();    // make sure we closed the connection
+        callUpdateWithException("unit", "test");
+    }
 
-        // call the other variation
+    @Test
+    public void testExecuteWithMultipleResultSets() throws Exception {
+        when(call.execute()).thenReturn(true);
+        when(call.getMoreResults()).thenAnswer(new Answer<Boolean>()
+        {
+            int count = 1;
+            @Override
+            public Boolean answer(final InvocationOnMock invocation)
+            {
+                return ++count <= 3;
+            }
+        });
         when(meta.getParameterCount()).thenReturn(0);
-        sql = "update blah set unit = test";
-        runner.update(sql);
-
-        verify(stmt, times(1)).executeUpdate(sql);
-        verify(stmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(2)).close();    // make sure we closed the connection
+        final List<Object[]> objects = runner.execute("{call my_proc()}", handler);
 
-        // call the other variation
-        when(meta.getParameterCount()).thenReturn(1);
-        sql = "update blah set unit = ?";
-        runner.update(sql, "test");
+        Assert.assertEquals(3, objects.size());
+        verify(call, times(1)).execute();
+        verify(results, times(3)).close();
+        verify(call, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(1)).close();    // make sure we close the connection
 
-        verify(prepStmt, times(2)).executeUpdate();
-        verify(prepStmt, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(3)).close();    // make sure we closed the connection
     }
 
     @Test
-    public void testGoodUpdate() throws Exception {
-        callGoodUpdate();
+    public void testExecuteWithResultSetException() throws Exception {
+        callExecuteWithResultSetWithException(handler, "unit", "test");
     }
 
     @Test
-    public void testGoodUpdatePmdTrue() throws Exception {
-        runner = new QueryRunner(true);
-        callGoodUpdate(conn);
+    public void testFillStatementWithBean() throws Exception {
+        final MyBean bean = new MyBean();
+        when(meta.getParameterCount()).thenReturn(3);
+        runner.fillStatementWithBean(prepStmt, bean, "a", "b", "c");
     }
 
-    @Test
-    public void testGoodUpdateDefaultConstructor() throws Exception {
-        runner = new QueryRunner();
-        callGoodUpdate(conn);
+    @Test(expected=NullPointerException.class)
+    public void testFillStatementWithBeanNullNames() throws Exception {
+        final MyBean bean = new MyBean();
+        runner.fillStatementWithBean(prepStmt, bean, "a", "b", null);
     }
 
     @Test
-    public void testGoodInsert() throws Exception {
-        results = mock(ResultSet.class);
+    public void testGoodBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        when(meta.getParameterCount()).thenReturn(2);
-        when(conn.prepareStatement(any(String.class), eq(Statement.RETURN_GENERATED_KEYS))).thenReturn(prepStmt);
-        when(prepStmt.getGeneratedKeys()).thenReturn(results);
-        when(results.next()).thenReturn(true).thenReturn(false);
-        when(results.getObject(1)).thenReturn(1L);
+        callGoodBatch(params);
+    }
 
-        final Long generatedKey = runner.insert("INSERT INTO blah(col1, col2) VALUES(?,?)", new ScalarHandler<Long>(), "unit", "test");
 
-        verify(prepStmt, times(1)).executeUpdate();
-        verify(prepStmt, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(1)).close();    // make sure we closed the connection
+    @Test
+    public void testGoodBatchDefaultConstructor() throws Exception {
+        runner = new QueryRunner();
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        Assert.assertEquals(1L, generatedKey.longValue());
+        callGoodBatch(conn, params);
     }
 
     @Test
@@ -486,260 +750,128 @@ public class QueryRunnerTest {
         Assert.assertEquals(2, generatedKeys.size());
     }
 
-    // helper method for calling batch when an exception is expected
-    private void callUpdateWithException(final Object... params) throws Exception {
-        boolean caught = false;
-
-        try {
-            when(meta.getParameterCount()).thenReturn(2);
-            final String sql = "select * from blah where ? = ?";
-            runner.update(sql, params);
-
-            verify(prepStmt, times(1)).executeUpdate();
-            verify(prepStmt, times(1)).close();    // make sure we closed the statement
-            verify(conn, times(1)).close();    // make sure we closed the connection
-        } catch (final SQLException e) {
-            caught = true;
-        }
+    @Test
+    public void testGoodBatchPmdTrue() throws Exception {
+        runner = new QueryRunner(dataSource, true);
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        if(!caught) {
-            fail("Exception never thrown, but expected");
-        }
+        callGoodBatch(params, false);
     }
 
     @Test
-    public void testNoParamsUpdate() throws Exception {
-        callGoodUpdate();
+    public void testGoodExecute() throws Exception {
+        callGoodExecute();
     }
 
     @Test
-    public void testTooFewParamsUpdate() throws Exception {
-        callUpdateWithException("unit");
+    public void testGoodExecuteDefaultConstructor() throws Exception {
+        runner = new QueryRunner();
+        callGoodExecute(conn);
     }
 
     @Test
-    public void testTooManyParamsUpdate() throws Exception {
-        callUpdateWithException("unit", "test", "fail");
+    public void testGoodExecutePmdTrue() throws Exception {
+        runner = new QueryRunner(true);
+        callGoodExecute(conn);
     }
 
-    @Test(expected=SQLException.class)
-    public void testNullConnectionUpdate() throws Exception {
-        when(dataSource.getConnection()).thenReturn(null);
+    @Test
+    public void testGoodExecuteWithResultSet() throws Exception {
+        callGoodExecuteWithResultSet();
+    }
 
-        runner.update("select * from blah where ? = ?", "unit", "test");
+    @Test
+    public void testGoodExecuteWithResultSetDefaultConstructor() throws Exception {
+        runner = new QueryRunner();
+        callGoodExecuteWithResultSet(conn);
     }
 
-    @Test(expected=SQLException.class)
-    public void testNullSqlUpdate() throws Exception {
-        runner.update(null);
+    @Test
+    public void testGoodExecuteWithResultSetPmdTrue() throws Exception {
+        runner = new QueryRunner(true);
+        callGoodExecuteWithResultSet(conn);
     }
 
     @Test
-    public void testExecuteUpdateException() throws Exception {
-        doThrow(new SQLException()).when(prepStmt).executeUpdate();
+    public void testGoodInsert() throws Exception {
+        results = mock(ResultSet.class);
 
-        callUpdateWithException("unit", "test");
+        when(meta.getParameterCount()).thenReturn(2);
+        when(conn.prepareStatement(any(String.class), eq(Statement.RETURN_GENERATED_KEYS))).thenReturn(prepStmt);
+        when(prepStmt.getGeneratedKeys()).thenReturn(results);
+        when(results.next()).thenReturn(true).thenReturn(false);
+        when(results.getObject(1)).thenReturn(1L);
+
+        final Long generatedKey = runner.insert("INSERT INTO blah(col1, col2) VALUES(?,?)", new ScalarHandler<Long>(), "unit", "test");
+
+        verify(prepStmt, times(1)).executeUpdate();
+        verify(prepStmt, times(1)).close();    // make sure we closed the statement
+        verify(conn, times(1)).close();    // make sure we closed the connection
+
+        Assert.assertEquals(1L, generatedKey.longValue());
     }
 
     @Test
-    public void testStatementConfiguration() throws Exception {
-        final StatementConfiguration stmtConfig = new StatementConfiguration(1, 2, 3, 4, 5);
-        final QueryRunner queryRunner = new QueryRunner(stmtConfig);
-        queryRunner.prepareStatement(conn, "select 1");
+    public void testGoodQuery() throws Exception {
+        callGoodQuery();
+    }
 
-        verify(prepStmt).setFetchDirection(eq(1));
-        verify(prepStmt).setFetchSize(eq(2));
-        verify(prepStmt).setMaxFieldSize(eq(3));
-        verify(prepStmt).setMaxRows(eq(4));
-        verify(prepStmt).setQueryTimeout(eq(5));
+    @Test
+    public void testGoodQueryDefaultConstructor() throws Exception {
+        runner = new QueryRunner();
+        callGoodQuery(conn);
     }
 
-    //
-    // Execute tests
-    //
-    private void callGoodExecute(final Connection conn) throws Exception {
-        when(call.execute()).thenReturn(false);
-        when(call.getUpdateCount()).thenReturn(3);
-
-        when(meta.getParameterCount()).thenReturn(2);
-        int result = runner.execute(conn, "{call my_proc(?, ?)}", "unit", "test");
-
-        Assert.assertEquals(3, result);
-
-        verify(call, times(1)).execute();
-        verify(call, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // call the other variation of query
-        when(meta.getParameterCount()).thenReturn(0);
-        result = runner.execute(conn, "{call my_proc()}");
-
-        Assert.assertEquals(3, result);
-
-        verify(call, times(2)).execute();
-        verify(call, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // Test single OUT parameter
-        when(meta.getParameterCount()).thenReturn(1);
-        when(call.getObject(1)).thenReturn(42);
-        final OutParameter<Integer> intParam =
-            new OutParameter<>(Types.INTEGER, Integer.class);
-        result = runner.execute(conn, "{?= call my_proc()}", intParam);
-
-        Assert.assertEquals(42, intParam.getValue().intValue());
-        Assert.assertEquals(3, result);
-
-        verify(call, times(3)).execute();
-        verify(call, times(3)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // Test OUT parameters with IN parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(4242);
-        intParam.setValue(null);
-        result = runner.execute(conn, "{?= call my_proc(?, ?)}", intParam, "unit", "test");
-
-        Assert.assertEquals(4242, intParam.getValue().intValue());
-        Assert.assertEquals(3, result);
-
-        verify(call, times(4)).execute();
-        verify(call, times(4)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // Test INOUT parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(24);
-        when(call.getObject(3)).thenReturn("out");
-        intParam.setValue(null);
-        final OutParameter<String> stringParam =
-            new OutParameter<>(Types.VARCHAR, String.class, "in");
-        result = runner.execute(conn, "{?= call my_proc(?, ?)}", intParam, "test", stringParam);
-
-        Assert.assertEquals(24, intParam.getValue().intValue());
-        Assert.assertEquals("out", stringParam.getValue());
-        Assert.assertEquals(3, result);
-
-        verify(call, times(5)).execute();
-        verify(call, times(5)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
+    @Test
+    public void testGoodQueryPmdTrue() throws Exception {
+        runner = new QueryRunner(true);
+        callGoodQuery(conn);
     }
 
-    private void callGoodExecute() throws Exception {
-        when(call.execute()).thenReturn(false);
-        when(call.getUpdateCount()).thenReturn(3);
-
-        when(meta.getParameterCount()).thenReturn(2);
-        int result = runner.execute("{call my_proc(?, ?)}", "unit", "test");
-
-        Assert.assertEquals(3, result);
-
-        verify(call, times(1)).execute();
-        verify(call, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(1)).close();    // make sure we do not close the connection
-
-        // call the other variation of query
-        when(meta.getParameterCount()).thenReturn(0);
-        result = runner.execute("{call my_proc()}");
-
-        Assert.assertEquals(3, result);
-
-        verify(call, times(2)).execute();
-        verify(call, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(2)).close();    // make sure we do not close the connection
-
-        // Test single OUT parameter
-        when(meta.getParameterCount()).thenReturn(1);
-        when(call.getObject(1)).thenReturn(42);
-        final OutParameter<Integer> intParam =
-            new OutParameter<>(Types.INTEGER, Integer.class);
-        result = runner.execute("{?= call my_proc()}", intParam);
-
-        Assert.assertEquals(42, intParam.getValue().intValue());
-        Assert.assertEquals(3, result);
-
-        verify(call, times(3)).execute();
-        verify(call, times(3)).close();    // make sure we closed the statement
-        verify(conn, times(3)).close();    // make sure we do not close the connection
-
-        // Test OUT parameters with IN parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(4242);
-        intParam.setValue(null);
-        result = runner.execute("{?= call my_proc(?, ?)}", intParam, "unit", "test");
-
-        Assert.assertEquals(4242, intParam.getValue().intValue());
-        Assert.assertEquals(3, result);
-
-        verify(call, times(4)).execute();
-        verify(call, times(4)).close();    // make sure we closed the statement
-        verify(conn, times(4)).close();    // make sure we do not close the connection
-
-        // Test INOUT parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(24);
-        when(call.getObject(3)).thenReturn("out");
-        intParam.setValue(null);
-        final OutParameter<String> stringParam =
-            new OutParameter<>(Types.VARCHAR, String.class, "in");
-        result = runner.execute("{?= call my_proc(?, ?)}", intParam, "test", stringParam);
-
-        Assert.assertEquals(24, intParam.getValue().intValue());
-        Assert.assertEquals("out", stringParam.getValue());
-        Assert.assertEquals(3, result);
-
-        verify(call, times(5)).execute();
-        verify(call, times(5)).close();    // make sure we closed the statement
-        verify(conn, times(5)).close();    // make sure we do not close the connection
+    @Test
+    public void testGoodUpdate() throws Exception {
+        callGoodUpdate();
     }
 
     @Test
-    public void testGoodExecute() throws Exception {
-        callGoodExecute();
+    public void testGoodUpdateDefaultConstructor() throws Exception {
+        runner = new QueryRunner();
+        callGoodUpdate(conn);
     }
 
     @Test
-    public void testGoodExecutePmdTrue() throws Exception {
+    public void testGoodUpdatePmdTrue() throws Exception {
         runner = new QueryRunner(true);
-        callGoodExecute(conn);
+        callGoodUpdate(conn);
     }
 
     @Test
-    public void testGoodExecuteDefaultConstructor() throws Exception {
-        runner = new QueryRunner();
-        callGoodExecute(conn);
+    public void testNoParamsExecute() throws Exception {
+        callGoodExecute();
     }
 
-    // helper method for calling execute when an exception is expected
-    private void callExecuteWithException(final Object... params) throws Exception {
-        boolean caught = false;
-
-        try {
-            when(meta.getParameterCount()).thenReturn(2);
-            runner.query("{call my_proc(?, ?)}", handler, params);
-
-        } catch (final SQLException e) {
-            caught = true;
-        }
-
-        if(!caught) {
-            fail("Exception never thrown, but expected");
-        }
+    @Test
+    public void testNoParamsExecuteWithResultSet() throws Exception {
+        callExecuteWithResultSetWithException();
     }
 
     @Test
-    public void testNoParamsExecute() throws Exception {
-        callGoodExecute();
+    public void testNoParamsQuery() throws Exception {
+        callGoodQuery();
     }
 
     @Test
-    public void testTooFewParamsExecute() throws Exception {
-        callExecuteWithException("unit");
+    public void testNoParamsUpdate() throws Exception {
+        callGoodUpdate();
     }
 
-    @Test
-    public void testTooManyParamsExecute() throws Exception {
-        callExecuteWithException("unit", "test", "fail");
+    @Test(expected=SQLException.class)
+    public void testNullConnectionBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
+
+        when(dataSource.getConnection()).thenReturn(null);
+
+        runner.batch("select * from blah where ? = ?", params);
     }
 
     @Test(expected=SQLException.class)
@@ -750,8 +882,24 @@ public class QueryRunnerTest {
     }
 
     @Test(expected=SQLException.class)
-    public void testNullSqlExecute() throws Exception {
-        runner.execute(null);
+    public void testNullConnectionExecuteWithResultSet() throws Exception {
+        when(dataSource.getConnection()).thenReturn(null);
+
+        runner.execute("{call my_proc(?, ?)}", handler, "unit", "test");
+    }
+
+    @Test(expected=SQLException.class)
+    public void testNullConnectionQuery() throws Exception {
+        when(dataSource.getConnection()).thenReturn(null);
+
+        runner.query("select * from blah where ? = ?", handler, "unit", "test");
+    }
+
+    @Test(expected=SQLException.class)
+    public void testNullConnectionUpdate() throws Exception {
+        when(dataSource.getConnection()).thenReturn(null);
+
+        runner.update("select * from blah where ? = ?", "unit", "test");
     }
 
     @Test(expected=SQLException.class)
@@ -761,205 +909,82 @@ public class QueryRunnerTest {
         runner.execute("{call my_proc(?, ?)}");
     }
 
-    @Test
-    public void testExecuteException() throws Exception {
-        callExecuteWithException(handler, "unit", "test");
+    @Test(expected=SQLException.class)
+    public void testNullHandlerExecuteWithResultSet() throws Exception {
+        runner.execute("{call my_proc(?, ?)}", (ResultSetHandler)null);
+    }
+
+    @Test(expected=SQLException.class)
+    public void testNullHandlerQuery() throws Exception {
+        runner.query("select * from blah where ? = ?", null);
     }
 
     //
     // Execute with ResultSetHandler
     //
 
-    @Test
-    public void testExecuteWithMultipleResultSets() throws Exception {
-        when(call.execute()).thenReturn(true);
-        when(call.getMoreResults()).thenAnswer(new Answer<Boolean>()
-        {
-            int count = 1;
-            @Override
-            public Boolean answer(final InvocationOnMock invocation)
-            {
-                return ++count <= 3;
-            }
-        });
-        when(meta.getParameterCount()).thenReturn(0);
-        final List<Object[]> objects = runner.execute("{call my_proc()}", handler);
-
-        Assert.assertEquals(3, objects.size());
-        verify(call, times(1)).execute();
-        verify(results, times(3)).close();
-        verify(call, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(1)).close();    // make sure we close the connection
-
+    @Test(expected=SQLException.class)
+    public void testNullParamsArgBatch() throws Exception {
+        runner.batch("select * from blah where ? = ?", null);
     }
 
-    private void callGoodExecuteWithResultSet(final Connection conn) throws Exception {
-        when(call.execute()).thenReturn(true);
-
-        when(meta.getParameterCount()).thenReturn(2);
-        runner.execute(conn, "{call my_proc(?, ?)}", handler, "unit", "test");
-
-        verify(call, times(1)).execute();
-        verify(results, times(1)).close();
-        verify(call, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // call the other variation of query
-        when(meta.getParameterCount()).thenReturn(0);
-        runner.execute(conn, "{call my_proc()}", handler);
-
-        verify(call, times(2)).execute();
-        verify(results, times(2)).close();
-        verify(call, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // Test single OUT parameter
-        when(meta.getParameterCount()).thenReturn(1);
-        when(call.getObject(1)).thenReturn(42);
-        final OutParameter<Integer> intParam =
-            new OutParameter<>(Types.INTEGER, Integer.class);
-        runner.execute(conn, "{?= call my_proc()}", handler, intParam);
-
-        Assert.assertEquals(42, intParam.getValue().intValue());
-
-        verify(call, times(3)).execute();
-        verify(results, times(3)).close();
-        verify(call, times(3)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // Test OUT parameters with IN parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(4242);
-        intParam.setValue(null);
-        runner.execute(conn, "{?= call my_proc(?, ?)}", handler, intParam, "unit", "test");
-
-        Assert.assertEquals(4242, intParam.getValue().intValue());
-
-        verify(call, times(4)).execute();
-        verify(results, times(4)).close();
-        verify(call, times(4)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
-
-        // Test INOUT parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(24);
-        when(call.getObject(3)).thenReturn("out");
-        intParam.setValue(null);
-        final OutParameter<String> stringParam =
-            new OutParameter<>(Types.VARCHAR, String.class, "in");
-        runner.execute(conn, "{?= call my_proc(?, ?)}", handler, intParam, "test", stringParam);
-
-        Assert.assertEquals(24, intParam.getValue().intValue());
-        Assert.assertEquals("out", stringParam.getValue());
+    @Test
+    public void testNullParamsBatch() throws Exception {
+        final String[][] params = new String[][] { { null, "unit" }, { "test", null } };
 
-        verify(call, times(5)).execute();
-        verify(results, times(5)).close();
-        verify(call, times(5)).close();    // make sure we closed the statement
-        verify(conn, times(0)).close();    // make sure we do not close the connection
+        callGoodBatch(params);
     }
 
-    private void callGoodExecuteWithResultSet() throws Exception {
-        when(call.execute()).thenReturn(true);
-
-        when(meta.getParameterCount()).thenReturn(2);
-        runner.execute("{call my_proc(?, ?)}", handler, "unit", "test");
-
-        verify(call, times(1)).execute();
-        verify(results, times(1)).close();
-        verify(call, times(1)).close();    // make sure we closed the statement
-        verify(conn, times(1)).close();    // make sure we do not close the connection
-
-        // call the other variation of query
-        when(meta.getParameterCount()).thenReturn(0);
-        runner.execute("{call my_proc()}", handler);
-
-        verify(call, times(2)).execute();
-        verify(results, times(2)).close();
-        verify(call, times(2)).close();    // make sure we closed the statement
-        verify(conn, times(2)).close();    // make sure we do not close the connection
-
-        // Test single OUT parameter
-        when(meta.getParameterCount()).thenReturn(1);
-        when(call.getObject(1)).thenReturn(42);
-        final OutParameter<Integer> intParam =
-            new OutParameter<>(Types.INTEGER, Integer.class);
-        runner.execute("{?= call my_proc()}", handler, intParam);
-
-        Assert.assertEquals(42, intParam.getValue().intValue());
-
-        verify(call, times(3)).execute();
-        verify(results, times(3)).close();
-        verify(call, times(3)).close();    // make sure we closed the statement
-        verify(conn, times(3)).close();    // make sure we do not close the connection
-
-        // Test OUT parameters with IN parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(4242);
-        intParam.setValue(null);
-        runner.execute("{?= call my_proc(?, ?)}", handler, intParam, "unit", "test");
-
-        Assert.assertEquals(4242, intParam.getValue().intValue());
-
-        verify(call, times(4)).execute();
-        verify(results, times(4)).close();
-        verify(call, times(4)).close();    // make sure we closed the statement
-        verify(conn, times(4)).close();    // make sure we do not close the connection
-
-        // Test INOUT parameters
-        when(meta.getParameterCount()).thenReturn(3);
-        when(call.getObject(1)).thenReturn(24);
-        when(call.getObject(3)).thenReturn("out");
-        intParam.setValue(null);
-        final OutParameter<String> stringParam =
-            new OutParameter<>(Types.VARCHAR, String.class, "in");
-        runner.execute("{?= call my_proc(?, ?)}", handler, intParam, "test", stringParam);
+    @Test(expected=SQLException.class)
+    public void testNullSqlBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit" }, { "test", "test" } };
 
-        Assert.assertEquals(24, intParam.getValue().intValue());
-        Assert.assertEquals("out", stringParam.getValue());
+        runner.batch(null, params);
+    }
 
-        verify(call, times(5)).execute();
-        verify(results, times(5)).close();
-        verify(call, times(5)).close();    // make sure we closed the statement
-        verify(conn, times(5)).close();    // make sure we do not close the connection
+    @Test(expected=SQLException.class)
+    public void testNullSqlExecute() throws Exception {
+        runner.execute(null);
     }
 
-    @Test
-    public void testGoodExecuteWithResultSet() throws Exception {
-        callGoodExecuteWithResultSet();
+    @Test(expected=SQLException.class)
+    public void testNullSqlExecuteWithResultSet() throws Exception {
+        runner.execute(null, handler);
     }
 
-    @Test
-    public void testGoodExecuteWithResultSetPmdTrue() throws Exception {
-        runner = new QueryRunner(true);
-        callGoodExecuteWithResultSet(conn);
+    @Test(expected=SQLException.class)
+    public void testNullSqlQuery() throws Exception {
+        runner.query(null, handler);
     }
 
-    @Test
-    public void testGoodExecuteWithResultSetDefaultConstructor() throws Exception {
-        runner = new QueryRunner();
-        callGoodExecuteWithResultSet(conn);
+    @Test(expected=SQLException.class)
+    public void testNullSqlUpdate() throws Exception {
+        runner.update(null);
     }
 
-    // helper method for calling execute when an exception is expected
-    private void callExecuteWithResultSetWithException(final Object... params) throws Exception {
-        boolean caught = false;
+    @Test
+    public void testStatementConfiguration() throws Exception {
+        final StatementConfiguration stmtConfig = new StatementConfiguration(1, 2, 3, 4, 5);
+        final QueryRunner queryRunner = new QueryRunner(stmtConfig);
+        queryRunner.prepareStatement(conn, "select 1");
 
-        try {
-            when(meta.getParameterCount()).thenReturn(2);
-            runner.execute("{call my_proc(?, ?)}", handler, params);
+        verify(prepStmt).setFetchDirection(eq(1));
+        verify(prepStmt).setFetchSize(eq(2));
+        verify(prepStmt).setMaxFieldSize(eq(3));
+        verify(prepStmt).setMaxRows(eq(4));
+        verify(prepStmt).setQueryTimeout(eq(5));
+    }
 
-        } catch (final SQLException e) {
-            caught = true;
-        }
+    @Test
+    public void testTooFewParamsBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit" }, { "test" } };
 
-        if(!caught) {
-            fail("Exception never thrown, but expected");
-        }
+        callBatchWithException("select * from blah where ? = ?", params);
     }
 
     @Test
-    public void testNoParamsExecuteWithResultSet() throws Exception {
-        callExecuteWithResultSetWithException();
+    public void testTooFewParamsExecute() throws Exception {
+        callExecuteWithException("unit");
     }
 
     @Test
@@ -968,64 +993,39 @@ public class QueryRunnerTest {
     }
 
     @Test
-    public void testTooManyParamsExecuteWithResultSet() throws Exception {
-        callExecuteWithResultSetWithException("unit", "test", "fail");
+    public void testTooFewParamsQuery() throws Exception {
+        callQueryWithException("unit");
     }
 
-    @Test(expected=SQLException.class)
-    public void testNullConnectionExecuteWithResultSet() throws Exception {
-        when(dataSource.getConnection()).thenReturn(null);
-
-        runner.execute("{call my_proc(?, ?)}", handler, "unit", "test");
+    @Test
+    public void testTooFewParamsUpdate() throws Exception {
+        callUpdateWithException("unit");
     }
 
-    @Test(expected=SQLException.class)
-    public void testNullSqlExecuteWithResultSet() throws Exception {
-        runner.execute(null, handler);
-    }
+    @Test
+    public void testTooManyParamsBatch() throws Exception {
+        final String[][] params = new String[][] { { "unit", "unit", "unit" }, { "test", "test", "test" } };
 
-    @Test(expected=SQLException.class)
-    public void testNullHandlerExecuteWithResultSet() throws Exception {
-        runner.execute("{call my_proc(?, ?)}", (ResultSetHandler)null);
+        callBatchWithException("select * from blah where ? = ?", params);
     }
 
     @Test
-    public void testExecuteWithResultSetException() throws Exception {
-        callExecuteWithResultSetWithException(handler, "unit", "test");
-    }
-
-    //
-    // Random tests
-    //
-    class MyBean {
-        private int a;
-        private double b;
-        private String c;
-
-        public int getA() {    return a; }
-        public void setA(final int a) { this.a = a; }
-        public double getB() { return b; }
-        public void setB(final double b) { this.b = b; }
-        public String getC() { return c; }
-        public void setC(final String c) { this.c = c; }
+    public void testTooManyParamsExecute() throws Exception {
+        callExecuteWithException("unit", "test", "fail");
     }
 
     @Test
-    public void testFillStatementWithBean() throws Exception {
-        final MyBean bean = new MyBean();
-        when(meta.getParameterCount()).thenReturn(3);
-        runner.fillStatementWithBean(prepStmt, bean, "a", "b", "c");
+    public void testTooManyParamsExecuteWithResultSet() throws Exception {
+        callExecuteWithResultSetWithException("unit", "test", "fail");
     }
 
-    @Test(expected=NullPointerException.class)
-    public void testFillStatementWithBeanNullNames() throws Exception {
-        final MyBean bean = new MyBean();
-        runner.fillStatementWithBean(prepStmt, bean, "a", "b", null);
+    @Test
+    public void testTooManyParamsQuery() throws Exception {
+        callQueryWithException("unit", "test", "fail");
     }
 
-    @Test(expected=SQLException.class)
-    public void testBadPrepareConnection() throws Exception {
-        runner = new QueryRunner();
-        runner.update("update blah set unit = test");
+    @Test
+    public void testTooManyParamsUpdate() throws Exception {
+        callUpdateWithException("unit", "test", "fail");
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/ResultSetIteratorTest.java b/src/test/java/org/apache/commons/dbutils/ResultSetIteratorTest.java
index 186057b..010e5da 100644
--- a/src/test/java/org/apache/commons/dbutils/ResultSetIteratorTest.java
+++ b/src/test/java/org/apache/commons/dbutils/ResultSetIteratorTest.java
@@ -29,6 +29,15 @@ import org.junit.Test;
  */
 public class ResultSetIteratorTest extends BaseTestCase {
 
+    @Test
+    public void testCreatesResultSetIteratorTakingThreeArgumentsAndCallsRemove() {
+
+        final ResultSet resultSet = mock(ResultSet.class);
+        final ResultSetIterator resultSetIterator = new ResultSetIterator(resultSet, null);
+        resultSetIterator.remove();
+
+    }
+
     public void testNext() {
 
         final Iterator<Object[]> iter = new ResultSetIterator(this.rs);
@@ -67,14 +76,5 @@ public class ResultSetIteratorTest extends BaseTestCase {
 
     }
 
-    @Test
-    public void testCreatesResultSetIteratorTakingThreeArgumentsAndCallsRemove() {
-
-        final ResultSet resultSet = mock(ResultSet.class);
-        final ResultSetIterator resultSetIterator = new ResultSetIterator(resultSet, null);
-        resultSetIterator.remove();
-
-    }
-
 
 }
diff --git a/src/test/java/org/apache/commons/dbutils/ServiceLoaderTest.java b/src/test/java/org/apache/commons/dbutils/ServiceLoaderTest.java
index 694b80a..ea06276 100644
--- a/src/test/java/org/apache/commons/dbutils/ServiceLoaderTest.java
+++ b/src/test/java/org/apache/commons/dbutils/ServiceLoaderTest.java
@@ -35,32 +35,6 @@ public class ServiceLoaderTest {
         properties = ServiceLoader.load(PropertyHandler.class);
     }
 
-    @Test
-    public void testFindsLocalColumnHandler() {
-        boolean found = false;
-        for (final ColumnHandler handler : columns) {
-            // this class is defined outside of the main classes in dbutils
-            if (handler instanceof TestColumnHandler) {
-                found = true;
-            }
-        }
-
-        assertTrue(found);
-    }
-
-    @Test
-    public void testFindsLocalPropertyHandler() {
-        boolean found = false;
-        for (final PropertyHandler handler : properties) {
-            // this class is defined outside of the main classes in dbutils
-            if (handler instanceof TestPropertyHandler) {
-                found = true;
-            }
-        }
-
-        assertTrue(found);
-    }
-
     /**
      * Verifying 'more than 1' shows that we found more than we loaded locally which assumes the core handlers
      * were loaded, too.
@@ -89,4 +63,30 @@ public class ServiceLoaderTest {
         assertTrue(count > 1);
     }
 
+    @Test
+    public void testFindsLocalColumnHandler() {
+        boolean found = false;
+        for (final ColumnHandler handler : columns) {
+            // this class is defined outside of the main classes in dbutils
+            if (handler instanceof TestColumnHandler) {
+                found = true;
+            }
+        }
+
+        assertTrue(found);
+    }
+
+    @Test
+    public void testFindsLocalPropertyHandler() {
+        boolean found = false;
+        for (final PropertyHandler handler : properties) {
+            // this class is defined outside of the main classes in dbutils
+            if (handler instanceof TestPropertyHandler) {
+                found = true;
+            }
+        }
+
+        assertTrue(found);
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java b/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java
index 3007cfd..ecc21cf 100644
--- a/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java
+++ b/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java
@@ -23,20 +23,6 @@ import static org.junit.Assert.assertTrue;
 import org.junit.Test;
 
 public class StatementConfigurationTest {
-    /**
-     * Test that an empty builder yields null values for all configuration settings.
-     */
-    @Test
-    public void testEmptyBuilder() {
-        final StatementConfiguration config = new StatementConfiguration.Builder().build();
-
-        assertFalse(config.isFetchDirectionSet());
-        assertFalse(config.isFetchSizeSet());
-        assertFalse(config.isMaxFieldSizeSet());
-        assertFalse(config.isMaxRowsSet());
-        assertFalse(config.isQueryTimeoutSet());
-    }
-
     /**
      * Test that a builder with all values set yields like values in the constructed configuration.
      */
@@ -79,4 +65,18 @@ public class StatementConfigurationTest {
         assertEquals(Integer.valueOf(4), config.getMaxRows());
         assertEquals(Integer.valueOf(5), config.getQueryTimeout());
     }
+
+    /**
+     * Test that an empty builder yields null values for all configuration settings.
+     */
+    @Test
+    public void testEmptyBuilder() {
+        final StatementConfiguration config = new StatementConfiguration.Builder().build();
+
+        assertFalse(config.isFetchDirectionSet());
+        assertFalse(config.isFetchSizeSet());
+        assertFalse(config.isMaxFieldSizeSet());
+        assertFalse(config.isMaxRowsSet());
+        assertFalse(config.isQueryTimeoutSet());
+    }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/TestBean.java b/src/test/java/org/apache/commons/dbutils/TestBean.java
index b42ac5c..b7200aa 100644
--- a/src/test/java/org/apache/commons/dbutils/TestBean.java
+++ b/src/test/java/org/apache/commons/dbutils/TestBean.java
@@ -72,44 +72,52 @@ public class TestBean {
     public TestBean() {
     }
 
-    public String getOne() {
-        return one;
+    public double getColumnProcessorDoubleTest() {
+        return columnProcessorDoubleTest;
     }
 
-    public Ordinal getThree() {
-        return three;
+    public String getDoNotSet() {
+        return doNotSet;
     }
 
-    public String getTwo() {
-        return two;
+    public Integer getIntegerTest() {
+        return integerTest;
     }
 
-    public void setOne(final String string) {
-        one = string;
+    public int getIntTest() {
+        return intTest;
     }
 
-    public void setThree(final Ordinal ordinal) {
-        three = ordinal;
+    public String getNotDate() {
+        return notDate;
     }
 
-    public void setTwo(final String string) {
-        two = string;
+    public Object getNullObjectTest() {
+        return nullObjectTest;
     }
 
-    public String getDoNotSet() {
-        return doNotSet;
+    public int getNullPrimitiveTest() {
+        return nullPrimitiveTest;
     }
 
-    public void setDoNotSet(final String string) {
-        doNotSet = string;
+    public String getOne() {
+        return one;
     }
 
-    public Integer getIntegerTest() {
-        return integerTest;
+    public Ordinal getThree() {
+        return three;
     }
 
-    public int getIntTest() {
-        return intTest;
+    public String getTwo() {
+        return two;
+    }
+
+    public void setColumnProcessorDoubleTest(final double d) {
+        columnProcessorDoubleTest = d;
+    }
+
+    public void setDoNotSet(final String string) {
+        doNotSet = string;
     }
 
     public void setIntegerTest(final Integer integer) {
@@ -120,12 +128,8 @@ public class TestBean {
         intTest = i;
     }
 
-    public Object getNullObjectTest() {
-        return nullObjectTest;
-    }
-
-    public int getNullPrimitiveTest() {
-        return nullPrimitiveTest;
+    public void setNotDate(final String string) {
+        notDate = string;
     }
 
     public void setNullObjectTest(final Object object) {
@@ -136,20 +140,16 @@ public class TestBean {
         nullPrimitiveTest = i;
     }
 
-    public String getNotDate() {
-        return notDate;
-    }
-
-    public void setNotDate(final String string) {
-        notDate = string;
+    public void setOne(final String string) {
+        one = string;
     }
 
-    public double getColumnProcessorDoubleTest() {
-        return columnProcessorDoubleTest;
+    public void setThree(final Ordinal ordinal) {
+        three = ordinal;
     }
 
-    public void setColumnProcessorDoubleTest(final double d) {
-        columnProcessorDoubleTest = d;
+    public void setTwo(final String string) {
+        two = string;
     }
 
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/ArrayHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/ArrayHandlerTest.java
index c9888bd..9fbd715 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/ArrayHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/ArrayHandlerTest.java
@@ -30,6 +30,13 @@ import org.apache.commons.dbutils.ResultSetHandler;
  */
 public class ArrayHandlerTest extends BaseTestCase {
 
+    public void testEmptyResultSetHandle() throws SQLException {
+        final ResultSetHandler<Object[]> h = new ArrayHandler();
+        final Object[] results = h.handle(this.emptyResultSet);
+
+        assertThat(results, is(emptyArray()));
+    }
+
     public void testHandle() throws SQLException {
         final ResultSetHandler<Object[]> h = new ArrayHandler();
         final Object[] results = h.handle(this.rs);
@@ -41,11 +48,4 @@ public class ArrayHandlerTest extends BaseTestCase {
         assertEquals("THREE", results[2]);
     }
 
-    public void testEmptyResultSetHandle() throws SQLException {
-        final ResultSetHandler<Object[]> h = new ArrayHandler();
-        final Object[] results = h.handle(this.emptyResultSet);
-
-        assertThat(results, is(emptyArray()));
-    }
-
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/ArrayListHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/ArrayListHandlerTest.java
index f832dc8..4c36f76 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/ArrayListHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/ArrayListHandlerTest.java
@@ -28,6 +28,14 @@ import org.apache.commons.dbutils.ResultSetHandler;
  */
 public class ArrayListHandlerTest extends BaseTestCase {
 
+    public void testEmptyResultSetHandle() throws SQLException {
+        final ResultSetHandler<List<Object[]>> h = new ArrayListHandler();
+        final List<Object[]> results = h.handle(this.emptyResultSet);
+
+        assertNotNull(results);
+        assertTrue(results.isEmpty());
+    }
+
     public void testHandle() throws SQLException {
         final ResultSetHandler<List<Object[]>> h = new ArrayListHandler();
         final List<Object[]> results = h.handle(this.rs);
@@ -54,12 +62,4 @@ public class ArrayListHandlerTest extends BaseTestCase {
         assertFalse(iter.hasNext());
     }
 
-    public void testEmptyResultSetHandle() throws SQLException {
-        final ResultSetHandler<List<Object[]>> h = new ArrayListHandler();
-        final List<Object[]> results = h.handle(this.emptyResultSet);
-
-        assertNotNull(results);
-        assertTrue(results.isEmpty());
-    }
-
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/BeanHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/BeanHandlerTest.java
index 299eda9..d01d7bf 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/BeanHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/BeanHandlerTest.java
@@ -27,15 +27,16 @@ import org.apache.commons.dbutils.TestBean;
  */
 public class BeanHandlerTest extends BaseTestCase {
 
-    public void testHandle() throws SQLException {
-        final ResultSetHandler<TestBean> h = new BeanHandler<>(TestBean.class);
-        final TestBean results = h.handle(this.rs);
+    public static class SubTestBean extends TestBean implements SubTestBeanInterface { }
 
-        assertNotNull(results);
-        assertEquals("1", results.getOne());
-        assertEquals("2", results.getTwo());
-        assertEquals(TestBean.Ordinal.THREE, results.getThree());
-        assertEquals("not set", results.getDoNotSet());
+    public interface SubTestBeanInterface {
+        String getDoNotSet();
+
+        String getOne();
+
+        TestBean.Ordinal getThree();
+
+        String getTwo();
     }
 
     public void testEmptyResultSetHandle() throws SQLException {
@@ -45,8 +46,8 @@ public class BeanHandlerTest extends BaseTestCase {
         assertNull(results);
     }
 
-    public void testHandleToSuperClass() throws SQLException {
-        final ResultSetHandler<TestBean> h = new BeanHandler<TestBean>(SubTestBean.class);
+    public void testHandle() throws SQLException {
+        final ResultSetHandler<TestBean> h = new BeanHandler<>(TestBean.class);
         final TestBean results = h.handle(this.rs);
 
         assertNotNull(results);
@@ -67,15 +68,14 @@ public class BeanHandlerTest extends BaseTestCase {
         assertEquals("not set", results.getDoNotSet());
     }
 
-    public interface SubTestBeanInterface {
-        String getOne();
-
-        TestBean.Ordinal getThree();
-
-        String getTwo();
+    public void testHandleToSuperClass() throws SQLException {
+        final ResultSetHandler<TestBean> h = new BeanHandler<TestBean>(SubTestBean.class);
+        final TestBean results = h.handle(this.rs);
 
-        String getDoNotSet();
+        assertNotNull(results);
+        assertEquals("1", results.getOne());
+        assertEquals("2", results.getTwo());
+        assertEquals(TestBean.Ordinal.THREE, results.getThree());
+        assertEquals("not set", results.getDoNotSet());
     }
-
-    public static class SubTestBean extends TestBean implements SubTestBeanInterface { }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/BeanListHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/BeanListHandlerTest.java
index 0cefa53..d522a06 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/BeanListHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/BeanListHandlerTest.java
@@ -29,6 +29,26 @@ import org.apache.commons.dbutils.TestBean;
  */
 public class BeanListHandlerTest extends BaseTestCase {
 
+    public static class SubTestBean extends TestBean implements SubTestBeanInterface { }
+
+    public interface SubTestBeanInterface {
+        String getDoNotSet();
+
+        String getOne();
+
+        TestBean.Ordinal getThree();
+
+        String getTwo();
+    }
+
+    public void testEmptyResultSetHandle() throws SQLException {
+        final ResultSetHandler<List<TestBean>> h = new BeanListHandler<>(TestBean.class);
+        final List<TestBean> results = h.handle(this.emptyResultSet);
+
+        assertNotNull(results);
+        assertTrue(results.isEmpty());
+    }
+
     public void testHandle() throws SQLException {
         final ResultSetHandler<List<TestBean>> h = new BeanListHandler<>(TestBean.class);
         final List<TestBean> results = h.handle(this.rs);
@@ -56,24 +76,17 @@ public class BeanListHandlerTest extends BaseTestCase {
         assertFalse(iter.hasNext());
     }
 
-    public void testEmptyResultSetHandle() throws SQLException {
-        final ResultSetHandler<List<TestBean>> h = new BeanListHandler<>(TestBean.class);
-        final List<TestBean> results = h.handle(this.emptyResultSet);
-
-        assertNotNull(results);
-        assertTrue(results.isEmpty());
-    }
-
-    public void testHandleToSuperClass() throws SQLException {
-        final ResultSetHandler<List<TestBean>> h = new BeanListHandler<TestBean>(SubTestBean.class);
-        final List<TestBean> results = h.handle(this.rs);
+    public void testHandleToInterface() throws SQLException {
+        final ResultSetHandler<List<SubTestBeanInterface>> h = new BeanListHandler<SubTestBeanInterface>(SubTestBean.class);
+        final List<SubTestBeanInterface> results = h.handle(this.rs);
 
         assertNotNull(results);
         assertEquals(ROWS, results.size());
 
-        final Iterator<TestBean> iter = results.iterator();
+        final Iterator<SubTestBeanInterface> iter = results.iterator();
+        SubTestBeanInterface row;
         assertTrue(iter.hasNext());
-        TestBean row = iter.next();
+        row = iter.next();
         assertSame(SubTestBean.class, row.getClass());
 
         assertEquals("1", row.getOne());
@@ -93,17 +106,16 @@ public class BeanListHandlerTest extends BaseTestCase {
         assertFalse(iter.hasNext());
     }
 
-    public void testHandleToInterface() throws SQLException {
-        final ResultSetHandler<List<SubTestBeanInterface>> h = new BeanListHandler<SubTestBeanInterface>(SubTestBean.class);
-        final List<SubTestBeanInterface> results = h.handle(this.rs);
+    public void testHandleToSuperClass() throws SQLException {
+        final ResultSetHandler<List<TestBean>> h = new BeanListHandler<TestBean>(SubTestBean.class);
+        final List<TestBean> results = h.handle(this.rs);
 
         assertNotNull(results);
         assertEquals(ROWS, results.size());
 
-        final Iterator<SubTestBeanInterface> iter = results.iterator();
-        SubTestBeanInterface row;
+        final Iterator<TestBean> iter = results.iterator();
         assertTrue(iter.hasNext());
-        row = iter.next();
+        TestBean row = iter.next();
         assertSame(SubTestBean.class, row.getClass());
 
         assertEquals("1", row.getOne());
@@ -122,16 +134,4 @@ public class BeanListHandlerTest extends BaseTestCase {
 
         assertFalse(iter.hasNext());
     }
-
-    public interface SubTestBeanInterface {
-        String getOne();
-
-        TestBean.Ordinal getThree();
-
-        String getTwo();
-
-        String getDoNotSet();
-    }
-
-    public static class SubTestBean extends TestBean implements SubTestBeanInterface { }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java
index 8d39b0d..4511766 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java
@@ -41,6 +41,11 @@ public class BeanMapHandlerTest {
     @Mock private ResultSetMetaData rsmd;
     @Mock private RowProcessor rp;
 
+    private void handle() throws Exception {
+        res = bmh.handle(rs);
+        assertNotNull(res.get(Long.valueOf(23L)));
+    }
+
     @Before
     public void setUp() throws Exception {
         when(Boolean.valueOf(rs.next())).thenReturn(Boolean.TRUE, Boolean.FALSE);
@@ -51,11 +56,6 @@ public class BeanMapHandlerTest {
         when(rp.toBean(rs, TestBean.class)).thenReturn(new TestBean());
     }
 
-    private void handle() throws Exception {
-        res = bmh.handle(rs);
-        assertNotNull(res.get(Long.valueOf(23L)));
-    }
-
     @Test
     public void testBeanMapHandlerClassOfV() throws Exception {
         bmh = new BeanMapHandler<>(TestBean.class);
@@ -63,14 +63,14 @@ public class BeanMapHandlerTest {
     }
 
     @Test
-    public void testBeanMapHandlerClassOfVRowProcessor() throws Exception {
-        bmh = new BeanMapHandler<>(TestBean.class, rp);
+    public void testBeanMapHandlerClassOfVInt() throws Exception {
+        bmh = new BeanMapHandler<>(TestBean.class, 2);
         handle();
     }
 
     @Test
-    public void testBeanMapHandlerClassOfVInt() throws Exception {
-        bmh = new BeanMapHandler<>(TestBean.class, 2);
+    public void testBeanMapHandlerClassOfVRowProcessor() throws Exception {
+        bmh = new BeanMapHandler<>(TestBean.class, rp);
         handle();
     }
 
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/ColumnListHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/ColumnListHandlerTest.java
index dd19d2d..f2d021a 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/ColumnListHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/ColumnListHandlerTest.java
@@ -27,17 +27,6 @@ import org.apache.commons.dbutils.ResultSetHandler;
  */
 public class ColumnListHandlerTest extends BaseTestCase {
 
-    public void testHandle() throws SQLException {
-        final ResultSetHandler<List<String>> h = new ColumnListHandler<>();
-        final List<String> results = h.handle(this.rs);
-
-        assertNotNull(results);
-        assertEquals(ROWS, results.size());
-
-        assertEquals("1", results.get(0));
-        assertEquals("4", results.get(1));
-    }
-
     public void testColumnIndexHandle() throws SQLException {
         final ResultSetHandler<List<String>> h = new ColumnListHandler<>(2);
         final List<String> results = h.handle(this.rs);
@@ -68,4 +57,15 @@ public class ColumnListHandlerTest extends BaseTestCase {
         assertTrue(results.isEmpty());
     }
 
+    public void testHandle() throws SQLException {
+        final ResultSetHandler<List<String>> h = new ColumnListHandler<>();
+        final List<String> results = h.handle(this.rs);
+
+        assertNotNull(results);
+        assertEquals(ROWS, results.size());
+
+        assertEquals("1", results.get(0));
+        assertEquals("4", results.get(1));
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/KeyedHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/KeyedHandlerTest.java
index 7057412..6de10a0 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/KeyedHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/KeyedHandlerTest.java
@@ -28,9 +28,8 @@ import org.apache.commons.dbutils.RowProcessor;
 
 public class KeyedHandlerTest extends BaseTestCase {
 
-    public void testInjectedRowProcess() throws Exception {
-        final RowProcessor mockProc = mock(RowProcessor.class);
-        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>(mockProc);
+    public void testColumnIndexHandle() throws SQLException {
+        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>(2);
         final Map<String,Map<String,Object>> results = h.handle(this.rs);
 
         assertNotNull(results);
@@ -39,23 +38,27 @@ public class KeyedHandlerTest extends BaseTestCase {
         Map<String,Object> row = null;
         for(final Entry<String, Map<String, Object>> entry : results.entrySet())
         {
+            final Object key = entry.getKey();
+            assertNotNull(key);
             row = entry.getValue();
             assertNotNull(row);
-            assertTrue(row.isEmpty());
-            assertEquals(0, row.size());
+            assertEquals(COLS, row.size());
         }
+        row = results.get("5");
+        assertEquals("4", row.get("one"));
+        assertEquals("5", row.get("TWO"));
+        assertEquals("SIX", row.get("Three"));
     }
 
-    public void testHandle() throws SQLException {
-        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>();
-
-        final Map<String,Map<String,Object>> results = h.handle(this.rs);
+    public void testColumnNameHandle() throws SQLException {
+        final ResultSetHandler<Map<Integer,Map<String,Object>>> h = new KeyedHandler<>("intTest");
+        final Map<Integer,Map<String,Object>> results = h.handle(this.rs);
 
         assertNotNull(results);
         assertEquals(ROWS, results.size());
 
         Map<String,Object> row = null;
-        for(final Entry<String, Map<String, Object>> entry : results.entrySet())
+        for(final Entry<Integer, Map<String, Object>> entry : results.entrySet())
         {
             final Object key = entry.getKey();
             assertNotNull(key);
@@ -63,14 +66,22 @@ public class KeyedHandlerTest extends BaseTestCase {
             assertNotNull(row);
             assertEquals(COLS, row.size());
         }
-        row = results.get("1");
-        assertEquals("1", row.get("one"));
-        assertEquals("2", row.get("TWO"));
-        assertEquals("THREE", row.get("Three"));
+        row = results.get(Integer.valueOf(3));
+        assertEquals("4", row.get("one"));
+        assertEquals("5", row.get("TWO"));
+        assertEquals("SIX", row.get("Three"));
     }
 
-    public void testColumnIndexHandle() throws SQLException {
-        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>(2);
+    public void testEmptyResultSetHandle() throws SQLException {
+        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>();
+        final Map<String,Map<String,Object>> results = h.handle(this.emptyResultSet);
+        assertNotNull(results);
+        assertTrue(results.isEmpty());
+    }
+
+    public void testHandle() throws SQLException {
+        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>();
+
         final Map<String,Map<String,Object>> results = h.handle(this.rs);
 
         assertNotNull(results);
@@ -85,38 +96,27 @@ public class KeyedHandlerTest extends BaseTestCase {
             assertNotNull(row);
             assertEquals(COLS, row.size());
         }
-        row = results.get("5");
-        assertEquals("4", row.get("one"));
-        assertEquals("5", row.get("TWO"));
-        assertEquals("SIX", row.get("Three"));
+        row = results.get("1");
+        assertEquals("1", row.get("one"));
+        assertEquals("2", row.get("TWO"));
+        assertEquals("THREE", row.get("Three"));
     }
 
-    public void testColumnNameHandle() throws SQLException {
-        final ResultSetHandler<Map<Integer,Map<String,Object>>> h = new KeyedHandler<>("intTest");
-        final Map<Integer,Map<String,Object>> results = h.handle(this.rs);
+    public void testInjectedRowProcess() throws Exception {
+        final RowProcessor mockProc = mock(RowProcessor.class);
+        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>(mockProc);
+        final Map<String,Map<String,Object>> results = h.handle(this.rs);
 
         assertNotNull(results);
         assertEquals(ROWS, results.size());
 
         Map<String,Object> row = null;
-        for(final Entry<Integer, Map<String, Object>> entry : results.entrySet())
+        for(final Entry<String, Map<String, Object>> entry : results.entrySet())
         {
-            final Object key = entry.getKey();
-            assertNotNull(key);
             row = entry.getValue();
             assertNotNull(row);
-            assertEquals(COLS, row.size());
+            assertTrue(row.isEmpty());
+            assertEquals(0, row.size());
         }
-        row = results.get(Integer.valueOf(3));
-        assertEquals("4", row.get("one"));
-        assertEquals("5", row.get("TWO"));
-        assertEquals("SIX", row.get("Three"));
-    }
-
-    public void testEmptyResultSetHandle() throws SQLException {
-        final ResultSetHandler<Map<String,Map<String,Object>>> h = new KeyedHandler<>();
-        final Map<String,Map<String,Object>> results = h.handle(this.emptyResultSet);
-        assertNotNull(results);
-        assertTrue(results.isEmpty());
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/MapHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/MapHandlerTest.java
index 62f6cff..f91e61d 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/MapHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/MapHandlerTest.java
@@ -27,6 +27,13 @@ import org.apache.commons.dbutils.ResultSetHandler;
  */
 public class MapHandlerTest extends BaseTestCase {
 
+    public void testEmptyResultSetHandle() throws SQLException {
+        final ResultSetHandler<Map<String,Object>> h = new MapHandler();
+        final Map<String,Object> results = h.handle(this.emptyResultSet);
+
+        assertNull(results);
+    }
+
     public void testHandle() throws SQLException {
         final ResultSetHandler<Map<String,Object>> h = new MapHandler();
         final Map<String,Object> results = h.handle(this.rs);
@@ -38,11 +45,4 @@ public class MapHandlerTest extends BaseTestCase {
         assertEquals("THREE", results.get("Three"));
     }
 
-    public void testEmptyResultSetHandle() throws SQLException {
-        final ResultSetHandler<Map<String,Object>> h = new MapHandler();
-        final Map<String,Object> results = h.handle(this.emptyResultSet);
-
-        assertNull(results);
-    }
-
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/MapListHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/MapListHandlerTest.java
index 0ed16a4..7a553dd 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/MapListHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/MapListHandlerTest.java
@@ -29,6 +29,14 @@ import org.apache.commons.dbutils.ResultSetHandler;
  */
 public class MapListHandlerTest extends BaseTestCase {
 
+    public void testEmptyResultSetHandle() throws SQLException {
+        final ResultSetHandler<List<Map<String,Object>>> h = new MapListHandler();
+        final List<Map<String,Object>> results = h.handle(this.emptyResultSet);
+
+        assertNotNull(results);
+        assertTrue(results.isEmpty());
+    }
+
     public void testHandle() throws SQLException {
         final ResultSetHandler<List<Map<String,Object>>> h = new MapListHandler();
         final List<Map<String,Object>> results = h.handle(this.rs);
@@ -55,12 +63,4 @@ public class MapListHandlerTest extends BaseTestCase {
         assertFalse(iter.hasNext());
     }
 
-    public void testEmptyResultSetHandle() throws SQLException {
-        final ResultSetHandler<List<Map<String,Object>>> h = new MapListHandler();
-        final List<Map<String,Object>> results = h.handle(this.emptyResultSet);
-
-        assertNotNull(results);
-        assertTrue(results.isEmpty());
-    }
-
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/ScalarHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/ScalarHandlerTest.java
index a0e1a89..0dbc022 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/ScalarHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/ScalarHandlerTest.java
@@ -23,13 +23,6 @@ import org.apache.commons.dbutils.ResultSetHandler;
 
 public class ScalarHandlerTest extends BaseTestCase {
 
-    public void testHandle() throws SQLException {
-        final ResultSetHandler<String> h = new ScalarHandler<>();
-        final Object results = h.handle(this.rs);
-        assertNotNull(results);
-        assertEquals("1", results);
-    }
-
     public void testColumnIndexHandle() throws SQLException {
         final ResultSetHandler<String> h = new ScalarHandler<>(2);
         final Object results = h.handle(this.rs);
@@ -50,4 +43,11 @@ public class ScalarHandlerTest extends BaseTestCase {
         assertNull(results);
     }
 
+    public void testHandle() throws SQLException {
+        final ResultSetHandler<String> h = new ScalarHandler<>();
+        final Object results = h.handle(this.rs);
+        assertNotNull(results);
+        assertEquals("1", results);
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/columns/ColumnHandlerTestBase.java b/src/test/java/org/apache/commons/dbutils/handlers/columns/ColumnHandlerTestBase.java
index 378eade..b8ed0ed 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/columns/ColumnHandlerTestBase.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/columns/ColumnHandlerTestBase.java
@@ -37,6 +37,9 @@ public abstract class ColumnHandlerTestBase {
         this.matchingType = matchingType;
     }
 
+    @Test
+    public abstract void testApplyType() throws Exception;
+
     @Test
     public void testMatch() {
         assertTrue(handler.match(matchingType));
@@ -46,7 +49,4 @@ public abstract class ColumnHandlerTestBase {
     public void testMatchNegative() {
         assertFalse(handler.match(Integer.class));
     }
-
-    @Test
-    public abstract void testApplyType() throws Exception;
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandlerTest.java
index 84ec24e..8713d46 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/columns/IntegerColumnHandlerTest.java
@@ -32,14 +32,14 @@ public class IntegerColumnHandlerTest extends ColumnHandlerTestBase {
 
     @Override
     @Test
-    public void testMatchNegative() {
-        assertFalse(handler.match(Float.class));
+    public void testApplyType() throws Exception {
+        when(rs.getInt(1)).thenReturn(Integer.MIN_VALUE);
+        assertEquals(Integer.class, handler.apply(rs, 1).getClass());
     }
 
     @Override
     @Test
-    public void testApplyType() throws Exception {
-        when(rs.getInt(1)).thenReturn(Integer.MIN_VALUE);
-        assertEquals(Integer.class, handler.apply(rs, 1).getClass());
+    public void testMatchNegative() {
+        assertFalse(handler.match(Float.class));
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/columns/TestColumnHandler.java b/src/test/java/org/apache/commons/dbutils/handlers/columns/TestColumnHandler.java
index db4e69d..fce6281 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/columns/TestColumnHandler.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/columns/TestColumnHandler.java
@@ -24,12 +24,12 @@ import org.apache.commons.dbutils.ColumnHandler;
 public class TestColumnHandler implements ColumnHandler {
 
     @Override
-    public boolean match(final Class<?> propType) {
-        return false;
+    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
+        return null;
     }
 
     @Override
-    public Object apply(final ResultSet rs, final int columnIndex) throws SQLException {
-        return null;
+    public boolean match(final Class<?> propType) {
+        return false;
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandlerTest.java
index 8c1c07d..2f50d55 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/properties/DatePropertyHandlerTest.java
@@ -38,36 +38,36 @@ public class DatePropertyHandlerTest {
     }
 
     @Test
-    public void testMatch() {
-        assertTrue(handler.match(java.sql.Date.class, testValue));
-        assertTrue(handler.match(java.sql.Time.class, testValue));
-        assertTrue(handler.match(java.sql.Timestamp.class, testValue));
+    public void testApplyTypeOfDate() throws Exception {
+        assertEquals(java.sql.Date.class, handler.apply(java.sql.Date.class, testValue).getClass());
     }
 
     @Test
-    public void testNotMatch() {
-        final Timestamp ts = new Timestamp(testValue.getTime());
-        assertFalse(handler.match(java.sql.Timestamp.class, ts));
+    public void testApplyTypeOfTime() throws Exception {
+        assertEquals(Time.class, handler.apply(java.sql.Time.class, testValue).getClass());
     }
 
     @Test
-    public void testMatchNegative() {
-        assertFalse(handler.match(Float.class, null));
-        assertFalse(handler.match(Float.class, testValue));
+    public void testApplyTypeOfTimestamp() throws Exception {
+        assertEquals(Timestamp.class, handler.apply(java.sql.Timestamp.class, testValue).getClass());
     }
 
     @Test
-    public void testApplyTypeOfDate() throws Exception {
-        assertEquals(java.sql.Date.class, handler.apply(java.sql.Date.class, testValue).getClass());
+    public void testMatch() {
+        assertTrue(handler.match(java.sql.Date.class, testValue));
+        assertTrue(handler.match(java.sql.Time.class, testValue));
+        assertTrue(handler.match(java.sql.Timestamp.class, testValue));
     }
 
     @Test
-    public void testApplyTypeOfTime() throws Exception {
-        assertEquals(Time.class, handler.apply(java.sql.Time.class, testValue).getClass());
+    public void testMatchNegative() {
+        assertFalse(handler.match(Float.class, null));
+        assertFalse(handler.match(Float.class, testValue));
     }
 
     @Test
-    public void testApplyTypeOfTimestamp() throws Exception {
-        assertEquals(Timestamp.class, handler.apply(java.sql.Timestamp.class, testValue).getClass());
+    public void testNotMatch() {
+        final Timestamp ts = new Timestamp(testValue.getTime());
+        assertFalse(handler.match(java.sql.Timestamp.class, ts));
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/properties/PropertyHandlerTest.java b/src/test/java/org/apache/commons/dbutils/handlers/properties/PropertyHandlerTest.java
index 5b642b2..d91702b 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/properties/PropertyHandlerTest.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/properties/PropertyHandlerTest.java
@@ -32,19 +32,6 @@ public class PropertyHandlerTest {
         loader = ServiceLoader.load(PropertyHandler.class);
     }
 
-    @Test
-    public void testServiceLoaderFindsMultipleRegistries() {
-        boolean found = false;
-        for (final PropertyHandler handler : loader) {
-            // this class is defined outside of the main classes of dbutils
-            if (handler instanceof TestPropertyHandler) {
-                found = true;
-            }
-        }
-
-        assertTrue(found);
-    }
-
     /**
      * Verifying 'more than 1' shows that we found more than we loaded locally which assumes the core handlers
      * were loaded, too.
@@ -59,4 +46,17 @@ public class PropertyHandlerTest {
         assertTrue(count > 1);
     }
 
+    @Test
+    public void testServiceLoaderFindsMultipleRegistries() {
+        boolean found = false;
+        for (final PropertyHandler handler : loader) {
+            // this class is defined outside of the main classes of dbutils
+            if (handler instanceof TestPropertyHandler) {
+                found = true;
+            }
+        }
+
+        assertTrue(found);
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/dbutils/handlers/properties/TestPropertyHandler.java b/src/test/java/org/apache/commons/dbutils/handlers/properties/TestPropertyHandler.java
index 99a0d27..a9c5275 100644
--- a/src/test/java/org/apache/commons/dbutils/handlers/properties/TestPropertyHandler.java
+++ b/src/test/java/org/apache/commons/dbutils/handlers/properties/TestPropertyHandler.java
@@ -21,12 +21,12 @@ import org.apache.commons.dbutils.PropertyHandler;
 public class TestPropertyHandler implements PropertyHandler {
 
     @Override
-    public boolean match(final Class<?> parameter, final Object value) {
-        return false;
+    public Object apply(final Class<?> parameter, final Object value) {
+        return null;
     }
 
     @Override
-    public Object apply(final Class<?> parameter, final Object value) {
-        return null;
+    public boolean match(final Class<?> parameter, final Object value) {
+        return false;
     }
 }
diff --git a/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java b/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java
index bfb1061..89b4367 100644
--- a/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java
+++ b/src/test/java/org/apache/commons/dbutils/wrappers/SqlNullCheckedResultSetTest.java
@@ -44,11 +44,191 @@ import java.util.Map;
 import org.apache.commons.dbutils.BaseTestCase;
 import org.apache.commons.dbutils.ProxyFactory;
 
+class SqlNullCheckedResultSetMockBlob implements Blob {
+
+    /**
+     * @throws SQLException
+     */
+    @Override
+    public void free() throws SQLException {
+
+    }
+
+    @Override
+    public InputStream getBinaryStream() throws SQLException {
+        return new ByteArrayInputStream(new byte[0]);
+    }
+
+    /**
+     * @throws SQLException
+     */
+    @Override
+    public InputStream getBinaryStream(final long pos, final long length) throws SQLException {
+      return null;
+    }
+
+    @Override
+    public byte[] getBytes(final long param, final int param1) throws SQLException {
+        return new byte[0];
+    }
+
+    @Override
+    public long length() throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public long position(final Blob blob, final long param) throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public long position(final byte[] values, final long param) throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public OutputStream setBinaryStream(final long pos) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public int setBytes(final long pos, final byte[] bytes) throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public int setBytes(final long pos, final byte[] bytes, final int offset, final int len)
+        throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public void truncate(final long len) throws SQLException {
+
+    }
+
+}
+
+class SqlNullCheckedResultSetMockClob implements Clob {
+
+    /**
+     * @throws SQLException
+     */
+    @Override
+    public void free() throws SQLException {
+
+    }
+
+    @Override
+    public InputStream getAsciiStream() throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Reader getCharacterStream() throws SQLException {
+        return null;
+    }
+
+    /**
+     * @throws SQLException
+     */
+    @Override
+    public Reader getCharacterStream(final long pos, final long length) throws SQLException {
+      return null;
+    }
+
+    @Override
+    public String getSubString(final long param, final int param1) throws SQLException {
+        return "";
+    }
+
+    @Override
+    public long length() throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public long position(final Clob clob, final long param) throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public long position(final String str, final long param) throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public OutputStream setAsciiStream(final long pos) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Writer setCharacterStream(final long pos) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public int setString(final long pos, final String str) throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public int setString(final long pos, final String str, final int offset, final int len)
+        throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public void truncate(final long len) throws SQLException {
+
+    }
+
+}
+
+class SqlNullCheckedResultSetMockRef implements Ref {
+
+    @Override
+    public String getBaseTypeName() throws SQLException {
+        return "";
+    }
+
+    @Override
+    public Object getObject() throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Object getObject(final Map<String,Class<?>> map) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public void setObject(final Object value) throws SQLException {
+
+    }
+
+}
+
 /**
  * Test cases for {@code SqlNullCheckedResultSet} class.
  */
 public class SqlNullCheckedResultSetTest extends BaseTestCase {
 
+    private static void assertArrayEquals(final byte[] expected, final byte[] actual) {
+        if (expected == actual) {
+            return;
+        }
+        if (expected.length != actual.length) {
+            failNotEquals(null, Arrays.toString(expected), Arrays.toString(actual));
+        }
+        for (int i = 0; i < expected.length; i++) {
+            final byte expectedItem = expected[i];
+            final byte actualItem = actual[i];
+            assertEquals("Array not equal at index " + i, expectedItem, actualItem);
+        }
+    }
+
     private SqlNullCheckedResultSet rs2 = null;
 
     /**
@@ -197,20 +377,6 @@ public class SqlNullCheckedResultSetTest extends BaseTestCase {
 
     }
 
-    private static void assertArrayEquals(final byte[] expected, final byte[] actual) {
-        if (expected == actual) {
-            return;
-        }
-        if (expected.length != actual.length) {
-            failNotEquals(null, Arrays.toString(expected), Arrays.toString(actual));
-        }
-        for (int i = 0; i < expected.length; i++) {
-            final byte expectedItem = expected[i];
-            final byte actualItem = actual[i];
-            assertEquals("Array not equal at index " + i, expectedItem, actualItem);
-        }
-    }
-
     /**
      * Tests the getCharacterStream implementation.
      */
@@ -468,36 +634,6 @@ public class SqlNullCheckedResultSetTest extends BaseTestCase {
         assertEquals(ts, rs.getTimestamp("column", Calendar.getInstance()));
     }
 
-    /**
-     * Tests the getURL and setNullURL implementations.
-     *
-     * Uses reflection to allow for building under JDK 1.3.
-     */
-    public void testURL() throws SQLException, MalformedURLException,
-            IllegalAccessException, IllegalArgumentException,
-            java.lang.reflect.InvocationTargetException
-    {
-        Method getUrlInt = null;
-        Method getUrlString = null;
-        try {
-            getUrlInt = ResultSet.class.getMethod("getURL", Integer.TYPE);
-            getUrlString = ResultSet.class.getMethod("getURL", String.class);
-        } catch (final NoSuchMethodException | SecurityException e) {
-            // ignore
-        }
-        if (getUrlInt != null && getUrlString != null) {
-            assertEquals(null, getUrlInt.invoke(rs, Integer.valueOf(1)) );
-            assertTrue(rs.wasNull());
-            assertEquals(null, getUrlString.invoke(rs, "column") );
-            assertTrue(rs.wasNull());
-            // Set what gets returned to something other than the default
-            final URL u = new URL("http://www.apache.org");
-            rs2.setNullURL(u);
-            assertEquals(u, getUrlInt.invoke(rs, Integer.valueOf(1)) );
-            assertEquals(u, getUrlString.invoke(rs, "column") );
-        }
-    }
-
     /**
      * Tests the setNullAsciiStream implementation.
      */
@@ -740,6 +876,20 @@ public class SqlNullCheckedResultSetTest extends BaseTestCase {
         assertEquals(o, rs.getObject("column", (Map<String, Class<?>>) null));
     }
 
+    /**
+     * Tests the setNullRef implementation.
+     */
+    public void testSetNullRef() throws SQLException {
+        assertNull(rs2.getNullRef());
+        // Set what gets returned to something other than the default
+        final Ref ref = new SqlNullCheckedResultSetMockRef();
+        rs2.setNullRef(ref);
+        assertNotNull(rs.getRef(1));
+        assertEquals(ref, rs.getRef(1));
+        assertNotNull(rs.getRef("column"));
+        assertEquals(ref, rs.getRef("column"));
+    }
+
     /**
      * Tests the setNullShort implementation.
      */
@@ -766,20 +916,6 @@ public class SqlNullCheckedResultSetTest extends BaseTestCase {
         assertEquals(s, rs.getString("column"));
     }
 
-    /**
-     * Tests the setNullRef implementation.
-     */
-    public void testSetNullRef() throws SQLException {
-        assertNull(rs2.getNullRef());
-        // Set what gets returned to something other than the default
-        final Ref ref = new SqlNullCheckedResultSetMockRef();
-        rs2.setNullRef(ref);
-        assertNotNull(rs.getRef(1));
-        assertEquals(ref, rs.getRef(1));
-        assertNotNull(rs.getRef("column"));
-        assertEquals(ref, rs.getRef("column"));
-    }
-
     /**
      * Tests the setNullTime implementation.
      */
@@ -828,6 +964,36 @@ public class SqlNullCheckedResultSetTest extends BaseTestCase {
         assertEquals(ts, rs.getTimestamp("column", Calendar.getInstance()));
     }
 
+    /**
+     * Tests the getURL and setNullURL implementations.
+     *
+     * Uses reflection to allow for building under JDK 1.3.
+     */
+    public void testURL() throws SQLException, MalformedURLException,
+            IllegalAccessException, IllegalArgumentException,
+            java.lang.reflect.InvocationTargetException
+    {
+        Method getUrlInt = null;
+        Method getUrlString = null;
+        try {
+            getUrlInt = ResultSet.class.getMethod("getURL", Integer.TYPE);
+            getUrlString = ResultSet.class.getMethod("getURL", String.class);
+        } catch (final NoSuchMethodException | SecurityException e) {
+            // ignore
+        }
+        if (getUrlInt != null && getUrlString != null) {
+            assertEquals(null, getUrlInt.invoke(rs, Integer.valueOf(1)) );
+            assertTrue(rs.wasNull());
+            assertEquals(null, getUrlString.invoke(rs, "column") );
+            assertTrue(rs.wasNull());
+            // Set what gets returned to something other than the default
+            final URL u = new URL("http://www.apache.org");
+            rs2.setNullURL(u);
+            assertEquals(u, getUrlInt.invoke(rs, Integer.valueOf(1)) );
+            assertEquals(u, getUrlString.invoke(rs, "column") );
+        }
+    }
+
     public void testWrapResultSet() throws SQLException {
         final ResultSet wrappedRs = mock(ResultSet.class);
         final ResultSet rs = SqlNullCheckedResultSet.wrap(wrappedRs);
@@ -885,169 +1051,3 @@ class SqlNullUncheckedMockResultSet implements InvocationHandler {
         return null;
     }
 }
-
-class SqlNullCheckedResultSetMockBlob implements Blob {
-
-    @Override
-    public InputStream getBinaryStream() throws SQLException {
-        return new ByteArrayInputStream(new byte[0]);
-    }
-
-    @Override
-    public byte[] getBytes(final long param, final int param1) throws SQLException {
-        return new byte[0];
-    }
-
-    @Override
-    public long length() throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public long position(final byte[] values, final long param) throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public long position(final Blob blob, final long param) throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public void truncate(final long len) throws SQLException {
-
-    }
-
-    @Override
-    public int setBytes(final long pos, final byte[] bytes) throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public int setBytes(final long pos, final byte[] bytes, final int offset, final int len)
-        throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public OutputStream setBinaryStream(final long pos) throws SQLException {
-        return null;
-    }
-
-    /**
-     * @throws SQLException
-     */
-    @Override
-    public void free() throws SQLException {
-
-    }
-
-    /**
-     * @throws SQLException
-     */
-    @Override
-    public InputStream getBinaryStream(final long pos, final long length) throws SQLException {
-      return null;
-    }
-
-}
-
-class SqlNullCheckedResultSetMockClob implements Clob {
-
-    @Override
-    public InputStream getAsciiStream() throws SQLException {
-        return null;
-    }
-
-    @Override
-    public Reader getCharacterStream() throws SQLException {
-        return null;
-    }
-
-    @Override
-    public String getSubString(final long param, final int param1) throws SQLException {
-        return "";
-    }
-
-    @Override
-    public long length() throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public long position(final Clob clob, final long param) throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public long position(final String str, final long param) throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public void truncate(final long len) throws SQLException {
-
-    }
-
-    @Override
-    public OutputStream setAsciiStream(final long pos) throws SQLException {
-        return null;
-    }
-
-    @Override
-    public Writer setCharacterStream(final long pos) throws SQLException {
-        return null;
-    }
-
-    @Override
-    public int setString(final long pos, final String str) throws SQLException {
-        return 0;
-    }
-
-    @Override
-    public int setString(final long pos, final String str, final int offset, final int len)
-        throws SQLException {
-        return 0;
-    }
-
-    /**
-     * @throws SQLException
-     */
-    @Override
-    public void free() throws SQLException {
-
-    }
-
-    /**
-     * @throws SQLException
-     */
-    @Override
-    public Reader getCharacterStream(final long pos, final long length) throws SQLException {
-      return null;
-    }
-
-}
-
-class SqlNullCheckedResultSetMockRef implements Ref {
-
-    @Override
-    public String getBaseTypeName() throws SQLException {
-        return "";
-    }
-
-    @Override
-    public Object getObject() throws SQLException {
-        return null;
-    }
-
-    @Override
-    public void setObject(final Object value) throws SQLException {
-
-    }
-
-    @Override
-    public Object getObject(final Map<String,Class<?>> map) throws SQLException {
-        return null;
-    }
-
-}
diff --git a/src/test/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSetTest.java b/src/test/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSetTest.java
index ca14afb..fdcb6ce 100644
--- a/src/test/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSetTest.java
+++ b/src/test/java/org/apache/commons/dbutils/wrappers/StringTrimmedResultSetTest.java
@@ -34,14 +34,14 @@ public class StringTrimmedResultSetTest extends BaseTestCase {
         this.rs = StringTrimmedResultSet.wrap(this.rs);
     }
 
-    public void testGetString() throws SQLException {
+    public void testGetObject() throws SQLException {
         this.rs.next();
-        assertEquals("notInBean", rs.getString(4));
+        assertEquals("notInBean", rs.getObject(4));
     }
 
-    public void testGetObject() throws SQLException {
+    public void testGetString() throws SQLException {
         this.rs.next();
-        assertEquals("notInBean", rs.getObject(4));
+        assertEquals("notInBean", rs.getString(4));
     }
 
     /**